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>
31 HINSTANCE hDllInstance
;
34 AceHeaderToSID(IN PACE_HEADER AceHeader
)
37 switch (AceHeader
->AceType
)
39 case ACCESS_ALLOWED_ACE_TYPE
:
40 Sid
= (PSID
)&((PACCESS_ALLOWED_ACE
)AceHeader
)->SidStart
;
43 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE
:
44 Sid
= (PSID
)&((PACCESS_ALLOWED_CALLBACK_ACE
)AceHeader
)->SidStart
;
46 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
:
47 Sid
= (PSID
)&((PACCESS_ALLOWED_CALLBACK_OBJECT_ACE
)AceHeader
)->SidStart
;
50 case ACCESS_ALLOWED_OBJECT_ACE_TYPE
:
51 Sid
= (PSID
)&((PACCESS_ALLOWED_OBJECT_ACE
)AceHeader
)->SidStart
;
53 case ACCESS_DENIED_ACE_TYPE
:
54 Sid
= (PSID
)&((PACCESS_DENIED_ACE
)AceHeader
)->SidStart
;
57 case ACCESS_DENIED_CALLBACK_ACE_TYPE
:
58 Sid
= (PSID
)&((PACCESS_DENIED_CALLBACK_ACE
)AceHeader
)->SidStart
;
60 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
:
61 Sid
= (PSID
)&((PACCESS_DENIED_CALLBACK_OBJECT_ACE
)AceHeader
)->SidStart
;
64 case SYSTEM_AUDIT_OBJECT_ACE_TYPE
:
65 Sid
= (PSID
)&((PACCESS_DENIED_OBJECT_ACE
)AceHeader
)->SidStart
;
73 DestroySecurityPage(IN PSECURITY_PAGE sp
)
75 if(sp
->hiPrincipals
!= NULL
)
77 ImageList_Destroy(sp
->hiPrincipals
);
80 HeapFree(GetProcessHeap(),
88 FreePrincipalsList(IN PPRINCIPAL_LISTITEM
*PrincipalsListHead
)
90 PPRINCIPAL_LISTITEM CurItem
, NextItem
;
91 PACE_ENTRY AceEntry
, NextAceEntry
;
93 CurItem
= *PrincipalsListHead
;
94 while (CurItem
!= NULL
)
97 AceEntry
= CurItem
->ACEs
;
98 while (AceEntry
!= NULL
)
100 NextAceEntry
= AceEntry
->Next
;
101 HeapFree(GetProcessHeap(),
104 AceEntry
= NextAceEntry
;
107 /* free the SID string if present */
108 if (CurItem
->DisplayString
!= NULL
)
110 LocalFree((HLOCAL
)CurItem
->DisplayString
);
113 /* free the ACE list item */
114 NextItem
= CurItem
->Next
;
115 HeapFree(GetProcessHeap(),
121 *PrincipalsListHead
= NULL
;
125 AddAceToPrincipal(IN PPRINCIPAL_LISTITEM Principal
,
126 IN PACE_HEADER AceHeader
)
128 PACE_ENTRY AceEntry
, *AceLink
;
130 AceEntry
= HeapAlloc(GetProcessHeap(),
132 sizeof(ACE_ENTRY
) + AceHeader
->AceSize
);
133 if (AceEntry
!= NULL
)
135 AceEntry
->Next
= NULL
;
138 CopyMemory(AceEntry
+ 1,
142 /* append it to the list */
143 AceLink
= &Principal
->ACEs
;
144 while (*AceLink
!= NULL
)
146 AceLink
= &(*AceLink
)->Next
;
154 static PPRINCIPAL_LISTITEM
155 FindSidInPrincipalsListAddAce(IN PPRINCIPAL_LISTITEM PrincipalsListHead
,
157 IN PACE_HEADER AceHeader
)
159 PPRINCIPAL_LISTITEM CurItem
;
161 for (CurItem
= PrincipalsListHead
;
163 CurItem
= CurItem
->Next
)
165 if (EqualSid((PSID
)(CurItem
+ 1),
168 if (AddAceToPrincipal(CurItem
,
174 /* unable to add the ACE to the principal */
183 AddPrincipalToList(IN PSECURITY_PAGE sp
,
185 IN PACE_HEADER AceHeader
)
187 PPRINCIPAL_LISTITEM PrincipalListItem
= NULL
;
188 PACE_ENTRY AceEntry
= NULL
;
191 if (!FindSidInPrincipalsListAddAce(sp
->PrincipalsListHead
,
195 DWORD SidLength
, AccountNameSize
, DomainNameSize
;
196 SID_NAME_USE SidNameUse
;
198 PPRINCIPAL_LISTITEM PrincipalListItem
, *PrincipalLink
;
203 /* calculate the size of the buffer we need to calculate */
204 if (!LookupAccountSid(sp
->ServerName
,
212 LookupResult
= GetLastError();
213 if (LookupResult
!= ERROR_NONE_MAPPED
&&
214 LookupResult
!= ERROR_INSUFFICIENT_BUFFER
)
220 PrincipalLink
= &sp
->PrincipalsListHead
;
221 while (*PrincipalLink
!= NULL
)
223 PrincipalLink
= &(*PrincipalLink
)->Next
;
226 SidLength
= GetLengthSid(Sid
);
228 /* allocate the principal */
229 PrincipalListItem
= HeapAlloc(GetProcessHeap(),
231 sizeof(PRINCIPAL_LISTITEM
) + SidLength
+
232 ((AccountNameSize
+ DomainNameSize
) * sizeof(WCHAR
)));
233 if (PrincipalListItem
!= NULL
)
235 PrincipalListItem
->AccountName
= (LPWSTR
)((ULONG_PTR
)(PrincipalListItem
+ 1) + SidLength
);
236 PrincipalListItem
->DomainName
= PrincipalListItem
->AccountName
+ AccountNameSize
;
239 (PSID
)(PrincipalListItem
+ 1),
242 LookupResult
= ERROR_SUCCESS
;
243 if (!LookupAccountSid(sp
->ServerName
,
245 PrincipalListItem
->AccountName
,
247 PrincipalListItem
->DomainName
,
251 LookupResult
= GetLastError();
252 if (LookupResult
!= ERROR_NONE_MAPPED
)
258 if (AccountNameSize
== 0)
260 PrincipalListItem
->AccountName
= NULL
;
262 if (DomainNameSize
== 0)
264 PrincipalListItem
->DomainName
= NULL
;
267 /* allocate some memory for the ACE and copy it */
268 AceEntry
= HeapAlloc(GetProcessHeap(),
270 sizeof(ACE_ENTRY
) + AceHeader
->AceSize
);
271 if (AceEntry
== NULL
)
275 AceEntry
->Next
= NULL
;
276 CopyMemory(AceEntry
+ 1,
280 /* add the ACE to the list */
281 PrincipalListItem
->ACEs
= AceEntry
;
283 PrincipalListItem
->Next
= NULL
;
286 if (LookupResult
== ERROR_NONE_MAPPED
)
288 if (!ConvertSidToStringSid(Sid
,
289 &PrincipalListItem
->DisplayString
))
291 PrincipalListItem
->DisplayString
= NULL
;
296 LSA_HANDLE LsaHandle
;
299 PrincipalListItem
->DisplayString
= NULL
;
301 /* read the domain of the SID */
302 if (OpenLSAPolicyHandle(sp
->ServerName
,
303 POLICY_LOOKUP_NAMES
| POLICY_VIEW_LOCAL_INFORMATION
,
306 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
;
307 PLSA_TRANSLATED_NAME Names
;
308 PLSA_TRUST_INFORMATION Domain
;
309 PLSA_UNICODE_STRING DomainName
;
310 PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo
= NULL
;
312 Status
= LsaLookupSids(LsaHandle
,
317 if (NT_SUCCESS(Status
))
319 if (ReferencedDomain
!= NULL
&&
320 Names
->DomainIndex
>= 0)
322 Domain
= &ReferencedDomain
->Domains
[Names
->DomainIndex
];
323 DomainName
= &Domain
->Name
;
331 PrincipalListItem
->SidNameUse
= Names
->Use
;
338 /* query the domain name for BUILTIN accounts */
339 Status
= LsaQueryInformationPolicy(LsaHandle
,
340 PolicyAccountDomainInformation
,
341 (PVOID
*)&PolicyAccountDomainInfo
);
342 if (NT_SUCCESS(Status
))
344 DomainName
= &PolicyAccountDomainInfo
->DomainName
;
346 /* make the user believe this is a group */
347 PrincipalListItem
->SidNameUse
= SidTypeGroup
;
356 SIZE_T Size
= (AccountNameSize
+ DomainName
->Length
+
357 Names
->Name
.Length
+ 6) * sizeof(WCHAR
);
358 PrincipalListItem
->DisplayString
= (LPWSTR
)LocalAlloc(LMEM_FIXED
,
360 if (PrincipalListItem
->DisplayString
!= NULL
)
364 /* NOTE: LSA_UNICODE_STRINGs are not always NULL-terminated! */
366 wcscpy(PrincipalListItem
->DisplayString
,
367 PrincipalListItem
->AccountName
);
368 wcscat(PrincipalListItem
->DisplayString
,
370 s
= PrincipalListItem
->DisplayString
+ wcslen(PrincipalListItem
->DisplayString
);
374 s
+= DomainName
->Length
/ sizeof(WCHAR
);
379 s
+= Names
->Name
.Length
/ sizeof(WCHAR
);
389 /* mark the ace as a user unless it's a
391 if (PolicyAccountDomainInfo
== NULL
)
393 PrincipalListItem
->SidNameUse
= SidTypeUser
;
399 case SidTypeWellKnownGroup
:
401 /* make the user believe this is a group */
402 PrincipalListItem
->SidNameUse
= SidTypeGroup
;
408 DPRINT("Unhandled SID type: 0x%x\n", Names
->Use
);
413 if (PolicyAccountDomainInfo
!= NULL
)
415 LsaFreeMemory(PolicyAccountDomainInfo
);
418 LsaFreeMemory(ReferencedDomain
);
419 LsaFreeMemory(Names
);
427 /* append item to the principals list */
428 *PrincipalLink
= PrincipalListItem
;
436 if (PrincipalListItem
!= NULL
)
438 if (PrincipalListItem
->DisplayString
!= NULL
)
440 LocalFree((HLOCAL
)PrincipalListItem
->DisplayString
);
443 HeapFree(GetProcessHeap(),
448 if (AceEntry
!= NULL
)
450 HeapFree(GetProcessHeap(),
460 ReloadPrincipalsList(IN PSECURITY_PAGE sp
)
462 PSECURITY_DESCRIPTOR SecurityDescriptor
;
463 BOOL DaclPresent
, DaclDefaulted
;
467 /* delete the cached ACL */
468 FreePrincipalsList(&sp
->PrincipalsListHead
);
471 hRet
= sp
->psi
->lpVtbl
->GetSecurity(sp
->psi
,
472 DACL_SECURITY_INFORMATION
,
475 if (SUCCEEDED(hRet
) && SecurityDescriptor
!= NULL
)
477 if (GetSecurityDescriptorDacl(SecurityDescriptor
,
481 DaclPresent
&& Dacl
!= NULL
)
484 PACE_HEADER AceHeader
;
488 AceIndex
< Dacl
->AceCount
;
493 (LPVOID
*)&AceHeader
) &&
496 Sid
= AceHeaderToSID(AceHeader
);
498 AddPrincipalToList(sp
,
504 LocalFree((HLOCAL
)SecurityDescriptor
);
509 AddPrincipalListEntry(IN PSECURITY_PAGE sp
,
510 IN PPRINCIPAL_LISTITEM PrincipalListItem
,
516 li
.mask
= LVIF_IMAGE
| LVIF_PARAM
| LVIF_STATE
| LVIF_TEXT
;
519 li
.state
= (Selected
? LVIS_SELECTED
: 0);
520 li
.stateMask
= LVIS_SELECTED
;
521 li
.pszText
= (PrincipalListItem
->DisplayString
!= NULL
?
522 PrincipalListItem
->DisplayString
:
523 PrincipalListItem
->AccountName
);
525 switch (PrincipalListItem
->SidNameUse
)
537 li
.lParam
= (LPARAM
)PrincipalListItem
;
539 return ListView_InsertItem(sp
->hWndPrincipalsList
,
544 FillPrincipalsList(IN PSECURITY_PAGE sp
)
547 PPRINCIPAL_LISTITEM CurItem
;
550 SelLParam
= ListViewGetSelectedItemData(sp
->hWndPrincipalsList
);
552 DisableRedrawWindow(sp
->hWndPrincipalsList
);
554 ListView_DeleteAllItems(sp
->hWndPrincipalsList
);
556 for (CurItem
= sp
->PrincipalsListHead
;
558 CurItem
= CurItem
->Next
)
560 AddPrincipalListEntry(sp
,
563 (SelLParam
== (LPARAM
)CurItem
));
566 EnableRedrawWindow(sp
->hWndPrincipalsList
);
568 GetClientRect(sp
->hWndPrincipalsList
,
571 ListView_SetColumnWidth(sp
->hWndPrincipalsList
,
577 UpdateControlStates(IN PSECURITY_PAGE sp
)
579 PPRINCIPAL_LISTITEM Selected
= (PPRINCIPAL_LISTITEM
)ListViewGetSelectedItemData(sp
->hWndPrincipalsList
);
581 EnableWindow(sp
->hBtnRemove
,
583 EnableWindow(sp
->hAceCheckList
,
586 if (Selected
!= NULL
)
590 if (LoadAndFormatString(hDllInstance
,
593 Selected
->AccountName
))
595 SetWindowText(sp
->hPermissionsForLabel
,
598 LocalFree((HLOCAL
)szLabel
);
601 /* FIXME - update the checkboxes */
605 WCHAR szPermissions
[255];
607 if (LoadString(hDllInstance
,
610 sizeof(szPermissions
) / sizeof(szPermissions
[0])))
612 SetWindowText(sp
->hPermissionsForLabel
,
616 SendMessage(sp
->hAceCheckList
,
624 SecurityPageCallback(IN HWND hwnd
,
626 IN LPPROPSHEETPAGE ppsp
)
628 PSECURITY_PAGE sp
= (PSECURITY_PAGE
)ppsp
->lParam
;
638 DestroySecurityPage(sp
);
647 SetAceCheckListColumns(IN HWND hAceCheckList
,
654 GetWindowRect(hLabel
,
657 pt
.x
= (rcLabel
.right
- rcLabel
.left
) / 2;
658 MapWindowPoints(hLabel
,
663 SendMessage(hAceCheckList
,
664 CLM_SETCHECKBOXCOLUMN
,
670 LoadPermissionsList(IN PSECURITY_PAGE sp
,
671 IN GUID
*GuidObjectType
,
673 OUT SI_ACCESS
*DefaultAccess
)
676 PSI_ACCESS AccessList
;
677 ULONG nAccessList
, DefaultAccessIndex
;
678 WCHAR szSpecialPermissions
[255];
679 BOOLEAN SpecialPermissionsPresent
= FALSE
;
680 ACCESS_MASK SpecialPermissionsMask
= 0;
682 /* clear the permissions list */
684 SendMessage(sp
->hAceCheckList
,
689 /* query the access rights from the server */
690 hRet
= sp
->psi
->lpVtbl
->GetAccessRights(sp
->psi
,
695 &DefaultAccessIndex
);
696 if (SUCCEEDED(hRet
) && nAccessList
!= 0)
699 PSI_ACCESS CurAccess
, LastAccess
;
700 WCHAR NameBuffer
[MAX_PATH
];
702 /* save the default access rights to be used when adding ACEs later */
703 if (DefaultAccess
!= NULL
)
705 *DefaultAccess
= AccessList
[DefaultAccessIndex
];
708 LastAccess
= AccessList
+ nAccessList
;
709 for (CurAccess
= &AccessList
[0];
710 CurAccess
!= LastAccess
;
713 if (CurAccess
->dwFlags
& dwFlags
)
715 /* get the permission name, load it from a string table if necessary */
716 if (IS_INTRESOURCE(CurAccess
->pszName
))
718 if (!LoadString(sp
->ObjectInfo
.hInstance
,
719 (UINT
)((ULONG_PTR
)CurAccess
->pszName
),
721 sizeof(NameBuffer
) / sizeof(NameBuffer
[0])))
723 LoadString(hDllInstance
,
726 sizeof(NameBuffer
) / sizeof(NameBuffer
[0]));
728 NameStr
= NameBuffer
;
732 NameStr
= CurAccess
->pszName
;
735 SendMessage(sp
->hAceCheckList
,
737 (WPARAM
)CurAccess
->mask
,
740 else if (CurAccess
->dwFlags
& SI_ACCESS_SPECIFIC
)
742 SpecialPermissionsPresent
= TRUE
;
743 SpecialPermissionsMask
|= CurAccess
->mask
;
748 /* add the special permissions check item in case the specific access rights
750 if (SpecialPermissionsPresent
&&
751 LoadString(hDllInstance
,
752 IDS_SPECIAL_PERMISSIONS
,
753 szSpecialPermissions
,
754 sizeof(szSpecialPermissions
) / sizeof(szSpecialPermissions
[0])))
756 /* add the special permissions check item */
757 sp
->SpecialPermCheckIndex
= (INT
)SendMessage(sp
->hAceCheckList
,
759 (WPARAM
)SpecialPermissionsMask
,
760 (LPARAM
)szSpecialPermissions
);
761 if (sp
->SpecialPermCheckIndex
!= -1)
763 SendMessage(sp
->hAceCheckList
,
765 (WPARAM
)sp
->SpecialPermCheckIndex
,
766 CIS_ALLOWDISABLED
| CIS_DENYDISABLED
| CIS_NONE
);
772 ResizeControls(IN PSECURITY_PAGE sp
,
776 HWND hWndAllow
, hWndDeny
;
777 RECT rcControl
, rcControl2
, rcControl3
, rcWnd
;
778 INT cxWidth
, cxEdge
, btnSpacing
;
784 hWndAllow
= GetDlgItem(sp
->hWnd
,
786 hWndDeny
= GetDlgItem(sp
->hWnd
,
789 GetWindowRect(sp
->hWnd
,
792 cxEdge
= GetSystemMetrics(SM_CXEDGE
);
794 /* use the left margin of the principal list view control for all control
798 MapWindowPoints(sp
->hWndPrincipalsList
,
802 cxWidth
= Width
- (2 * pt
.x
);
804 if (sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
)
809 if ((dwp
= BeginDeferWindowPos(nControls
)))
811 /* resize the Principal list view */
812 GetWindowRect(sp
->hWndPrincipalsList
,
814 if (!(dwp
= DeferWindowPos(dwp
,
815 sp
->hWndPrincipalsList
,
820 rcControl
.bottom
- rcControl
.top
,
821 SWP_NOMOVE
| SWP_NOZORDER
)))
826 /* move the Add Principal button */
827 GetWindowRect(sp
->hBtnAdd
,
829 GetWindowRect(sp
->hBtnRemove
,
831 btnSpacing
= rcControl2
.left
- rcControl
.right
;
834 MapWindowPoints(sp
->hBtnAdd
,
838 if (!(dwp
= DeferWindowPos(dwp
,
841 pt
.x
+ cxWidth
- (rcControl2
.right
- rcControl2
.left
) -
842 (rcControl
.right
- rcControl
.left
) -
847 SWP_NOSIZE
| SWP_NOZORDER
)))
852 /* move the Delete Principal button */
855 MapWindowPoints(sp
->hBtnRemove
,
859 if (!(dwp
= DeferWindowPos(dwp
,
862 pt
.x
+ cxWidth
- (rcControl2
.right
- rcControl2
.left
) - cxEdge
,
866 SWP_NOSIZE
| SWP_NOZORDER
)))
871 /* move the Permissions For label */
872 GetWindowRect(hWndAllow
,
874 GetWindowRect(hWndDeny
,
876 GetWindowRect(sp
->hPermissionsForLabel
,
880 MapWindowPoints(sp
->hPermissionsForLabel
,
884 if (!(dwp
= DeferWindowPos(dwp
,
885 sp
->hPermissionsForLabel
,
889 cxWidth
- (rcControl2
.right
- rcControl2
.left
) -
890 (rcControl
.right
- rcControl
.left
) -
891 (2 * btnSpacing
) - cxEdge
,
892 rcControl3
.bottom
- rcControl3
.top
,
893 SWP_NOMOVE
| SWP_NOZORDER
)))
898 /* move the Allow label */
901 MapWindowPoints(hWndAllow
,
905 if (!(dwp
= DeferWindowPos(dwp
,
908 cxWidth
- (rcControl2
.right
- rcControl2
.left
) -
909 (rcControl
.right
- rcControl
.left
) -
914 SWP_NOSIZE
| SWP_NOZORDER
)))
919 /* move the Deny label */
922 MapWindowPoints(hWndDeny
,
926 if (!(dwp
= DeferWindowPos(dwp
,
929 cxWidth
- (rcControl2
.right
- rcControl2
.left
) - cxEdge
,
933 SWP_NOSIZE
| SWP_NOZORDER
)))
938 /* resize the Permissions check list box */
939 GetWindowRect(sp
->hAceCheckList
,
941 GetWindowRect(sp
->hBtnAdvanced
,
943 GetWindowRect(GetDlgItem(sp
->hWnd
,
946 if (!(dwp
= DeferWindowPos(dwp
,
952 ((sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
) ?
953 Height
- (rcControl
.top
- rcWnd
.top
) -
954 (rcControl3
.bottom
- rcControl3
.top
) - pt
.x
- btnSpacing
:
955 Height
- (rcControl
.top
- rcWnd
.top
) - pt
.x
),
956 SWP_NOMOVE
| SWP_NOZORDER
)))
961 if (sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
)
963 /* move and resize the Advanced label */
964 if (!(dwp
= DeferWindowPos(dwp
,
969 Height
- (rcControl3
.bottom
- rcControl3
.top
) - pt
.x
,
970 cxWidth
- (rcControl2
.right
- rcControl2
.left
) - cxEdge
,
971 rcControl3
.bottom
- rcControl3
.top
,
977 /* move and resize the Advanced button */
978 if (!(dwp
= DeferWindowPos(dwp
,
981 cxWidth
- (rcControl2
.right
- rcControl2
.left
) + pt
.x
,
982 Height
- (rcControl2
.bottom
- rcControl2
.top
) - pt
.x
,
985 SWP_NOSIZE
| SWP_NOZORDER
)))
991 EndDeferWindowPos(dwp
);
995 /* update the width of the principal list view column */
996 GetClientRect(sp
->hWndPrincipalsList
,
998 lvc
.mask
= LVCF_WIDTH
;
999 lvc
.cx
= rcControl
.right
;
1000 ListView_SetColumn(sp
->hWndPrincipalsList
,
1004 /* calculate the columns of the allow/deny checkboxes */
1005 SetAceCheckListColumns(sp
->hAceCheckList
,
1008 SetAceCheckListColumns(sp
->hAceCheckList
,
1014 BuildDefaultPrincipalAce(IN PSECURITY_PAGE sp
,
1017 PACCESS_ALLOWED_ACE Ace
;
1021 SidLen
= GetLengthSid(pSid
);
1022 AceSize
= sizeof(ACCESS_ALLOWED_ACE
) + (WORD
)SidLen
- sizeof(DWORD
);
1023 Ace
= HeapAlloc(GetProcessHeap(),
1028 Ace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
1029 Ace
->Header
.AceFlags
= 0; /* FIXME */
1030 Ace
->Header
.AceSize
= AceSize
;
1031 Ace
->Mask
= sp
->DefaultAccess
.mask
;
1034 (PSID
)&Ace
->SidStart
,
1037 return &Ace
->Header
;
1040 HeapFree(GetProcessHeap(),
1049 AddSelectedPrincipal(IN IDsObjectPicker
*pDsObjectPicker
,
1050 IN HWND hwndParent OPTIONAL
,
1052 IN PVOID Context OPTIONAL
)
1054 PACE_HEADER AceHeader
;
1055 PSECURITY_PAGE sp
= (PSECURITY_PAGE
)Context
;
1057 AceHeader
= BuildDefaultPrincipalAce(sp
,
1059 if (AceHeader
!= NULL
)
1061 AddPrincipalToList(sp
,
1065 HeapFree(GetProcessHeap(),
1073 static INT_PTR CALLBACK
1074 SecurityPageProc(IN HWND hwndDlg
,
1080 INT_PTR Ret
= FALSE
;
1082 sp
= (PSECURITY_PAGE
)GetWindowLongPtr(hwndDlg
,
1084 if (sp
!= NULL
|| uMsg
== WM_INITDIALOG
)
1090 NMHDR
*pnmh
= (NMHDR
*)lParam
;
1092 if (pnmh
->hwndFrom
== sp
->hWndPrincipalsList
)
1096 case LVN_ITEMCHANGED
:
1098 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
)lParam
;
1100 if ((pnmv
->uChanged
& LVIF_STATE
) &&
1101 ((pnmv
->uOldState
& (LVIS_FOCUSED
| LVIS_SELECTED
)) ||
1102 (pnmv
->uNewState
& (LVIS_FOCUSED
| LVIS_SELECTED
))))
1104 UpdateControlStates(sp
);
1110 else if (pnmh
->hwndFrom
== sp
->hAceCheckList
)
1114 case CLN_CHANGINGITEMCHECKBOX
:
1116 PNMCHANGEITEMCHECKBOX pcicb
= (PNMCHANGEITEMCHECKBOX
)lParam
;
1118 /* make sure only one of both checkboxes is only checked
1122 pcicb
->NewState
&= ~((pcicb
->CheckBox
!= CLB_DENY
) ? CIS_DENY
: CIS_ALLOW
);
1133 switch (LOWORD(wParam
))
1135 case IDC_ADD_PRINCIPAL
:
1139 hRet
= InitializeObjectPicker(sp
->ServerName
,
1141 &sp
->pDsObjectPicker
);
1142 if (SUCCEEDED(hRet
))
1144 hRet
= InvokeObjectPickerDialog(sp
->pDsObjectPicker
,
1146 AddSelectedPrincipal
,
1150 MessageBox(hwndDlg
, L
"InvokeObjectPickerDialog failed!\n", NULL
, 0);
1153 /* delete the instance */
1154 FreeObjectPicker(sp
->pDsObjectPicker
);
1156 /* reload the principal list */
1157 FillPrincipalsList(sp
);
1161 MessageBox(hwndDlg
, L
"InitializeObjectPicker failed!\n", NULL
, 0);
1166 case IDC_REMOVE_PRINCIPAL
:
1168 PPRINCIPAL_LISTITEM SelectedPrincipal
;
1170 SelectedPrincipal
= (PPRINCIPAL_LISTITEM
)ListViewGetSelectedItemData(sp
->hWndPrincipalsList
);
1171 if (SelectedPrincipal
!= NULL
)
1184 (INT
)LOWORD(lParam
),
1185 (INT
)HIWORD(lParam
));
1191 sp
= (PSECURITY_PAGE
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1198 sp
->hWndPrincipalsList
= GetDlgItem(hwndDlg
, IDC_PRINCIPALS
);
1199 sp
->hBtnAdd
= GetDlgItem(hwndDlg
, IDC_ADD_PRINCIPAL
);
1200 sp
->hBtnRemove
= GetDlgItem(hwndDlg
, IDC_REMOVE_PRINCIPAL
);
1201 sp
->hBtnAdvanced
= GetDlgItem(hwndDlg
, IDC_ADVANCED
);
1202 sp
->hAceCheckList
= GetDlgItem(hwndDlg
, IDC_ACE_CHECKLIST
);
1203 sp
->hPermissionsForLabel
= GetDlgItem(hwndDlg
, IDC_LABEL_PERMISSIONS_FOR
);
1205 sp
->SpecialPermCheckIndex
= -1;
1207 if ((sp
->ObjectInfo
.dwFlags
& SI_SERVER_IS_DC
) &&
1208 sp
->ObjectInfo
.pszServerName
!= NULL
&&
1209 sp
->ObjectInfo
.pszServerName
[0] != L
'\0')
1211 sp
->ServerName
= sp
->ObjectInfo
.pszServerName
;
1214 /* save the pointer to the structure */
1215 SetWindowLongPtr(hwndDlg
,
1219 ListView_SetExtendedListViewStyleEx(sp
->hWndPrincipalsList
,
1220 LVS_EX_FULLROWSELECT
,
1221 LVS_EX_FULLROWSELECT
);
1223 sp
->hiPrincipals
= ImageList_LoadBitmap(hDllInstance
,
1224 MAKEINTRESOURCE(IDB_USRGRPIMAGES
),
1231 /* setup the listview control */
1232 if (sp
->hiPrincipals
!= NULL
)
1234 ListView_SetImageList(sp
->hWndPrincipalsList
,
1239 GetClientRect(sp
->hWndPrincipalsList
,
1242 /* add a column to the list view */
1243 lvc
.mask
= LVCF_FMT
| LVCF_WIDTH
;
1244 lvc
.fmt
= LVCFMT_LEFT
;
1245 lvc
.cx
= rcLvClient
.right
;
1246 ListView_InsertColumn(sp
->hWndPrincipalsList
,
1250 ReloadPrincipalsList(sp
);
1252 FillPrincipalsList(sp
);
1254 ListViewSelectItem(sp
->hWndPrincipalsList
,
1257 /* calculate the columns of the allow/deny checkboxes */
1258 SetAceCheckListColumns(sp
->hAceCheckList
,
1260 GetDlgItem(hwndDlg
, IDC_LABEL_ALLOW
));
1261 SetAceCheckListColumns(sp
->hAceCheckList
,
1263 GetDlgItem(hwndDlg
, IDC_LABEL_DENY
));
1265 LoadPermissionsList(sp
,
1268 ((sp
->ObjectInfo
.dwFlags
& SI_CONTAINER
) ? SI_ACCESS_CONTAINER
: 0),
1269 &sp
->DefaultAccess
);
1271 /* hide controls in case the flags aren't present */
1272 if (sp
->ObjectInfo
.dwFlags
& SI_ADVANCED
)
1274 /* editing the permissions is least the user can do when
1275 the advanced button is showed */
1276 sp
->ObjectInfo
.dwFlags
|= SI_EDIT_PERMS
;
1280 ShowWindow(sp
->hBtnAdvanced
,
1282 ShowWindow(GetDlgItem(hwndDlg
, IDC_LABEL_ADVANCED
),
1286 /* enable quicksearch for the permissions checklist control */
1287 SendMessage(sp
->hAceCheckList
,
1288 CLM_ENABLEQUICKSEARCH
,
1292 UpdateControlStates(sp
);
1305 * CreateSecurityPage EXPORTED
1311 CreateSecurityPage(IN LPSECURITYINFO psi
)
1313 PROPSHEETPAGE psp
= {0};
1314 PSECURITY_PAGE sPage
;
1315 SI_OBJECT_INFO ObjectInfo
= {0};
1320 SetLastError(ERROR_INVALID_PARAMETER
);
1322 DPRINT("No ISecurityInformation class passed!\n");
1326 /* get the object information from the server. Zero the structure before
1327 because some applications seem to return SUCCESS but only seem to set the
1328 fields they care about. */
1329 hRet
= psi
->lpVtbl
->GetObjectInformation(psi
,
1336 DPRINT("CreateSecurityPage() failed! Failed to query the object information!\n");
1340 hRet
= CoInitialize(NULL
);
1343 DPRINT("CoInitialize failed!\n");
1347 sPage
= HeapAlloc(GetProcessHeap(),
1349 sizeof(SECURITY_PAGE
));
1352 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1354 DPRINT("Not enough memory to allocate a SECURITY_PAGE!\n");
1358 sPage
->ObjectInfo
= ObjectInfo
;
1360 psp
.dwSize
= sizeof(PROPSHEETPAGE
);
1361 psp
.dwFlags
= PSP_USECALLBACK
;
1362 psp
.hInstance
= hDllInstance
;
1363 psp
.pszTemplate
= MAKEINTRESOURCE(IDD_SECPAGE
);
1364 psp
.pfnDlgProc
= SecurityPageProc
;
1365 psp
.lParam
= (LPARAM
)sPage
;
1366 psp
.pfnCallback
= SecurityPageCallback
;
1368 if (ObjectInfo
.dwFlags
& SI_PAGE_TITLE
)
1370 psp
.pszTitle
= ObjectInfo
.pszPageTitle
;
1372 if (psp
.pszTitle
!= NULL
)
1374 psp
.dwFlags
|= PSP_USETITLE
;
1379 psp
.pszTitle
= NULL
;
1382 /* NOTE: the SECURITY_PAGE structure will be freed by the property page
1385 return CreatePropertySheetPage(&psp
);
1390 * EditSecurity EXPORTED
1396 EditSecurity(IN HWND hwndOwner
,
1397 IN LPSECURITYINFO psi
)
1400 SI_OBJECT_INFO ObjectInfo
= {0};
1401 PROPSHEETHEADER psh
;
1402 HPROPSHEETPAGE hPages
[1];
1403 LPWSTR lpCaption
= NULL
;
1408 SetLastError(ERROR_INVALID_PARAMETER
);
1410 DPRINT("No ISecurityInformation class passed!\n");
1414 /* get the object information from the server. Zero the structure before
1415 because some applications seem to return SUCCESS but only seem to set the
1416 fields they care about. */
1417 hRet
= psi
->lpVtbl
->GetObjectInformation(psi
,
1424 DPRINT("GetObjectInformation() failed!\n");
1428 /* create the page */
1429 hPages
[0] = CreateSecurityPage(psi
);
1430 if (hPages
[0] == NULL
)
1432 DPRINT("CreateSecurityPage(), couldn't create property sheet!\n");
1436 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1437 psh
.dwFlags
= PSH_DEFAULT
;
1438 psh
.hwndParent
= hwndOwner
;
1439 psh
.hInstance
= hDllInstance
;
1441 /* Set the page title to the object name, make sure the format string
1442 has "%1" NOT "%s" because it uses FormatMessage() to automatically
1443 allocate the right amount of memory. */
1444 if (LoadAndFormatString(hDllInstance
,
1447 ObjectInfo
.pszObjectName
))
1449 psh
.pszCaption
= lpCaption
;
1453 psh
.pszCaption
= ObjectInfo
.pszObjectName
;
1456 psh
.nPages
= sizeof(hPages
) / sizeof(HPROPSHEETPAGE
);
1458 psh
.phpage
= hPages
;
1460 Ret
= (PropertySheet(&psh
) != -1);
1462 if (lpCaption
!= NULL
)
1464 LocalFree((HLOCAL
)lpCaption
);
1472 DllMain(IN HINSTANCE hinstDLL
,
1474 IN LPVOID lpvReserved
)
1478 case DLL_PROCESS_ATTACH
:
1479 hDllInstance
= hinstDLL
;
1481 DisableThreadLibraryCalls(hinstDLL
);
1483 if (!RegisterCheckListControl(hinstDLL
))
1485 DPRINT("Registering the CHECKLIST_ACLUI class failed!\n");
1490 case DLL_PROCESS_DETACH
:
1491 UnregisterCheckListControl();