/*
* 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
* UPDATE HISTORY:
* 08/10/2004 Created
*/
-#include "acluilib.h"
+#include <precomp.h>
+
+#define NDEBUG
+#include <debug.h>
HINSTANCE hDllInstance;
+#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->hiUsrs != NULL)
+ if(sp->hiPrincipals != NULL)
{
- ImageList_Destroy(sp->hiUsrs);
+ ImageList_Destroy(sp->hiPrincipals);
}
+ DestroySidCacheMgr(sp->SidCacheMgr);
+
HeapFree(GetProcessHeap(),
0,
sp);
+
+ CoUninitialize();
}
static VOID
-FreeAceList(IN PACE_LISTITEM *AceListHead)
+FreePrincipalsList(IN PSECURITY_PAGE sp,
+ IN PPRINCIPAL_LISTITEM *PrincipalsListHead)
{
- PACE_LISTITEM CurItem, NextItem;
+ PPRINCIPAL_LISTITEM CurItem, NextItem;
+ PACE_ENTRY AceEntry, NextAceEntry;
- CurItem = *AceListHead;
+ 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);
CurItem = NextItem;
}
- *AceListHead = NULL;
+ *PrincipalsListHead = NULL;
+}
+
+static PACE_ENTRY
+AddAceToPrincipal(IN PPRINCIPAL_LISTITEM Principal,
+ IN PACE_HEADER AceHeader)
+{
+ 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)
+ {
+ AceLink = &(*AceLink)->Next;
+ }
+ *AceLink = AceEntry;
+ }
+
+ return AceEntry;
}
-static PACE_LISTITEM
-FindSidInAceList(IN PACE_LISTITEM AceListHead,
- IN PSID Sid)
+static PPRINCIPAL_LISTITEM
+FindSidInPrincipalsListAddAce(IN PPRINCIPAL_LISTITEM PrincipalsListHead,
+ IN PSID Sid,
+ IN PACE_HEADER AceHeader)
{
- PACE_LISTITEM CurItem;
+ PPRINCIPAL_LISTITEM CurItem;
- for (CurItem = AceListHead;
+ for (CurItem = PrincipalsListHead;
CurItem != NULL;
CurItem = CurItem->Next)
{
if (EqualSid((PSID)(CurItem + 1),
Sid))
{
- return CurItem;
+ if (AddAceToPrincipal(CurItem,
+ AceHeader) != NULL)
+ {
+ return CurItem;
+ }
+
+ /* unable to add the ACE to the principal */
+ break;
}
}
}
static VOID
-ReloadUsersGroupsList(IN PSECURITY_PAGE sp)
+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);
+ }
+}
+
+static PPRINCIPAL_LISTITEM
+AddPrincipalToList(IN PSECURITY_PAGE sp,
+ IN PSID Sid,
+ IN PACE_HEADER AceHeader,
+ OUT BOOL *LookupDeferred OPTIONAL)
+{
+ PPRINCIPAL_LISTITEM PrincipalListItem = NULL, *PrincipalLink;
+ PACE_ENTRY AceEntry;
+ BOOL Deferred = FALSE;
+
+ if (!FindSidInPrincipalsListAddAce(sp->PrincipalsListHead,
+ Sid,
+ AceHeader))
+ {
+ DWORD SidLength;
+
+ PrincipalLink = &sp->PrincipalsListHead;
+ while (*PrincipalLink != NULL)
+ {
+ PrincipalLink = &(*PrincipalLink)->Next;
+ }
+
+ 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;
HRESULT hRet;
/* delete the cached ACL */
- FreeAceList(&sp->AceListHead);
+ FreePrincipalsList(sp,
+ &sp->PrincipalsListHead);
/* query the ACL */
hRet = sp->psi->lpVtbl->GetSecurity(sp->psi,
if (GetSecurityDescriptorDacl(SecurityDescriptor,
&DaclPresent,
&Dacl,
- &DaclDefaulted))
+ &DaclDefaulted) &&
+ DaclPresent && Dacl != NULL)
{
- PACE_LISTITEM AceListItem, *NextAcePtr;
PSID Sid;
- PVOID Ace;
+ PACE_HEADER AceHeader;
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))
+ if (GetAce(Dacl,
+ AceIndex,
+ (LPVOID*)&AceHeader) &&
+ AceHeader != NULL)
{
- SidLength = GetLengthSid(Sid);
-
- AccountNameSize = 0;
- DomainNameSize = 0;
-
- /* calculate the size of the buffer we need to calculate */
- LookupAccountSid(NULL, /* FIXME */
- 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(NULL, /* FIXME */
- 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;
- }
+ BOOL LookupDeferred;
+ PPRINCIPAL_LISTITEM PrincipalListItem;
- 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(NULL, /* FIXME */
- 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:
- {
- break;
- }
- }
-
- if (PolicyAccountDomainInfo != NULL)
- {
- LsaFreeMemory(PolicyAccountDomainInfo);
- }
-
- LsaFreeMemory(ReferencedDomain);
- LsaFreeMemory(Names);
- }
- LsaClose(LsaHandle);
- }
- }
+ Sid = AceHeaderToSID(AceHeader);
+
+ PrincipalListItem = AddPrincipalToList(sp,
+ Sid,
+ AceHeader,
+ &LookupDeferred);
- /* append item to the cached ACL */
- *NextAcePtr = AceListItem;
- NextAcePtr = &AceListItem->Next;
+ if (PrincipalListItem != NULL && LookupDeferred)
+ {
+ AddPrincipalListEntry(sp,
+ PrincipalListItem,
+ -1,
+ FALSE);
}
}
}
}
}
-static INT
-AddAceListEntry(IN PSECURITY_PAGE sp,
- IN PACE_LISTITEM AceListItem,
- IN INT Index,
- IN BOOL Selected)
+static VOID
+UpdateControlStates(IN PSECURITY_PAGE sp)
{
- LVITEM li;
+ PPRINCIPAL_LISTITEM Selected = (PPRINCIPAL_LISTITEM)ListViewGetSelectedItemData(sp->hWndPrincipalsList);
- 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)
+ EnableWindow(sp->hBtnRemove,
+ Selected != NULL);
+ EnableWindow(sp->hAceCheckList,
+ Selected != NULL);
+
+ if (Selected != NULL)
{
- 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);
-}
+ LPWSTR szLabel;
+ LPWSTR szDisplayString;
+
+ szDisplayString = GetPrincipalAccountNameString(Selected);
+ if (LoadAndFormatString(hDllInstance,
+ IDS_PERMISSIONS_FOR,
+ &szLabel,
+ szDisplayString))
+ {
+ SetWindowText(sp->hPermissionsForLabel,
+ szLabel);
-static VOID
-FillUsersGroupsList(IN PSECURITY_PAGE sp)
-{
- LPARAM SelLParam;
- PACE_LISTITEM CurItem;
- RECT rcLvClient;
+ LocalFree((HLOCAL)szLabel);
+ }
- SelLParam = ListViewGetSelectedItemData(sp->hWndAceList);
+ LocalFree((HLOCAL)szDisplayString);
- DisableRedrawWindow(sp->hWndAceList);
+ /* FIXME - update the checkboxes */
+ }
+ else
+ {
+ WCHAR szPermissions[255];
+
+ if (LoadString(hDllInstance,
+ IDS_PERMISSIONS,
+ szPermissions,
+ sizeof(szPermissions) / sizeof(szPermissions[0])))
+ {
+ SetWindowText(sp->hPermissionsForLabel,
+ szPermissions);
+ }
- ListView_DeleteAllItems(sp->hWndAceList);
+ SendMessage(sp->hAceCheckList,
+ CLM_CLEARCHECKBOXES,
+ 0,
+ 0);
+ }
+}
- ReloadUsersGroupsList(sp);
+static void
+UpdatePrincipalInfo(IN PSECURITY_PAGE sp,
+ IN PSIDLOOKUPNOTIFYINFO LookupInfo)
+{
+ PPRINCIPAL_LISTITEM CurItem;
- for (CurItem = sp->AceListHead;
+ for (CurItem = sp->PrincipalsListHead;
CurItem != NULL;
CurItem = CurItem->Next)
{
- AddAceListEntry(sp,
- CurItem,
- -1,
- (SelLParam == (LPARAM)CurItem));
- }
-
- EnableRedrawWindow(sp->hWndAceList);
-
- GetClientRect(sp->hWndAceList, &rcLvClient);
-
- ListView_SetColumnWidth(sp->hWndAceList,
- 0,
- rcLvClient.right);
-}
+ if (EqualSid((PSID)(CurItem + 1),
+ LookupInfo->Sid))
+ {
+ INT PrincipalIndex;
+ LVFINDINFO lvfi;
-static VOID
-UpdateControlStates(IN PSECURITY_PAGE sp)
-{
- BOOL UserOrGroupSelected;
-
- UserOrGroupSelected = (ListViewGetSelectedItemData(sp->hWndAceList) != 0);
+ /* 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);
- EnableWindow(sp->hBtnRemove, UserOrGroupSelected);
+ if (ListViewGetSelectedItemData(sp->hWndPrincipalsList) == (LPARAM)CurItem)
+ {
+ UpdateControlStates(sp);
+ }
+ }
+ else
+ {
+ AddPrincipalListEntry(sp,
+ CurItem,
+ -1,
+ FALSE);
+ }
+ break;
+ }
+ }
}
static UINT CALLBACK
{
PSECURITY_PAGE sp = (PSECURITY_PAGE)ppsp->lParam;
- switch(uMsg)
+ switch (uMsg)
{
case PSPCB_CREATE:
{
case PSPCB_RELEASE:
{
DestroySecurityPage(sp);
- UnregisterCheckListControl();
return FALSE;
}
}
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 LPARAM lParam)
{
PSECURITY_PAGE sp;
+ INT_PTR Ret = FALSE;
- switch(uMsg)
+ sp = (PSECURITY_PAGE)GetWindowLongPtr(hwndDlg,
+ DWL_USER);
+ if (sp != NULL || uMsg == WM_INITDIALOG)
{
- case WM_NOTIFY:
+ switch (uMsg)
{
- NMHDR *pnmh = (NMHDR*)lParam;
- if (pnmh->idFrom == IDC_ACELIST)
+ case WM_NOTIFY:
{
- sp = (PSECURITY_PAGE)GetWindowLongPtr(hwndDlg,
- DWL_USER);
- if (sp != NULL)
+ NMHDR *pnmh = (NMHDR*)lParam;
+
+ if (pnmh->hwndFrom == sp->hWndPrincipalsList)
{
- switch(pnmh->code)
+ switch (pnmh->code)
{
case LVN_ITEMCHANGED:
{
- UpdateControlStates(sp);
+ 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;
}
- break;
- }
-
- case WM_INITDIALOG:
- {
- sp = (PSECURITY_PAGE)((LPPROPSHEETPAGE)lParam)->lParam;
- if(sp != NULL)
+
+ case WM_COMMAND:
{
- LV_COLUMN lvc;
- RECT rcLvClient;
-
- sp->hWnd = hwndDlg;
- sp->hWndAceList = GetDlgItem(hwndDlg, IDC_ACELIST);
- sp->hBtnRemove = GetDlgItem(hwndDlg, IDC_ACELIST_REMOVE);
- sp->hAceCheckList = GetDlgItem(hwndDlg, IDC_ACE_CHECKLIST);
-
- /* 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));
-
- /* FIXME - hide controls in case the flags aren't present */
+ 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;
}
- break;
}
}
- return 0;
+ return Ret;
}
WINAPI
CreateSecurityPage(IN LPSECURITYINFO psi)
{
- PROPSHEETPAGE psp;
+ PROPSHEETPAGE psp = {0};
PSECURITY_PAGE sPage;
- SI_OBJECT_INFO ObjectInfo;
+ SI_OBJECT_INFO ObjectInfo = {0};
+ HANDLE SidCacheMgr;
+ LPCWSTR SystemName = NULL;
HRESULT hRet;
- if(psi == NULL)
+ if (psi == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
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))
+ if (FAILED(hRet))
{
SetLastError(hRet);
DPRINT("CreateSecurityPage() failed! Failed to query the object information!\n");
return NULL;
}
-
- if (!RegisterCheckListControl(hDllInstance))
+
+ if ((ObjectInfo.dwFlags & SI_SERVER_IS_DC) &&
+ ObjectInfo.pszServerName != NULL &&
+ ObjectInfo.pszServerName[0] != L'\0')
{
- DPRINT("Registering the CHECKLIST_ACLUI class failed!\n");
+ 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;
}
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.lParam = (LPARAM)sPage;
psp.pfnCallback = SecurityPageCallback;
- if((ObjectInfo.dwFlags & SI_PAGE_TITLE) &&
- ObjectInfo.pszPageTitle != NULL && ObjectInfo.pszPageTitle[0] != L'\0')
+ if (ObjectInfo.dwFlags & SI_PAGE_TITLE)
{
- /* Set the page title if the flag is present and the string isn't empty */
psp.pszTitle = ObjectInfo.pszPageTitle;
- psp.dwFlags |= PSP_USETITLE;
+
+ if (psp.pszTitle != NULL)
+ {
+ psp.dwFlags |= PSP_USETITLE;
+ }
+ }
+ else
+ {
+ psp.pszTitle = NULL;
}
/* NOTE: the SECURITY_PAGE structure will be freed by the property page
IN LPSECURITYINFO psi)
{
HRESULT hRet;
- SI_OBJECT_INFO ObjectInfo;
+ SI_OBJECT_INFO ObjectInfo = {0};
PROPSHEETHEADER psh;
HPROPSHEETPAGE hPages[1];
- LPWSTR lpCaption;
+ LPWSTR lpCaption = NULL;
BOOL Ret;
- if(psi == NULL)
+ if (psi == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- /* 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))
+ if (FAILED(hRet))
{
SetLastError(hRet);
/* create the page */
hPages[0] = CreateSecurityPage(psi);
- if(hPages[0] == NULL)
+ if (hPages[0] == NULL)
{
DPRINT("CreateSecurityPage(), couldn't create property sheet!\n");
return FALSE;
psh.dwFlags = PSH_DEFAULT;
psh.hwndParent = hwndOwner;
psh.hInstance = hDllInstance;
- if((ObjectInfo.dwFlags & SI_PAGE_TITLE) &&
- ObjectInfo.pszPageTitle != NULL && ObjectInfo.pszPageTitle[0] != L'\0')
+
+ /* 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. */
+ if (LoadAndFormatString(hDllInstance,
+ IDS_PSP_TITLE,
+ &lpCaption,
+ ObjectInfo.pszObjectName))
{
- /* Set the page title if the flag is present and the string isn't empty */
- psh.pszCaption = ObjectInfo.pszPageTitle;
- lpCaption = NULL;
+ psh.pszCaption = lpCaption;
}
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. */
- LoadAndFormatString(hDllInstance,
- IDS_PSP_TITLE,
- &lpCaption,
- ObjectInfo.pszObjectName);
- psh.pszCaption = lpCaption;
+ psh.pszCaption = ObjectInfo.pszObjectName;
}
psh.nPages = sizeof(hPages) / sizeof(HPROPSHEETPAGE);
Ret = (PropertySheet(&psh) != -1);
- if(lpCaption != NULL)
+ if (lpCaption != NULL)
{
LocalFree((HLOCAL)lpCaption);
}
return Ret;
}
-BOOL STDCALL
+BOOL
+WINAPI
DllMain(IN HINSTANCE hinstDLL,
IN DWORD dwReason,
IN LPVOID lpvReserved)
{
case DLL_PROCESS_ATTACH:
hDllInstance = hinstDLL;
+
+ DisableThreadLibraryCalls(hinstDLL);
+
+ if (!RegisterCheckListControl(hinstDLL))
+ {
+ DPRINT("Registering the CHECKLIST_ACLUI class failed!\n");
+ return FALSE;
+ }
break;
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
+
case DLL_PROCESS_DETACH:
+ UnregisterCheckListControl();
break;
}
+
return TRUE;
}