2 * ReactOS Access Control List Editor
3 * Copyright (C) 2004-2005 ReactOS Team
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * PROJECT: ReactOS Access Control List Editor
22 * FILE: lib/aclui/aclui.c
23 * PURPOSE: Access Control List Editor
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
34 HINSTANCE hDllInstance
;
36 #define SIDN_LOOKUPSUCCEEDED (0x101)
37 typedef struct _SIDLOOKUPNOTIFYINFO
41 PSIDREQRESULT SidRequestResult
;
42 } SIDLOOKUPNOTIFYINFO
, *PSIDLOOKUPNOTIFYINFO
;
45 AceHeaderToSID(IN PACE_HEADER AceHeader
)
48 switch (AceHeader
->AceType
)
50 case ACCESS_ALLOWED_ACE_TYPE
:
51 Sid
= (PSID
)&((PACCESS_ALLOWED_ACE
)AceHeader
)->SidStart
;
54 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE
:
55 Sid
= (PSID
)&((PACCESS_ALLOWED_CALLBACK_ACE
)AceHeader
)->SidStart
;
57 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
58 Sid
= (PSID
)&((PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
)->SidStart
;
61 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
62 Sid
= (PSID
)&((PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
)->SidStart
;
64 case ACCESS_DENIED_ACE_TYPE
:
65 Sid
= (PSID
)&((PACCESS_DENIED_ACE
)AceHeader
)->SidStart
;
68 case ACCESS_DENIED_CALLBACK_ACE_TYPE
:
69 Sid
= (PSID
)&((PACCESS_DENIED_CALLBACK_ACE
)AceHeader
)->SidStart
;
71 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
72 Sid
= (PSID
)&((PACCESS_DENIED_CALLBACK_OBJECT_ACE
)AceHeader
)->SidStart
;
75 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
76 Sid
= (PSID
)&((PACCESS_DENIED_OBJECT_ACE
)AceHeader
)->SidStart
;
84 DestroySecurityPage(IN PSECURITY_PAGE sp
)
86 if(sp
->hiPrincipals
!= NULL
)
88 ImageList_Destroy(sp
->hiPrincipals
);
91 DestroySidCacheMgr(sp
->SidCacheMgr
);
93 HeapFree(GetProcessHeap(),
101 FreePrincipalsList(IN PSECURITY_PAGE sp
,
102 IN PPRINCIPAL_LISTITEM
*PrincipalsListHead
)
104 PPRINCIPAL_LISTITEM CurItem
, NextItem
;
105 PACE_ENTRY AceEntry
, NextAceEntry
;
107 CurItem
= *PrincipalsListHead
;
108 while (CurItem
!= NULL
)
111 AceEntry
= CurItem
->ACEs
;
112 while (AceEntry
!= NULL
)
114 NextAceEntry
= AceEntry
->Next
;
115 HeapFree(GetProcessHeap(),
118 AceEntry
= NextAceEntry
;
121 /* free the SID string if present */
122 if (CurItem
->SidReqResult
!= NULL
)
124 DereferenceSidReqResult(sp
->SidCacheMgr
,
125 CurItem
->SidReqResult
);
128 if (CurItem
->DisplayString
!= NULL
)
130 LocalFree((HLOCAL
)CurItem
->DisplayString
);
133 /* free the ACE list item */
134 NextItem
= CurItem
->Next
;
135 HeapFree(GetProcessHeap(),
141 *PrincipalsListHead
= NULL
;
145 AddAceToPrincipal(IN PPRINCIPAL_LISTITEM Principal
,
146 IN PACE_HEADER AceHeader
)
148 PACE_ENTRY AceEntry
, *AceLink
;
150 AceEntry
= HeapAlloc(GetProcessHeap(),
152 sizeof(ACE_ENTRY
) + AceHeader
->AceSize
);
153 if (AceEntry
!= NULL
)
155 AceEntry
->Next
= NULL
;
158 CopyMemory(AceEntry
+ 1,
162 /* append it to the list */
163 AceLink
= &Principal
->ACEs
;
164 while (*AceLink
!= NULL
)
166 AceLink
= &(*AceLink
)->Next
;
174 static PPRINCIPAL_LISTITEM
175 FindSidInPrincipalsListAddAce(IN PPRINCIPAL_LISTITEM PrincipalsListHead
,
177 IN PACE_HEADER AceHeader
)
179 PPRINCIPAL_LISTITEM CurItem
;
181 for (CurItem
= PrincipalsListHead
;
183 CurItem
= CurItem
->Next
)
185 if (EqualSid((PSID
)(CurItem
+ 1),
188 if (AddAceToPrincipal(CurItem
,
194 /* unable to add the ACE to the principal */
203 SidLookupCompletion(IN HANDLE SidCacheMgr
,
205 IN PSIDREQRESULT SidRequestResult
,
208 PSECURITY_PAGE sp
= (PSECURITY_PAGE
)Context
;
210 /* NOTE: this routine may be executed in a different thread
213 if (SidRequestResult
!= NULL
)
215 SIDLOOKUPNOTIFYINFO LookupInfo
;
217 LookupInfo
.nmh
.hwndFrom
= sp
->hWnd
;
218 LookupInfo
.nmh
.idFrom
= 0;
219 LookupInfo
.nmh
.code
= SIDN_LOOKUPSUCCEEDED
;
220 LookupInfo
.Sid
= Sid
;
221 LookupInfo
.SidRequestResult
= SidRequestResult
;
223 /* notify the page that the sid lookup succeeded */
224 SendMessage(sp
->hWnd
,
226 (WPARAM
)LookupInfo
.nmh
.idFrom
,
227 (LPARAM
)&LookupInfo
.nmh
);
231 static PPRINCIPAL_LISTITEM
232 AddPrincipalToList(IN PSECURITY_PAGE sp
,
234 IN PACE_HEADER AceHeader
,
235 OUT BOOL
*LookupDeferred OPTIONAL
)
237 PPRINCIPAL_LISTITEM PrincipalListItem
= NULL
, *PrincipalLink
;
239 BOOL Deferred
= FALSE
;
241 if (!FindSidInPrincipalsListAddAce(sp
->PrincipalsListHead
,
247 PrincipalLink
= &sp
->PrincipalsListHead
;
248 while (*PrincipalLink
!= NULL
)
250 PrincipalLink
= &(*PrincipalLink
)->Next
;
253 SidLength
= GetLengthSid(Sid
);
255 /* allocate the principal */
256 PrincipalListItem
= HeapAlloc(GetProcessHeap(),
258 sizeof(PRINCIPAL_LISTITEM
) + SidLength
);
259 if (PrincipalListItem
!= NULL
)
261 PrincipalListItem
->DisplayString
= NULL
;
262 PrincipalListItem
->SidReqResult
= NULL
;
265 (PSID
)(PrincipalListItem
+ 1),
268 /* allocate some memory for the ACE and copy it */
269 AceEntry
= HeapAlloc(GetProcessHeap(),
271 sizeof(ACE_ENTRY
) + AceHeader
->AceSize
);
272 if (AceEntry
!= NULL
)
274 AceEntry
->Next
= NULL
;
275 CopyMemory(AceEntry
+ 1,
279 /* add the ACE to the list */
280 PrincipalListItem
->ACEs
= AceEntry
;
282 PrincipalListItem
->Next
= NULL
;
284 /* append item to the principals list */
285 *PrincipalLink
= PrincipalListItem
;
287 /* lookup the SID now */
288 Deferred
= !LookupSidCache(sp
->SidCacheMgr
,
295 HeapFree(GetProcessHeap(),
298 PrincipalListItem
= NULL
;
303 if (PrincipalListItem
!= NULL
&& LookupDeferred
!= NULL
)
305 *LookupDeferred
= Deferred
;
308 return PrincipalListItem
;
312 GetPrincipalDisplayString(IN PPRINCIPAL_LISTITEM PrincipalListItem
)
314 LPWSTR lpDisplayString
= NULL
;
316 if (PrincipalListItem
->SidReqResult
!= NULL
)
318 if (PrincipalListItem
->SidReqResult
->SidNameUse
== SidTypeUser
||
319 PrincipalListItem
->SidReqResult
->SidNameUse
== SidTypeGroup
)
321 LoadAndFormatString(hDllInstance
,
322 IDS_USERDOMAINFORMAT
,
324 PrincipalListItem
->SidReqResult
->AccountName
,
325 PrincipalListItem
->SidReqResult
->DomainName
,
326 PrincipalListItem
->SidReqResult
->AccountName
);
330 LoadAndFormatString(hDllInstance
,
333 PrincipalListItem
->SidReqResult
->AccountName
);
338 ConvertSidToStringSid((PSID
)(PrincipalListItem
+ 1),
342 return lpDisplayString
;
346 CreatePrincipalListItem(OUT LVITEM
*li
,
347 IN PSECURITY_PAGE sp
,
348 IN PPRINCIPAL_LISTITEM PrincipalListItem
,
354 if (PrincipalListItem
->SidReqResult
!= NULL
)
356 switch (PrincipalListItem
->SidReqResult
->SidNameUse
)
361 case SidTypeWellKnownGroup
:
370 li
->mask
= LVIF_IMAGE
| LVIF_PARAM
| LVIF_STATE
| LVIF_TEXT
;
373 li
->state
= (Selected
? LVIS_SELECTED
: 0);
374 li
->stateMask
= LVIS_SELECTED
;
375 li
->pszText
= PrincipalListItem
->DisplayString
;
376 li
->iImage
= ImageIndex
;
377 li
->lParam
= (LPARAM
)PrincipalListItem
;
381 AddPrincipalListEntry(IN PSECURITY_PAGE sp
,
382 IN PPRINCIPAL_LISTITEM PrincipalListItem
,
389 if (PrincipalListItem
->DisplayString
!= NULL
)
391 LocalFree((HLOCAL
)PrincipalListItem
->DisplayString
);
393 PrincipalListItem
->DisplayString
= GetPrincipalDisplayString(PrincipalListItem
);
395 CreatePrincipalListItem(&li
,
401 Ret
= ListView_InsertItem(sp
->hWndPrincipalsList
,
408 PrincipalCompare(IN LPARAM lParam1
,
410 IN LPARAM lParamSort
)
412 PPRINCIPAL_LISTITEM Item1
= (PPRINCIPAL_LISTITEM
)lParam1
;
413 PPRINCIPAL_LISTITEM Item2
= (PPRINCIPAL_LISTITEM
)lParam2
;
415 if (Item1
->DisplayString
!= NULL
&& Item2
->DisplayString
!= NULL
)
417 return wcscmp(Item1
->DisplayString
,
418 Item2
->DisplayString
);
425 UpdatePrincipalListItem(IN PSECURITY_PAGE sp
,
426 IN INT PrincipalIndex
,
427 IN PPRINCIPAL_LISTITEM PrincipalListItem
,
428 IN PSIDREQRESULT SidReqResult
)
432 /* replace the request result structure */
433 if (PrincipalListItem
->SidReqResult
!= NULL
)
435 DereferenceSidReqResult(sp
->SidCacheMgr
,
436 PrincipalListItem
->SidReqResult
);
439 ReferenceSidReqResult(sp
->SidCacheMgr
,
441 PrincipalListItem
->SidReqResult
= SidReqResult
;
443 /* update the display string */
444 if (PrincipalListItem
->DisplayString
!= NULL
)
446 LocalFree((HLOCAL
)PrincipalListItem
->DisplayString
);
448 PrincipalListItem
->DisplayString
= GetPrincipalDisplayString(PrincipalListItem
);
450 /* update the list item */
451 CreatePrincipalListItem(&li
,
457 /* don't change the list item state */
458 li
.mask
&= ~(LVIF_STATE
| LVIF_PARAM
);
460 ListView_SetItem(sp
->hWndPrincipalsList
,
463 /* sort the principals list view again */
464 ListView_SortItems(sp
->hWndPrincipalsList
,
470 ReloadPrincipalsList(IN PSECURITY_PAGE sp
)
472 PSECURITY_DESCRIPTOR SecurityDescriptor
;
473 BOOL DaclPresent
, DaclDefaulted
;
477 /* delete the cached ACL */
478 FreePrincipalsList(sp
,
479 &sp
->PrincipalsListHead
);
482 hRet
= sp
->psi
->lpVtbl
->GetSecurity(sp
->psi
,
483 DACL_SECURITY_INFORMATION
,
486 if (SUCCEEDED(hRet
) && SecurityDescriptor
!= NULL
)
488 if (GetSecurityDescriptorDacl(SecurityDescriptor
,
492 DaclPresent
&& Dacl
!= NULL
)
495 PACE_HEADER AceHeader
;
499 AceIndex
< Dacl
->AceCount
;
504 (LPVOID
*)&AceHeader
) &&
508 PPRINCIPAL_LISTITEM PrincipalListItem
;
510 Sid
= AceHeaderToSID(AceHeader
);
512 PrincipalListItem
= AddPrincipalToList(sp
,
517 if (PrincipalListItem
!= NULL
&& LookupDeferred
)
519 AddPrincipalListEntry(sp
,
527 LocalFree((HLOCAL
)SecurityDescriptor
);
532 UpdateControlStates(IN PSECURITY_PAGE sp
)
534 PPRINCIPAL_LISTITEM Selected
= (PPRINCIPAL_LISTITEM
)ListViewGetSelectedItemData(sp
->hWndPrincipalsList
);
536 EnableWindow(sp
->hBtnRemove
,
538 EnableWindow(sp
->hAceCheckList
,
541 if (Selected
!= NULL
)
544 LPWSTR szDisplayString
;
546 szDisplayString
= GetPrincipalDisplayString(Selected
);
547 if (LoadAndFormatString(hDllInstance
,
552 SetWindowText(sp
->hPermissionsForLabel
,
555 LocalFree((HLOCAL
)szLabel
);
558 LocalFree((HLOCAL
)szDisplayString
);
560 /* FIXME - update the checkboxes */
564 WCHAR szPermissions
[255];
566 if (LoadString(hDllInstance
,
569 sizeof(szPermissions
) / sizeof(szPermissions
[0])))
571 SetWindowText(sp
->hPermissionsForLabel
,
575 SendMessage(sp
->hAceCheckList
,
583 UpdatePrincipalInfo(IN PSECURITY_PAGE sp
,
584 IN PSIDLOOKUPNOTIFYINFO LookupInfo
)
586 PPRINCIPAL_LISTITEM CurItem
;
588 for (CurItem
= sp
->PrincipalsListHead
;
590 CurItem
= CurItem
->Next
)
592 if (EqualSid((PSID
)(CurItem
+ 1),
598 /* find the principal in the list */
599 lvfi
.flags
= LVFI_PARAM
;
600 lvfi
.lParam
= (LPARAM
)CurItem
;
601 PrincipalIndex
= ListView_FindItem(sp
->hWndPrincipalsList
,
605 if (PrincipalIndex
!= -1)
607 /* update the principal in the list view control */
608 UpdatePrincipalListItem(sp
,
611 LookupInfo
->SidRequestResult
);
613 if (ListViewGetSelectedItemData(sp
->hWndPrincipalsList
) == (LPARAM
)CurItem
)
615 UpdateControlStates(sp
);
620 AddPrincipalListEntry(sp
,
631 SecurityPageCallback(IN HWND hwnd
,
633 IN LPPROPSHEETPAGE ppsp
)
635 PSECURITY_PAGE sp
= (PSECURITY_PAGE
)ppsp
->lParam
;
645 DestroySecurityPage(sp
);
654 SetAceCheckListColumns(IN HWND hAceCheckList
,
661 GetWindowRect(hLabel
,
664 pt
.x
= (rcLabel
.right
- rcLabel
.left
) / 2;
665 MapWindowPoints(hLabel
,
670 SendMessage(hAceCheckList
,
671 CLM_SETCHECKBOXCOLUMN
,
677 LoadPermissionsList(IN PSECURITY_PAGE sp
,
678 IN GUID
*GuidObjectType
,
680 OUT SI_ACCESS
*DefaultAccess
)
683 PSI_ACCESS AccessList
;
684 ULONG nAccessList
, DefaultAccessIndex
;
685 WCHAR szSpecialPermissions
[255];
686 BOOLEAN SpecialPermissionsPresent
= FALSE
;
687 ACCESS_MASK SpecialPermissionsMask
= 0;
689 /* clear the permissions list */
691 SendMessage(sp
->hAceCheckList
,
696 /* query the access rights from the server */
697 hRet
= sp
->psi
->lpVtbl
->GetAccessRights(sp
->psi
,
702 &DefaultAccessIndex
);
703 if (SUCCEEDED(hRet
) && nAccessList
!= 0)
706 PSI_ACCESS CurAccess
, LastAccess
;
707 WCHAR NameBuffer
[MAX_PATH
];
709 /* save the default access rights to be used when adding ACEs later */
710 if (DefaultAccess
!= NULL
)
712 *DefaultAccess
= AccessList
[DefaultAccessIndex
];
715 LastAccess
= AccessList
+ nAccessList
;
716 for (CurAccess
= &AccessList
[0];
717 CurAccess
!= LastAccess
;
720 if (CurAccess
->dwFlags
& dwFlags
)
722 /* get the permission name, load it from a string table if necessary */
723 if (IS_INTRESOURCE(CurAccess
->pszName
))
725 if (!LoadString(sp
->ObjectInfo
.hInstance
,
726 (UINT
)((ULONG_PTR
)CurAccess
->pszName
),
728 sizeof(NameBuffer
) / sizeof(NameBuffer
[0])))
730 LoadString(hDllInstance
,
733 sizeof(NameBuffer
) / sizeof(NameBuffer
[0]));
735 NameStr
= NameBuffer
;
739 NameStr
= CurAccess
->pszName
;
742 SendMessage(sp
->hAceCheckList
,
744 (WPARAM
)CurAccess
->mask
,
747 else if (CurAccess
->dwFlags
& SI_ACCESS_SPECIFIC
)
749 SpecialPermissionsPresent
= TRUE
;
750 SpecialPermissionsMask
|= CurAccess
->mask
;
755 /* add the special permissions check item in case the specific access rights
757 if (SpecialPermissionsPresent
&&
758 LoadString(hDllInstance
,
759 IDS_SPECIAL_PERMISSIONS
,
760 szSpecialPermissions
,
761 sizeof(szSpecialPermissions
) / sizeof(szSpecialPermissions
[0])))
763 /* add the special permissions check item */
764 sp
->SpecialPermCheckIndex
= (INT
)SendMessage(sp
->hAceCheckList
,
766 (WPARAM
)SpecialPermissionsMask
,
767 (LPARAM
)szSpecialPermissions
);
768 if (sp
->SpecialPermCheckIndex
!= -1)
770 SendMessage(sp
->hAceCheckList
,
772 (WPARAM
)sp
->SpecialPermCheckIndex
,
773 CIS_ALLOWDISABLED
| CIS_DENYDISABLED
| CIS_NONE
);
779 ResizeControls(IN PSECURITY_PAGE sp
,
783 HWND hWndAllow
, hWndDeny
;
784 RECT rcControl
, rcControl2
, rcControl3
, rcWnd
;
785 INT cxWidth
, cxEdge
, btnSpacing
;
791 hWndAllow
= GetDlgItem(sp
->hWnd
,
793 hWndDeny
= GetDlgItem(sp
->hWnd
,
796 GetWindowRect(sp
->hWnd
,
799 cxEdge
= GetSystemMetrics(SM_CXEDGE
);
801 /* use the left margin of the principal list view control for all control
805 MapWindowPoints(sp
->hWndPrincipalsList
,
809 cxWidth
= Width
- (2 * pt
.x
);
811 if (sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
)
816 if ((dwp
= BeginDeferWindowPos(nControls
)))
818 /* resize the Principal list view */
819 GetWindowRect(sp
->hWndPrincipalsList
,
821 if (!(dwp
= DeferWindowPos(dwp
,
822 sp
->hWndPrincipalsList
,
827 rcControl
.bottom
- rcControl
.top
,
828 SWP_NOMOVE
| SWP_NOZORDER
)))
833 /* move the Add Principal button */
834 GetWindowRect(sp
->hBtnAdd
,
836 GetWindowRect(sp
->hBtnRemove
,
838 btnSpacing
= rcControl2
.left
- rcControl
.right
;
841 MapWindowPoints(sp
->hBtnAdd
,
845 if (!(dwp
= DeferWindowPos(dwp
,
848 pt
.x
+ cxWidth
- (rcControl2
.right
- rcControl2
.left
) -
849 (rcControl
.right
- rcControl
.left
) -
854 SWP_NOSIZE
| SWP_NOZORDER
)))
859 /* move the Delete Principal button */
862 MapWindowPoints(sp
->hBtnRemove
,
866 if (!(dwp
= DeferWindowPos(dwp
,
869 pt
.x
+ cxWidth
- (rcControl2
.right
- rcControl2
.left
) - cxEdge
,
873 SWP_NOSIZE
| SWP_NOZORDER
)))
878 /* move the Permissions For label */
879 GetWindowRect(hWndAllow
,
881 GetWindowRect(hWndDeny
,
883 GetWindowRect(sp
->hPermissionsForLabel
,
887 MapWindowPoints(sp
->hPermissionsForLabel
,
891 if (!(dwp
= DeferWindowPos(dwp
,
892 sp
->hPermissionsForLabel
,
896 cxWidth
- (rcControl2
.right
- rcControl2
.left
) -
897 (rcControl
.right
- rcControl
.left
) -
898 (2 * btnSpacing
) - cxEdge
,
899 rcControl3
.bottom
- rcControl3
.top
,
900 SWP_NOMOVE
| SWP_NOZORDER
)))
905 /* move the Allow label */
908 MapWindowPoints(hWndAllow
,
912 if (!(dwp
= DeferWindowPos(dwp
,
915 cxWidth
- (rcControl2
.right
- rcControl2
.left
) -
916 (rcControl
.right
- rcControl
.left
) -
921 SWP_NOSIZE
| SWP_NOZORDER
)))
926 /* move the Deny label */
929 MapWindowPoints(hWndDeny
,
933 if (!(dwp
= DeferWindowPos(dwp
,
936 cxWidth
- (rcControl2
.right
- rcControl2
.left
) - cxEdge
,
940 SWP_NOSIZE
| SWP_NOZORDER
)))
945 /* resize the Permissions check list box */
946 GetWindowRect(sp
->hAceCheckList
,
948 GetWindowRect(sp
->hBtnAdvanced
,
950 GetWindowRect(GetDlgItem(sp
->hWnd
,
953 if (!(dwp
= DeferWindowPos(dwp
,
959 ((sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
) ?
960 Height
- (rcControl
.top
- rcWnd
.top
) -
961 (rcControl3
.bottom
- rcControl3
.top
) - pt
.x
- btnSpacing
:
962 Height
- (rcControl
.top
- rcWnd
.top
) - pt
.x
),
963 SWP_NOMOVE
| SWP_NOZORDER
)))
968 if (sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
)
970 /* move and resize the Advanced label */
971 if (!(dwp
= DeferWindowPos(dwp
,
976 Height
- (rcControl3
.bottom
- rcControl3
.top
) - pt
.x
,
977 cxWidth
- (rcControl2
.right
- rcControl2
.left
) - cxEdge
,
978 rcControl3
.bottom
- rcControl3
.top
,
984 /* move and resize the Advanced button */
985 if (!(dwp
= DeferWindowPos(dwp
,
988 cxWidth
- (rcControl2
.right
- rcControl2
.left
) + pt
.x
,
989 Height
- (rcControl2
.bottom
- rcControl2
.top
) - pt
.x
,
992 SWP_NOSIZE
| SWP_NOZORDER
)))
998 EndDeferWindowPos(dwp
);
1002 /* update the width of the principal list view column */
1003 GetClientRect(sp
->hWndPrincipalsList
,
1005 lvc
.mask
= LVCF_WIDTH
;
1006 lvc
.cx
= rcControl
.right
;
1007 ListView_SetColumn(sp
->hWndPrincipalsList
,
1011 /* calculate the columns of the allow/deny checkboxes */
1012 SetAceCheckListColumns(sp
->hAceCheckList
,
1015 SetAceCheckListColumns(sp
->hAceCheckList
,
1021 BuildDefaultPrincipalAce(IN PSECURITY_PAGE sp
,
1024 PACCESS_ALLOWED_ACE Ace
;
1028 SidLen
= GetLengthSid(pSid
);
1029 AceSize
= sizeof(ACCESS_ALLOWED_ACE
) + (WORD
)SidLen
- sizeof(DWORD
);
1030 Ace
= HeapAlloc(GetProcessHeap(),
1035 Ace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
1036 Ace
->Header
.AceFlags
= 0; /* FIXME */
1037 Ace
->Header
.AceSize
= AceSize
;
1038 Ace
->Mask
= sp
->DefaultAccess
.mask
;
1041 (PSID
)&Ace
->SidStart
,
1044 return &Ace
->Header
;
1047 HeapFree(GetProcessHeap(),
1056 AddSelectedPrincipal(IN IDsObjectPicker
*pDsObjectPicker
,
1057 IN HWND hwndParent OPTIONAL
,
1059 IN PVOID Context OPTIONAL
)
1061 PACE_HEADER AceHeader
;
1062 PSECURITY_PAGE sp
= (PSECURITY_PAGE
)Context
;
1064 AceHeader
= BuildDefaultPrincipalAce(sp
,
1066 if (AceHeader
!= NULL
)
1068 PPRINCIPAL_LISTITEM PrincipalListItem
;
1069 BOOL LookupDeferred
;
1071 PrincipalListItem
= AddPrincipalToList(sp
,
1076 if (PrincipalListItem
!= NULL
&& LookupDeferred
)
1078 AddPrincipalListEntry(sp
,
1084 HeapFree(GetProcessHeap(),
1092 static INT_PTR CALLBACK
1093 SecurityPageProc(IN HWND hwndDlg
,
1099 INT_PTR Ret
= FALSE
;
1101 sp
= (PSECURITY_PAGE
)GetWindowLongPtr(hwndDlg
,
1103 if (sp
!= NULL
|| uMsg
== WM_INITDIALOG
)
1109 NMHDR
*pnmh
= (NMHDR
*)lParam
;
1111 if (pnmh
->hwndFrom
== sp
->hWndPrincipalsList
)
1115 case LVN_ITEMCHANGED
:
1117 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
)lParam
;
1119 if ((pnmv
->uChanged
& LVIF_STATE
) &&
1120 ((pnmv
->uOldState
& (LVIS_FOCUSED
| LVIS_SELECTED
)) ||
1121 (pnmv
->uNewState
& (LVIS_FOCUSED
| LVIS_SELECTED
))))
1123 UpdateControlStates(sp
);
1129 else if (pnmh
->hwndFrom
== sp
->hAceCheckList
)
1133 case CLN_CHANGINGITEMCHECKBOX
:
1135 PNMCHANGEITEMCHECKBOX pcicb
= (PNMCHANGEITEMCHECKBOX
)lParam
;
1137 /* make sure only one of both checkboxes is only checked
1141 pcicb
->NewState
&= ~((pcicb
->CheckBox
!= CLB_DENY
) ? CIS_DENY
: CIS_ALLOW
);
1147 else if (pnmh
->hwndFrom
== sp
->hWnd
)
1151 case SIDN_LOOKUPSUCCEEDED
:
1153 PSIDLOOKUPNOTIFYINFO LookupInfo
= CONTAINING_RECORD(lParam
,
1154 SIDLOOKUPNOTIFYINFO
,
1157 /* a SID lookup succeeded, update the information */
1158 UpdatePrincipalInfo(sp
,
1169 switch (LOWORD(wParam
))
1171 case IDC_ADD_PRINCIPAL
:
1175 hRet
= InitializeObjectPicker(sp
->ServerName
,
1177 &sp
->pDsObjectPicker
);
1178 if (SUCCEEDED(hRet
))
1180 hRet
= InvokeObjectPickerDialog(sp
->pDsObjectPicker
,
1182 AddSelectedPrincipal
,
1186 MessageBox(hwndDlg
, L
"InvokeObjectPickerDialog failed!\n", NULL
, 0);
1189 /* delete the instance */
1190 FreeObjectPicker(sp
->pDsObjectPicker
);
1194 MessageBox(hwndDlg
, L
"InitializeObjectPicker failed!\n", NULL
, 0);
1199 case IDC_REMOVE_PRINCIPAL
:
1201 PPRINCIPAL_LISTITEM SelectedPrincipal
;
1203 SelectedPrincipal
= (PPRINCIPAL_LISTITEM
)ListViewGetSelectedItemData(sp
->hWndPrincipalsList
);
1204 if (SelectedPrincipal
!= NULL
)
1217 (INT
)LOWORD(lParam
),
1218 (INT
)HIWORD(lParam
));
1224 sp
= (PSECURITY_PAGE
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1231 sp
->hWndPrincipalsList
= GetDlgItem(hwndDlg
, IDC_PRINCIPALS
);
1232 sp
->hBtnAdd
= GetDlgItem(hwndDlg
, IDC_ADD_PRINCIPAL
);
1233 sp
->hBtnRemove
= GetDlgItem(hwndDlg
, IDC_REMOVE_PRINCIPAL
);
1234 sp
->hBtnAdvanced
= GetDlgItem(hwndDlg
, IDC_ADVANCED
);
1235 sp
->hAceCheckList
= GetDlgItem(hwndDlg
, IDC_ACE_CHECKLIST
);
1236 sp
->hPermissionsForLabel
= GetDlgItem(hwndDlg
, IDC_LABEL_PERMISSIONS_FOR
);
1238 sp
->SpecialPermCheckIndex
= -1;
1240 /* save the pointer to the structure */
1241 SetWindowLongPtr(hwndDlg
,
1245 ListView_SetExtendedListViewStyleEx(sp
->hWndPrincipalsList
,
1246 LVS_EX_FULLROWSELECT
,
1247 LVS_EX_FULLROWSELECT
);
1249 sp
->hiPrincipals
= ImageList_LoadBitmap(hDllInstance
,
1250 MAKEINTRESOURCE(IDB_USRGRPIMAGES
),
1257 /* setup the listview control */
1258 if (sp
->hiPrincipals
!= NULL
)
1260 ListView_SetImageList(sp
->hWndPrincipalsList
,
1265 GetClientRect(sp
->hWndPrincipalsList
,
1268 /* add a column to the list view */
1269 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
1270 lvc
.fmt
= LVCFMT_LEFT
;
1271 lvc
.cx
= rcLvClient
.right
;
1272 ListView_InsertColumn(sp
->hWndPrincipalsList
,
1276 ReloadPrincipalsList(sp
);
1278 ListViewSelectItem(sp
->hWndPrincipalsList
,
1281 /* calculate the columns of the allow/deny checkboxes */
1282 SetAceCheckListColumns(sp
->hAceCheckList
,
1284 GetDlgItem(hwndDlg
, IDC_LABEL_ALLOW
));
1285 SetAceCheckListColumns(sp
->hAceCheckList
,
1287 GetDlgItem(hwndDlg
, IDC_LABEL_DENY
));
1289 LoadPermissionsList(sp
,
1292 ((sp
->ObjectInfo
.dwFlags
& SI_CONTAINER
) ? SI_ACCESS_CONTAINER
: 0),
1293 &sp
->DefaultAccess
);
1295 /* hide controls in case the flags aren't present */
1296 if (sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
)
1298 /* editing the permissions is least the user can do when
1299 the advanced button is showed */
1300 sp
->ObjectInfo
.dwFlags
|= SI_EDIT_PERMS
;
1304 ShowWindow(sp
->hBtnAdvanced
,
1306 ShowWindow(GetDlgItem(hwndDlg
, IDC_LABEL_ADVANCED
),
1310 /* enable quicksearch for the permissions checklist control */
1311 SendMessage(sp
->hAceCheckList
,
1312 CLM_ENABLEQUICKSEARCH
,
1316 UpdateControlStates(sp
);
1329 * CreateSecurityPage EXPORTED
1335 CreateSecurityPage(IN LPSECURITYINFO psi
)
1337 PROPSHEETPAGE psp
= {0};
1338 PSECURITY_PAGE sPage
;
1339 SI_OBJECT_INFO ObjectInfo
= {0};
1341 LPCWSTR SystemName
= NULL
;
1346 SetLastError(ERROR_INVALID_PARAMETER
);
1348 DPRINT("No ISecurityInformation class passed!\n");
1352 /* get the object information from the server. Zero the structure before
1353 because some applications seem to return SUCCESS but only seem to set the
1354 fields they care about. */
1355 hRet
= psi
->lpVtbl
->GetObjectInformation(psi
,
1362 DPRINT("CreateSecurityPage() failed! Failed to query the object information!\n");
1366 if ((ObjectInfo
.dwFlags
& SI_SERVER_IS_DC
) &&
1367 ObjectInfo
.pszServerName
!= NULL
&&
1368 ObjectInfo
.pszServerName
[0] != L
'\0')
1370 SystemName
= ObjectInfo
.pszServerName
;
1373 SidCacheMgr
= CreateSidCacheMgr(GetProcessHeap(),
1375 if (SidCacheMgr
== NULL
)
1377 DPRINT("Creating the SID cache failed!\n");
1381 hRet
= CoInitialize(NULL
);
1384 DestroySidCacheMgr(SidCacheMgr
);
1385 DPRINT("CoInitialize failed!\n");
1389 sPage
= HeapAlloc(GetProcessHeap(),
1391 sizeof(SECURITY_PAGE
));
1394 DestroySidCacheMgr(SidCacheMgr
);
1397 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1399 DPRINT("Not enough memory to allocate a SECURITY_PAGE!\n");
1404 sPage
->ObjectInfo
= ObjectInfo
;
1405 sPage
->ServerName
= SystemName
;
1406 sPage
->SidCacheMgr
= SidCacheMgr
;
1408 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1409 psp
.dwFlags
= PSP_USECALLBACK
;
1410 psp
.hInstance
= hDllInstance
;
1411 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SECPAGE
);
1412 psp
.pfnDlgProc
= SecurityPageProc
;
1413 psp
.lParam
= (LPARAM
)sPage
;
1414 psp
.pfnCallback
= SecurityPageCallback
;
1416 if (ObjectInfo
.dwFlags
& SI_PAGE_TITLE
)
1418 psp
.pszTitle
= ObjectInfo
.pszPageTitle
;
1420 if (psp
.pszTitle
!= NULL
)
1422 psp
.dwFlags
|= PSP_USETITLE
;
1427 psp
.pszTitle
= NULL
;
1430 /* NOTE: the SECURITY_PAGE structure will be freed by the property page
1433 return CreatePropertySheetPage(&psp
);
1438 * EditSecurity EXPORTED
1444 EditSecurity(IN HWND hwndOwner
,
1445 IN LPSECURITYINFO psi
)
1448 SI_OBJECT_INFO ObjectInfo
= {0};
1449 PROPSHEETHEADER psh
;
1450 HPROPSHEETPAGE hPages
[1];
1451 LPWSTR lpCaption
= NULL
;
1456 SetLastError(ERROR_INVALID_PARAMETER
);
1458 DPRINT("No ISecurityInformation class passed!\n");
1462 /* get the object information from the server. Zero the structure before
1463 because some applications seem to return SUCCESS but only seem to set the
1464 fields they care about. */
1465 hRet
= psi
->lpVtbl
->GetObjectInformation(psi
,
1472 DPRINT("GetObjectInformation() failed!\n");
1476 /* create the page */
1477 hPages
[0] = CreateSecurityPage(psi
);
1478 if (hPages
[0] == NULL
)
1480 DPRINT("CreateSecurityPage(), couldn't create property sheet!\n");
1484 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1485 psh
.dwFlags
= PSH_DEFAULT
;
1486 psh
.hwndParent
= hwndOwner
;
1487 psh
.hInstance
= hDllInstance
;
1489 /* Set the page title to the object name, make sure the format string
1490 has "%1" NOT "%s" because it uses FormatMessage() to automatically
1491 allocate the right amount of memory. */
1492 if (LoadAndFormatString(hDllInstance
,
1495 ObjectInfo
.pszObjectName
))
1497 psh
.pszCaption
= lpCaption
;
1501 psh
.pszCaption
= ObjectInfo
.pszObjectName
;
1504 psh
.nPages
= sizeof(hPages
) / sizeof(HPROPSHEETPAGE
);
1506 psh
.phpage
= hPages
;
1508 Ret
= (PropertySheet(&psh
) != -1);
1510 if (lpCaption
!= NULL
)
1512 LocalFree((HLOCAL
)lpCaption
);
1520 DllMain(IN HINSTANCE hinstDLL
,
1522 IN LPVOID lpvReserved
)
1526 case DLL_PROCESS_ATTACH
:
1527 hDllInstance
= hinstDLL
;
1529 DisableThreadLibraryCalls(hinstDLL
);
1531 if (!RegisterCheckListControl(hinstDLL
))
1533 DPRINT("Registering the CHECKLIST_ACLUI class failed!\n");
1538 case DLL_PROCESS_DETACH
:
1539 UnregisterCheckListControl();