--- branches/cache_manager_rewrite/reactos/lib/aclui/aclui.c 2005-08-14 16:42:46 UTC (rev 17385)
+++ branches/cache_manager_rewrite/reactos/lib/aclui/aclui.c 2005-08-14 17:10:07 UTC (rev 17386)
@@ -21,100 +21,719 @@
* 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 "internal.h"
-#include "resource.h"
+#include "acluilib.h"
HINSTANCE hDllInstance;
-UINT CALLBACK
-SecurityPageCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
+static VOID
+DestroySecurityPage(IN PSECURITY_PAGE sp)
{
- switch(uMsg)
- {
- case PSPCB_CREATE:
+ if(sp->hiUsrs != NULL)
{
- PSECURITY_PAGE sp;
+ ImageList_Destroy(sp->hiUsrs);
+ }
- 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;
+ HeapFree(GetProcessHeap(),
+ 0,
+ sp);
+}
+
+static VOID
+FreeAceList(IN PACE_LISTITEM *AceListHead)
+{
+ PACE_LISTITEM CurItem, NextItem;
+
+ CurItem = *AceListHead;
+ while (CurItem != NULL)
+ {
+ /* free the SID string if present */
+ if (CurItem->DisplayString != NULL)
+ {
+ LocalFree((HLOCAL)CurItem->DisplayString);
+ }
+
+ /* free the ACE list item */
+ NextItem = CurItem->Next;
+ HeapFree(GetProcessHeap(),
+ 0,
+ CurItem);
+ CurItem = NextItem;
}
- case PSPCB_RELEASE:
+
+ *AceListHead = NULL;
+}
+
+static PACE_LISTITEM
+FindSidInAceList(IN PACE_LISTITEM AceListHead,
+ IN PSID Sid)
+{
+ PACE_LISTITEM CurItem;
+
+ for (CurItem = AceListHead;
+ CurItem != NULL;
+ CurItem = CurItem->Next)
{
- if(ppsp->lParam != 0)
- {
- PSECURITY_PAGE sp = (PSECURITY_PAGE)ppsp->lParam;
- if(sp->hiUsrs != NULL)
+ if (EqualSid((PSID)(CurItem + 1),
+ Sid))
{
- ImageList_Destroy(sp->hiUsrs);
+ return CurItem;
}
- LocalFree((HLOCAL)sp);
- }
- return FALSE;
}
- }
+
+ return NULL;
+}
- return FALSE;
+static VOID
+ReloadUsersGroupsList(IN PSECURITY_PAGE sp)
+{
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
+ BOOL DaclPresent, DaclDefaulted;
+ PACL Dacl = NULL;
+ HRESULT hRet;
+
+ /* delete the cached ACL */
+ FreeAceList(&sp->AceListHead);
+
+ /* 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))
+ {
+ PACE_LISTITEM AceListItem, *NextAcePtr;
+ PSID Sid;
+ PVOID Ace;
+ ULONG AceIndex;
+ DWORD AccountNameSize, DomainNameSize, SidLength;
+ SID_NAME_USE SidNameUse;
+ DWORD LookupResult;
+
+ NextAcePtr = &sp->AceListHead;
+
+ for (AceIndex = 0;
+ AceIndex < Dacl->AceCount;
+ AceIndex++)
+ {
+ GetAce(Dacl,
+ AceIndex,
+ &Ace);
+
+ Sid = (PSID)&((PACCESS_ALLOWED_ACE)Ace)->SidStart;
+
+ if (!FindSidInAceList(sp->AceListHead,
+ Sid))
+ {
+ SidLength = GetLengthSid(Sid);
+
+ AccountNameSize = 0;
+ DomainNameSize = 0;
+
+ /* calculate the size of the buffer we need to calculate */
+ LookupAccountSid(sp->ServerName,
+ Sid,
+ NULL,
+ &AccountNameSize,
+ NULL,
+ &DomainNameSize,
+ &SidNameUse);
+
+ /* allocate the ace */
+ AceListItem = HeapAlloc(GetProcessHeap(),
+ 0,
+ sizeof(ACE_LISTITEM) +
+ SidLength +
+ ((AccountNameSize + DomainNameSize) * sizeof(WCHAR)));
+ if (AceListItem != NULL)
+ {
+ AceListItem->AccountName = (LPWSTR)((ULONG_PTR)(AceListItem + 1) + SidLength);
+ AceListItem->DomainName = AceListItem->AccountName + AccountNameSize;
+
+ CopySid(SidLength,
+ (PSID)(AceListItem + 1),
+ Sid);
+
+ LookupResult = ERROR_SUCCESS;
+ if (!LookupAccountSid(sp->ServerName,
+ Sid,
+ AceListItem->AccountName,
+ &AccountNameSize,
+ AceListItem->DomainName,
+ &DomainNameSize,
+ &SidNameUse))
+ {
+ LookupResult = GetLastError();
+ if (LookupResult != ERROR_NONE_MAPPED)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ AceListItem);
+ continue;
+ }
+ }
+
+ if (AccountNameSize == 0)
+ {
+ AceListItem->AccountName = NULL;
+ }
+ if (DomainNameSize == 0)
+ {
+ AceListItem->DomainName = NULL;
+ }
+
+ AceListItem->Next = NULL;
+ if (LookupResult == ERROR_NONE_MAPPED)
+ {
+ if (!ConvertSidToStringSid(Sid,
+ &AceListItem->DisplayString))
+ {
+ AceListItem->DisplayString = NULL;
+ }
+ }
+ else
+ {
+ LSA_HANDLE LsaHandle;
+ NTSTATUS Status;
+
+ AceListItem->DisplayString = NULL;
+
+ /* read the domain of the SID */
+ if (OpenLSAPolicyHandle(sp->ServerName,
+ POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION,
+ &LsaHandle))
+ {
+ PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain;
+ PLSA_TRANSLATED_NAME Names;
+ PLSA_TRUST_INFORMATION Domain;
+ PLSA_UNICODE_STRING DomainName;
+ PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo = NULL;
+
+ Status = LsaLookupSids(LsaHandle,
+ 1,
+ &Sid,
+ &ReferencedDomain,
+ &Names);
+ if (NT_SUCCESS(Status))
+ {
+ if (ReferencedDomain != NULL &&
+ Names->DomainIndex >= 0)
+ {
+ Domain = &ReferencedDomain->Domains[Names->DomainIndex];
+ DomainName = &Domain->Name;
+ }
+ else
+ {
+ Domain = NULL;
+ DomainName = NULL;
+ }
+
+ AceListItem->SidNameUse = Names->Use;
+
+ switch (Names->Use)
+ {
+ case SidTypeAlias:
+ if (Domain != NULL)
+ {
+ /* query the domain name for BUILTIN accounts */
+ Status = LsaQueryInformationPolicy(LsaHandle,
+ PolicyAccountDomainInformation,
+ (PVOID*)&PolicyAccountDomainInfo);
+ if (NT_SUCCESS(Status))
+ {
+ DomainName = &PolicyAccountDomainInfo->DomainName;
+
+ /* make the user believe this is a group */
+ AceListItem->SidNameUse = SidTypeGroup;
+ }
+ }
+ /* fall through */
+
+ case SidTypeUser:
+ {
+ if (Domain != NULL)
+ {
+ AceListItem->DisplayString = (LPWSTR)LocalAlloc(LMEM_FIXED,
+ (AccountNameSize * sizeof(WCHAR)) +
+ (DomainName->Length + sizeof(WCHAR)) +
+ (Names->Name.Length + sizeof(WCHAR)) +
+ (4 * sizeof(WCHAR)));
+ if (AceListItem->DisplayString != NULL)
+ {
+ WCHAR *s;
+
+ /* NOTE: LSA_UNICODE_STRINGs are not always NULL-terminated! */
+
+ wcscpy(AceListItem->DisplayString,
+ AceListItem->AccountName);
+ wcscat(AceListItem->DisplayString,
+ L" (");
+ s = AceListItem->DisplayString + wcslen(AceListItem->DisplayString);
+ CopyMemory(s,
+ DomainName->Buffer,
+ DomainName->Length);
+ s += DomainName->Length / sizeof(WCHAR);
+ *(s++) = L'\\';
+ CopyMemory(s,
+ Names->Name.Buffer,
+ Names->Name.Length);
+ s += Names->Name.Length / sizeof(WCHAR);
+ *(s++) = L')';
+ *s = L'\0';
+ }
+
+ /* mark the ace as a user unless it's a
+ BUILTIN account */
+ if (PolicyAccountDomainInfo == NULL)
+ {
+ AceListItem->SidNameUse = SidTypeUser;
+ }
+ }
+ break;
+ }
+
+ case SidTypeWellKnownGroup:
+ {
+ /* make the user believe this is a group */
+ AceListItem->SidNameUse = SidTypeGroup;
+ break;
+ }
+
+ default:
+ {
+ DPRINT("Unhandled SID type: 0x%x\n", Names->Use);
+ break;
+ }
+ }
+
+ if (PolicyAccountDomainInfo != NULL)
+ {
+ LsaFreeMemory(PolicyAccountDomainInfo);
+ }
+
+ LsaFreeMemory(ReferencedDomain);
+ LsaFreeMemory(Names);
+ }
+ LsaClose(LsaHandle);
+ }
+ }
+
+ /* append item to the cached ACL */
+ *NextAcePtr = AceListItem;
+ NextAcePtr = &AceListItem->Next;
+ }
+ }
+ }
+ }
+ LocalFree((HLOCAL)SecurityDescriptor);
+ }
}
+static INT
+AddAceListEntry(IN PSECURITY_PAGE sp,
+ IN PACE_LISTITEM AceListItem,
+ IN INT Index,
+ IN BOOL Selected)
+{
+ LVITEM li;
-INT_PTR CALLBACK
-SecurityPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ 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 = (AceListItem->DisplayString != NULL ? AceListItem->DisplayString : AceListItem->AccountName);
+ switch (AceListItem->SidNameUse)
+ {
+ case SidTypeUser:
+ li.iImage = 0;
+ break;
+ case SidTypeGroup:
+ li.iImage = 1;
+ break;
+ default:
+ li.iImage = -1;
+ break;
+ }
+ li.lParam = (LPARAM)AceListItem;
+
+ return ListView_InsertItem(sp->hWndAceList,
+ &li);
+}
+
+static VOID
+FillUsersGroupsList(IN PSECURITY_PAGE sp)
{
- PSECURITY_PAGE sp;
-
- switch(uMsg)
- {
- case WM_INITDIALOG:
+ LPARAM SelLParam;
+ PACE_LISTITEM CurItem;
+ RECT rcLvClient;
+
+ SelLParam = ListViewGetSelectedItemData(sp->hWndAceList);
+
+ DisableRedrawWindow(sp->hWndAceList);
+
+ ListView_DeleteAllItems(sp->hWndAceList);
+
+ ReloadUsersGroupsList(sp);
+
+ for (CurItem = sp->AceListHead;
+ CurItem != NULL;
+ CurItem = CurItem->Next)
{
- sp = (PSECURITY_PAGE)lParam;
- if(sp != NULL)
- {
- LV_COLUMN lvc;
- RECT rcLvClient;
+ AddAceListEntry(sp,
+ CurItem,
+ -1,
+ (SelLParam == (LPARAM)CurItem));
+ }
+
+ EnableRedrawWindow(sp->hWndAceList);
+
+ GetClientRect(sp->hWndAceList, &rcLvClient);
+
+ ListView_SetColumnWidth(sp->hWndAceList,
+ 0,
+ rcLvClient.right);
+}
+
+static VOID
+UpdateControlStates(IN PSECURITY_PAGE sp)
+{
+ PACE_LISTITEM Selected = (PACE_LISTITEM)ListViewGetSelectedItemData(sp->hWndAceList);
+
+ EnableWindow(sp->hBtnRemove, Selected != NULL);
+ EnableWindow(sp->hAceCheckList, Selected != NULL);
+
+ if (Selected != NULL)
+ {
+ LPWSTR szLabel;
+
+ if (LoadAndFormatString(hDllInstance,
+ IDS_PERMISSIONS_FOR,
+ &szLabel,
+ Selected->AccountName))
+ {
+ SetWindowText(sp->hPermissionsForLabel,
+ szLabel);
+
+ LocalFree((HLOCAL)szLabel);
+ }
- sp->hWnd = hwndDlg;
- sp->hWndUsrList = GetDlgItem(hwndDlg, IDC_ACELIST);
- sp->hiUsrs = ImageList_LoadBitmap(hDllInstance, MAKEINTRESOURCE(IDB_USRGRPIMAGES), 16, 3, 0);
+ /* FIXME - update the checkboxes */
+ }
+ else
+ {
+ WCHAR szPermissions[255];
- /* save the pointer to the structure */
- SetWindowLongPtr(hwndDlg, DWL_USER, (DWORD_PTR)sp);
+ if (LoadString(hDllInstance,
+ IDS_PERMISSIONS,
+ szPermissions,
+ sizeof(szPermissions) / sizeof(szPermissions[0])))
+ {
+ SetWindowText(sp->hPermissionsForLabel,
+ szPermissions);
+ }
+
+ SendMessage(sp->hAceCheckList,
+ CLM_CLEARCHECKBOXES,
+ 0,
+ 0);
+ }
+}
+
+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);
+ UnregisterCheckListControl();
+ 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;
+
+ /* 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,
+ &AccessList,
+ &nAccessList,
+ &DefaultAccessIndex);
+ if (SUCCEEDED(hRet) && nAccessList != 0)
+ {
+ LPCWSTR NameStr;
+ PSI_ACCESS CurAccess, LastAccess;
+ WCHAR NameBuffer[MAX_PATH];
- GetClientRect(sp->hWndUsrList, &rcLvClient);
+ /* save the default access rights to be used when adding ACEs later */
+ if (DefaultAccess != NULL)
+ {
+ *DefaultAccess = AccessList[DefaultAccessIndex];
+ }
- /* setup the listview control */
- ListView_SetExtendedListViewStyleEx(sp->hWndUsrList, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
- ListView_SetImageList(sp->hWndUsrList, sp->hiUsrs, LVSIL_SMALL);
+ 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;
+ }
- /* 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);
+ SendMessage(sp->hAceCheckList,
+ CLM_ADDITEM,
+ CIS_NONE,
+ (LPARAM)NameStr);
+ }
+ }
+ }
+}
+
+static INT_PTR CALLBACK
+SecurityPageProc(IN HWND hwndDlg,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
+{
+ PSECURITY_PAGE sp;
+
+ switch(uMsg)
+ {
+ case WM_NOTIFY:
+ {
+ NMHDR *pnmh = (NMHDR*)lParam;
+ sp = (PSECURITY_PAGE)GetWindowLongPtr(hwndDlg,
+ DWL_USER);
+ if (sp != NULL)
+ {
+ if (pnmh->hwndFrom == sp->hWndAceList)
+ {
+ 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;
+ }
+ }
+ }
+ }
+ break;
+ }
- /* FIXME - hide controls in case the flags aren't present */
- }
- break;
+ case WM_INITDIALOG:
+ {
+ sp = (PSECURITY_PAGE)((LPPROPSHEETPAGE)lParam)->lParam;
+ if(sp != NULL)
+ {
+ LV_COLUMN lvc;
+ RECT rcLvClient;
+
+ sp->hWnd = hwndDlg;
+ sp->hWndAceList = GetDlgItem(hwndDlg, IDC_ACELIST);
+ sp->hBtnRemove = GetDlgItem(hwndDlg, IDC_ACELIST_REMOVE);
+ sp->hBtnAdvanced = GetDlgItem(hwndDlg, IDC_ADVANCED);
+ sp->hAceCheckList = GetDlgItem(hwndDlg, IDC_ACE_CHECKLIST);
+ sp->hPermissionsForLabel = GetDlgItem(hwndDlg, IDC_LABEL_PERMISSIONS_FOR);
+
+ sp->SpecialPermCheckIndex = -1;
+
+ if ((sp->ObjectInfo.dwFlags & SI_SERVER_IS_DC) &&
+ sp->ObjectInfo.pszServerName != NULL &&
+ sp->ObjectInfo.pszServerName[0] != L'\0')
+ {
+ sp->ServerName = sp->ObjectInfo.pszServerName;
+ }
+
+ /* save the pointer to the structure */
+ SetWindowLongPtr(hwndDlg,
+ DWL_USER,
+ (DWORD_PTR)sp);
+
+ sp->hiUsrs = ImageList_LoadBitmap(hDllInstance,
+ MAKEINTRESOURCE(IDB_USRGRPIMAGES),
+ 16,
+ 3,
+ 0);
+
+ /* setup the listview control */
+ ListView_SetExtendedListViewStyleEx(sp->hWndAceList,
+ LVS_EX_FULLROWSELECT,
+ LVS_EX_FULLROWSELECT);
+ ListView_SetImageList(sp->hWndAceList,
+ sp->hiUsrs,
+ LVSIL_SMALL);
+
+ GetClientRect(sp->hWndAceList, &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->hWndAceList, 0, &lvc);
+
+ FillUsersGroupsList(sp);
+
+ ListViewSelectItem(sp->hWndAceList,
+ 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)
+ {
+ WCHAR szSpecialPermissions[255];
+
+ /* editing the permissions is least the user can do when
+ the advanced button is showed */
+ sp->ObjectInfo.dwFlags |= SI_EDIT_PERMS;
+
+ if (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,
+ CIS_ALLOWDISABLED | CIS_DENYDISABLED | CIS_NONE,
+ (LPARAM)szSpecialPermissions);
+ }
+ }
+ 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);
+ }
+ break;
+ }
}
- }
- return 0;
+ return 0;
}
@@ -125,48 +744,82 @@
*/
HPROPSHEETPAGE
WINAPI
-CreateSecurityPage(LPSECURITYINFO psi)
+CreateSecurityPage(IN LPSECURITYINFO psi)
{
- PROPSHEETPAGE psp;
- SI_OBJECT_INFO ObjectInfo;
- HRESULT hRet;
+ PROPSHEETPAGE psp;
+ PSECURITY_PAGE sPage;
+ SI_OBJECT_INFO ObjectInfo;
+ 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. */
+ ZeroMemory(&ObjectInfo, sizeof(ObjectInfo));
+ hRet = psi->lpVtbl->GetObjectInformation(psi, &ObjectInfo);
- if(FAILED(hRet))
- {
- SetLastError(hRet);
+ if(FAILED(hRet))
+ {
+ SetLastError(hRet);
- DPRINT("CreateSecurityPage() failed!\n");
- return NULL;
- }
+ DPRINT("CreateSecurityPage() failed! Failed to query the object information!\n");
+ return NULL;
+ }
+
+ if (!RegisterCheckListControl(hDllInstance))
+ {
+ DPRINT("Registering the CHECKLIST_ACLUI class failed!\n");
+ return NULL;
+ }
+
+ sPage = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(SECURITY_PAGE));
+ if (sPage == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+ DPRINT("Not enough memory to allocate a SECURITY_PAGE!\n");
+ return NULL;
+ }
+ sPage->psi = psi;
+ sPage->ObjectInfo = ObjectInfo;
- 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;
+ ZeroMemory(&psp, sizeof(psp));
- 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;
- }
+ 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;
- return CreatePropertySheetPage(&psp);
+ 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);
}
@@ -177,99 +830,89 @@
*/
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];
- LPVOID 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;
+ PROPSHEETHEADER psh;
+ HPROPSHEETPAGE hPages[1];
+ LPWSTR lpCaption;
+ BOOL Ret;
- /* 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
- {
+ 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. */
[truncated at 1000 lines; 288 more skipped]