Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenaclui.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS Access Control List Editor 00003 * Copyright (C) 2004-2005 ReactOS Team 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 /* $Id: aclui.c 43790 2009-10-27 10:34:16Z dgorbachev $ 00020 * 00021 * PROJECT: ReactOS Access Control List Editor 00022 * FILE: lib/aclui/aclui.c 00023 * PURPOSE: Access Control List Editor 00024 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 00025 * 00026 * UPDATE HISTORY: 00027 * 08/10/2004 Created 00028 */ 00029 #include <precomp.h> 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 HINSTANCE hDllInstance; 00035 00036 #define SIDN_LOOKUPSUCCEEDED (0x101) 00037 typedef struct _SIDLOOKUPNOTIFYINFO 00038 { 00039 NMHDR nmh; 00040 PSID Sid; 00041 PSIDREQRESULT SidRequestResult; 00042 } SIDLOOKUPNOTIFYINFO, *PSIDLOOKUPNOTIFYINFO; 00043 00044 static PSID 00045 AceHeaderToSID(IN PACE_HEADER AceHeader) 00046 { 00047 PSID Sid = NULL; 00048 switch (AceHeader->AceType) 00049 { 00050 case ACCESS_ALLOWED_ACE_TYPE: 00051 Sid = (PSID)&((PACCESS_ALLOWED_ACE)AceHeader)->SidStart; 00052 break; 00053 #if 0 00054 case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 00055 Sid = (PSID)&((PACCESS_ALLOWED_CALLBACK_ACE)AceHeader)->SidStart; 00056 break; 00057 case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 00058 Sid = (PSID)&((PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader)->SidStart; 00059 break; 00060 #endif 00061 case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 00062 Sid = (PSID)&((PACCESS_ALLOWED_OBJECT_ACE)AceHeader)->SidStart; 00063 break; 00064 case ACCESS_DENIED_ACE_TYPE: 00065 Sid = (PSID)&((PACCESS_DENIED_ACE)AceHeader)->SidStart; 00066 break; 00067 #if 0 00068 case ACCESS_DENIED_CALLBACK_ACE_TYPE: 00069 Sid = (PSID)&((PACCESS_DENIED_CALLBACK_ACE)AceHeader)->SidStart; 00070 break; 00071 case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 00072 Sid = (PSID)&((PACCESS_DENIED_CALLBACK_OBJECT_ACE)AceHeader)->SidStart; 00073 break; 00074 #endif 00075 case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 00076 Sid = (PSID)&((PACCESS_DENIED_OBJECT_ACE)AceHeader)->SidStart; 00077 break; 00078 } 00079 00080 return Sid; 00081 } 00082 00083 static VOID 00084 DestroySecurityPage(IN PSECURITY_PAGE sp) 00085 { 00086 if(sp->hiPrincipals != NULL) 00087 { 00088 ImageList_Destroy(sp->hiPrincipals); 00089 } 00090 00091 DestroySidCacheMgr(sp->SidCacheMgr); 00092 00093 if (sp->OwnerSid != NULL) 00094 LocalFree((HLOCAL)sp->OwnerSid); 00095 00096 HeapFree(GetProcessHeap(), 00097 0, 00098 sp); 00099 00100 CoUninitialize(); 00101 } 00102 00103 static VOID 00104 FreePrincipalsList(IN PSECURITY_PAGE sp, 00105 IN PPRINCIPAL_LISTITEM *PrincipalsListHead) 00106 { 00107 PPRINCIPAL_LISTITEM CurItem, NextItem; 00108 PACE_ENTRY AceEntry, NextAceEntry; 00109 00110 CurItem = *PrincipalsListHead; 00111 while (CurItem != NULL) 00112 { 00113 /* Free all ACEs */ 00114 AceEntry = CurItem->ACEs; 00115 while (AceEntry != NULL) 00116 { 00117 NextAceEntry = AceEntry->Next; 00118 HeapFree(GetProcessHeap(), 00119 0, 00120 AceEntry); 00121 AceEntry = NextAceEntry; 00122 } 00123 00124 /* free the SID string if present */ 00125 if (CurItem->SidReqResult != NULL) 00126 { 00127 DereferenceSidReqResult(sp->SidCacheMgr, 00128 CurItem->SidReqResult); 00129 } 00130 00131 if (CurItem->DisplayString != NULL) 00132 { 00133 LocalFree((HLOCAL)CurItem->DisplayString); 00134 } 00135 00136 /* free the ACE list item */ 00137 NextItem = CurItem->Next; 00138 HeapFree(GetProcessHeap(), 00139 0, 00140 CurItem); 00141 CurItem = NextItem; 00142 } 00143 00144 *PrincipalsListHead = NULL; 00145 } 00146 00147 static PACE_ENTRY 00148 AddAceToPrincipal(IN PPRINCIPAL_LISTITEM Principal, 00149 IN PACE_HEADER AceHeader) 00150 { 00151 PACE_ENTRY AceEntry, *AceLink; 00152 00153 AceEntry = HeapAlloc(GetProcessHeap(), 00154 0, 00155 sizeof(ACE_ENTRY) + AceHeader->AceSize); 00156 if (AceEntry != NULL) 00157 { 00158 AceEntry->Next = NULL; 00159 00160 /* copy the ACE */ 00161 CopyMemory(AceEntry + 1, 00162 AceHeader, 00163 AceHeader->AceSize); 00164 00165 /* append it to the list */ 00166 AceLink = &Principal->ACEs; 00167 while (*AceLink != NULL) 00168 { 00169 AceLink = &(*AceLink)->Next; 00170 } 00171 *AceLink = AceEntry; 00172 } 00173 00174 return AceEntry; 00175 } 00176 00177 static PPRINCIPAL_LISTITEM 00178 FindSidInPrincipalsListAddAce(IN PPRINCIPAL_LISTITEM PrincipalsListHead, 00179 IN PSID Sid, 00180 IN PACE_HEADER AceHeader) 00181 { 00182 PPRINCIPAL_LISTITEM CurItem; 00183 00184 for (CurItem = PrincipalsListHead; 00185 CurItem != NULL; 00186 CurItem = CurItem->Next) 00187 { 00188 if (EqualSid((PSID)(CurItem + 1), 00189 Sid)) 00190 { 00191 if (AddAceToPrincipal(CurItem, 00192 AceHeader) != NULL) 00193 { 00194 return CurItem; 00195 } 00196 00197 /* unable to add the ACE to the principal */ 00198 break; 00199 } 00200 } 00201 00202 return NULL; 00203 } 00204 00205 static VOID 00206 SidLookupCompletion(IN HANDLE SidCacheMgr, 00207 IN PSID Sid, 00208 IN PSIDREQRESULT SidRequestResult, 00209 IN PVOID Context) 00210 { 00211 PSECURITY_PAGE sp = (PSECURITY_PAGE)Context; 00212 00213 /* NOTE: this routine may be executed in a different thread 00214 than the GUI! */ 00215 00216 if (SidRequestResult != NULL) 00217 { 00218 SIDLOOKUPNOTIFYINFO LookupInfo; 00219 00220 LookupInfo.nmh.hwndFrom = sp->hWnd; 00221 LookupInfo.nmh.idFrom = 0; 00222 LookupInfo.nmh.code = SIDN_LOOKUPSUCCEEDED; 00223 LookupInfo.Sid = Sid; 00224 LookupInfo.SidRequestResult = SidRequestResult; 00225 00226 /* notify the page that the sid lookup succeeded */ 00227 SendMessage(sp->hWnd, 00228 WM_NOTIFY, 00229 (WPARAM)LookupInfo.nmh.idFrom, 00230 (LPARAM)&LookupInfo.nmh); 00231 } 00232 } 00233 00234 static PPRINCIPAL_LISTITEM 00235 AddPrincipalToList(IN PSECURITY_PAGE sp, 00236 IN PSID Sid, 00237 IN PACE_HEADER AceHeader, 00238 OUT BOOL *LookupDeferred OPTIONAL) 00239 { 00240 PPRINCIPAL_LISTITEM PrincipalListItem = NULL, *PrincipalLink; 00241 PACE_ENTRY AceEntry; 00242 BOOL Deferred = FALSE; 00243 00244 if (!FindSidInPrincipalsListAddAce(sp->PrincipalsListHead, 00245 Sid, 00246 AceHeader)) 00247 { 00248 DWORD SidLength; 00249 00250 PrincipalLink = &sp->PrincipalsListHead; 00251 while (*PrincipalLink != NULL) 00252 { 00253 PrincipalLink = &(*PrincipalLink)->Next; 00254 } 00255 00256 SidLength = GetLengthSid(Sid); 00257 00258 /* allocate the principal */ 00259 PrincipalListItem = HeapAlloc(GetProcessHeap(), 00260 0, 00261 sizeof(PRINCIPAL_LISTITEM) + SidLength); 00262 if (PrincipalListItem != NULL) 00263 { 00264 PrincipalListItem->DisplayString = NULL; 00265 PrincipalListItem->SidReqResult = NULL; 00266 00267 CopySid(SidLength, 00268 (PSID)(PrincipalListItem + 1), 00269 Sid); 00270 00271 /* allocate some memory for the ACE and copy it */ 00272 AceEntry = HeapAlloc(GetProcessHeap(), 00273 0, 00274 sizeof(ACE_ENTRY) + AceHeader->AceSize); 00275 if (AceEntry != NULL) 00276 { 00277 AceEntry->Next = NULL; 00278 CopyMemory(AceEntry + 1, 00279 AceHeader, 00280 AceHeader->AceSize); 00281 00282 /* add the ACE to the list */ 00283 PrincipalListItem->ACEs = AceEntry; 00284 00285 PrincipalListItem->Next = NULL; 00286 00287 /* append item to the principals list */ 00288 *PrincipalLink = PrincipalListItem; 00289 00290 /* lookup the SID now */ 00291 Deferred = !LookupSidCache(sp->SidCacheMgr, 00292 Sid, 00293 SidLookupCompletion, 00294 sp); 00295 } 00296 else 00297 { 00298 HeapFree(GetProcessHeap(), 00299 0, 00300 PrincipalListItem); 00301 PrincipalListItem = NULL; 00302 } 00303 } 00304 } 00305 00306 if (PrincipalListItem != NULL && LookupDeferred != NULL) 00307 { 00308 *LookupDeferred = Deferred; 00309 } 00310 00311 return PrincipalListItem; 00312 } 00313 00314 static LPWSTR 00315 GetDisplayStringFromSidRequestResult(IN PSIDREQRESULT SidReqResult) 00316 { 00317 LPWSTR lpDisplayString = NULL; 00318 00319 if (SidReqResult->SidNameUse == SidTypeUser || 00320 SidReqResult->SidNameUse == SidTypeGroup) 00321 { 00322 LoadAndFormatString(hDllInstance, 00323 IDS_USERDOMAINFORMAT, 00324 &lpDisplayString, 00325 SidReqResult->AccountName, 00326 SidReqResult->DomainName, 00327 SidReqResult->AccountName); 00328 } 00329 else 00330 { 00331 LoadAndFormatString(hDllInstance, 00332 IDS_USERFORMAT, 00333 &lpDisplayString, 00334 SidReqResult->AccountName); 00335 } 00336 00337 return lpDisplayString; 00338 } 00339 00340 static LPWSTR 00341 GetPrincipalDisplayString(IN PPRINCIPAL_LISTITEM PrincipalListItem) 00342 { 00343 LPWSTR lpDisplayString = NULL; 00344 00345 if (PrincipalListItem->SidReqResult != NULL) 00346 { 00347 lpDisplayString = GetDisplayStringFromSidRequestResult(PrincipalListItem->SidReqResult); 00348 } 00349 else 00350 { 00351 ConvertSidToStringSidW((PSID)(PrincipalListItem + 1), 00352 &lpDisplayString); 00353 } 00354 00355 return lpDisplayString; 00356 } 00357 00358 static LPWSTR 00359 GetPrincipalAccountNameString(IN PPRINCIPAL_LISTITEM PrincipalListItem) 00360 { 00361 LPWSTR lpDisplayString = NULL; 00362 00363 if (PrincipalListItem->SidReqResult != NULL) 00364 { 00365 LoadAndFormatString(hDllInstance, 00366 IDS_USERFORMAT, 00367 &lpDisplayString, 00368 PrincipalListItem->SidReqResult->AccountName); 00369 } 00370 else 00371 { 00372 ConvertSidToStringSid((PSID)(PrincipalListItem + 1), 00373 &lpDisplayString); 00374 } 00375 00376 return lpDisplayString; 00377 } 00378 00379 static VOID 00380 CreatePrincipalListItem(OUT LVITEM *li, 00381 IN PSECURITY_PAGE sp, 00382 IN PPRINCIPAL_LISTITEM PrincipalListItem, 00383 IN INT Index, 00384 IN BOOL Selected) 00385 { 00386 INT ImageIndex = 2; 00387 00388 if (PrincipalListItem->SidReqResult != NULL) 00389 { 00390 switch (PrincipalListItem->SidReqResult->SidNameUse) 00391 { 00392 case SidTypeUser: 00393 ImageIndex = 0; 00394 break; 00395 case SidTypeWellKnownGroup: 00396 case SidTypeGroup: 00397 ImageIndex = 1; 00398 break; 00399 default: 00400 break; 00401 } 00402 } 00403 00404 li->mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_TEXT; 00405 li->iItem = Index; 00406 li->iSubItem = 0; 00407 li->state = (Selected ? LVIS_SELECTED : 0); 00408 li->stateMask = LVIS_SELECTED; 00409 li->pszText = PrincipalListItem->DisplayString; 00410 li->iImage = ImageIndex; 00411 li->lParam = (LPARAM)PrincipalListItem; 00412 } 00413 00414 static INT 00415 AddPrincipalListEntry(IN PSECURITY_PAGE sp, 00416 IN PPRINCIPAL_LISTITEM PrincipalListItem, 00417 IN INT Index, 00418 IN BOOL Selected) 00419 { 00420 LVITEM li; 00421 INT Ret; 00422 00423 if (PrincipalListItem->DisplayString != NULL) 00424 { 00425 LocalFree((HLOCAL)PrincipalListItem->DisplayString); 00426 } 00427 PrincipalListItem->DisplayString = GetPrincipalDisplayString(PrincipalListItem); 00428 00429 CreatePrincipalListItem(&li, 00430 sp, 00431 PrincipalListItem, 00432 Index, 00433 Selected); 00434 00435 Ret = ListView_InsertItem(sp->hWndPrincipalsList, 00436 &li); 00437 00438 return Ret; 00439 } 00440 00441 static int CALLBACK 00442 PrincipalCompare(IN LPARAM lParam1, 00443 IN LPARAM lParam2, 00444 IN LPARAM lParamSort) 00445 { 00446 PPRINCIPAL_LISTITEM Item1 = (PPRINCIPAL_LISTITEM)lParam1; 00447 PPRINCIPAL_LISTITEM Item2 = (PPRINCIPAL_LISTITEM)lParam2; 00448 00449 if (Item1->DisplayString != NULL && Item2->DisplayString != NULL) 00450 { 00451 return wcscmp(Item1->DisplayString, 00452 Item2->DisplayString); 00453 } 00454 00455 return 0; 00456 } 00457 00458 static VOID 00459 UpdatePrincipalListItem(IN PSECURITY_PAGE sp, 00460 IN INT PrincipalIndex, 00461 IN PPRINCIPAL_LISTITEM PrincipalListItem, 00462 IN PSIDREQRESULT SidReqResult) 00463 { 00464 LVITEM li; 00465 00466 /* replace the request result structure */ 00467 if (PrincipalListItem->SidReqResult != NULL) 00468 { 00469 DereferenceSidReqResult(sp->SidCacheMgr, 00470 PrincipalListItem->SidReqResult); 00471 } 00472 00473 ReferenceSidReqResult(sp->SidCacheMgr, 00474 SidReqResult); 00475 PrincipalListItem->SidReqResult = SidReqResult; 00476 00477 /* update the display string */ 00478 if (PrincipalListItem->DisplayString != NULL) 00479 { 00480 LocalFree((HLOCAL)PrincipalListItem->DisplayString); 00481 } 00482 PrincipalListItem->DisplayString = GetPrincipalDisplayString(PrincipalListItem); 00483 00484 /* update the list item */ 00485 CreatePrincipalListItem(&li, 00486 sp, 00487 PrincipalListItem, 00488 PrincipalIndex, 00489 FALSE); 00490 00491 /* don't change the list item state */ 00492 li.mask &= ~(LVIF_STATE | LVIF_PARAM); 00493 00494 (void)ListView_SetItem(sp->hWndPrincipalsList, 00495 &li); 00496 00497 /* sort the principals list view again */ 00498 (void)ListView_SortItems(sp->hWndPrincipalsList, 00499 PrincipalCompare, 00500 (LPARAM)sp); 00501 } 00502 00503 static VOID 00504 ReloadPrincipalsList(IN PSECURITY_PAGE sp) 00505 { 00506 PSECURITY_DESCRIPTOR SecurityDescriptor; 00507 BOOL DaclPresent, DaclDefaulted, OwnerDefaulted; 00508 PACL Dacl = NULL; 00509 PSID OwnerSid = NULL; 00510 LPTSTR OwnerSidString; 00511 DWORD SidLen; 00512 HRESULT hRet; 00513 00514 /* delete the cached ACL */ 00515 FreePrincipalsList(sp, 00516 &sp->PrincipalsListHead); 00517 00518 /* query the ACL */ 00519 hRet = sp->psi->lpVtbl->GetSecurity(sp->psi, 00520 DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION, 00521 &SecurityDescriptor, 00522 FALSE); 00523 if (SUCCEEDED(hRet) && SecurityDescriptor != NULL) 00524 { 00525 if (GetSecurityDescriptorOwner(SecurityDescriptor, 00526 &OwnerSid, 00527 &OwnerDefaulted)) 00528 { 00529 sp->OwnerDefaulted = OwnerDefaulted; 00530 if (sp->OwnerSid != NULL) 00531 { 00532 LocalFree((HLOCAL)sp->OwnerSid); 00533 sp->OwnerSid = NULL; 00534 } 00535 00536 SidLen = GetLengthSid(OwnerSid); 00537 if (SidLen == 0) 00538 goto ClearOwner; 00539 00540 sp->OwnerSid = (PSID)LocalAlloc(LMEM_FIXED, 00541 SidLen); 00542 if (sp->OwnerSid != NULL) 00543 { 00544 if (CopySid(SidLen, 00545 sp->OwnerSid, 00546 OwnerSid)) 00547 { 00548 /* Lookup the SID now */ 00549 if (!LookupSidCache(sp->SidCacheMgr, 00550 sp->OwnerSid, 00551 SidLookupCompletion, 00552 sp)) 00553 { 00554 /* Lookup was deferred */ 00555 if (ConvertSidToStringSid(sp->OwnerSid, 00556 &OwnerSidString)) 00557 { 00558 SetDlgItemText(sp->hWnd, 00559 IDC_OWNER, 00560 OwnerSidString); 00561 LocalFree((HLOCAL)OwnerSidString); 00562 } 00563 else 00564 goto ClearOwner; 00565 } 00566 } 00567 else 00568 goto ClearOwner; 00569 } 00570 else 00571 goto ClearOwner; 00572 } 00573 else 00574 { 00575 ClearOwner: 00576 SetDlgItemText(sp->hWnd, 00577 IDC_OWNER, 00578 NULL); 00579 } 00580 00581 if (GetSecurityDescriptorDacl(SecurityDescriptor, 00582 &DaclPresent, 00583 &Dacl, 00584 &DaclDefaulted) && 00585 DaclPresent && Dacl != NULL) 00586 { 00587 PSID Sid; 00588 PACE_HEADER AceHeader; 00589 ULONG AceIndex; 00590 00591 for (AceIndex = 0; 00592 AceIndex < Dacl->AceCount; 00593 AceIndex++) 00594 { 00595 if (GetAce(Dacl, 00596 AceIndex, 00597 (LPVOID*)&AceHeader) && 00598 AceHeader != NULL) 00599 { 00600 BOOL LookupDeferred; 00601 PPRINCIPAL_LISTITEM PrincipalListItem; 00602 00603 Sid = AceHeaderToSID(AceHeader); 00604 00605 PrincipalListItem = AddPrincipalToList(sp, 00606 Sid, 00607 AceHeader, 00608 &LookupDeferred); 00609 00610 if (PrincipalListItem != NULL && LookupDeferred) 00611 { 00612 AddPrincipalListEntry(sp, 00613 PrincipalListItem, 00614 -1, 00615 FALSE); 00616 } 00617 } 00618 } 00619 } 00620 LocalFree((HLOCAL)SecurityDescriptor); 00621 } 00622 } 00623 00624 static VOID 00625 UpdateControlStates(IN PSECURITY_PAGE sp) 00626 { 00627 PPRINCIPAL_LISTITEM Selected = (PPRINCIPAL_LISTITEM)ListViewGetSelectedItemData(sp->hWndPrincipalsList); 00628 00629 EnableWindow(sp->hBtnRemove, 00630 Selected != NULL); 00631 EnableWindow(sp->hAceCheckList, 00632 Selected != NULL); 00633 00634 if (Selected != NULL) 00635 { 00636 LPWSTR szLabel; 00637 LPWSTR szDisplayString; 00638 00639 szDisplayString = GetPrincipalAccountNameString(Selected); 00640 if (LoadAndFormatString(hDllInstance, 00641 IDS_PERMISSIONS_FOR, 00642 &szLabel, 00643 szDisplayString)) 00644 { 00645 SetWindowText(sp->hPermissionsForLabel, 00646 szLabel); 00647 00648 LocalFree((HLOCAL)szLabel); 00649 } 00650 00651 LocalFree((HLOCAL)szDisplayString); 00652 00653 /* FIXME - update the checkboxes */ 00654 } 00655 else 00656 { 00657 WCHAR szPermissions[255]; 00658 00659 if (LoadString(hDllInstance, 00660 IDS_PERMISSIONS, 00661 szPermissions, 00662 sizeof(szPermissions) / sizeof(szPermissions[0]))) 00663 { 00664 SetWindowText(sp->hPermissionsForLabel, 00665 szPermissions); 00666 } 00667 00668 SendMessage(sp->hAceCheckList, 00669 CLM_CLEARCHECKBOXES, 00670 0, 00671 0); 00672 } 00673 } 00674 00675 static void 00676 UpdatePrincipalInfo(IN PSECURITY_PAGE sp, 00677 IN PSIDLOOKUPNOTIFYINFO LookupInfo) 00678 { 00679 PPRINCIPAL_LISTITEM CurItem; 00680 LPWSTR DisplayName; 00681 00682 if (sp->OwnerSid != NULL && 00683 EqualSid(sp->OwnerSid, 00684 LookupInfo->Sid)) 00685 { 00686 if (LookupInfo->SidRequestResult != NULL) 00687 DisplayName = GetDisplayStringFromSidRequestResult(LookupInfo->SidRequestResult); 00688 else if (!ConvertSidToStringSidW(LookupInfo->Sid, 00689 &DisplayName)) 00690 { 00691 DisplayName = NULL; 00692 } 00693 00694 if (DisplayName != NULL) 00695 { 00696 SetDlgItemTextW(sp->hWnd, 00697 IDC_OWNER, 00698 DisplayName); 00699 00700 LocalFree((HLOCAL)DisplayName); 00701 } 00702 } 00703 00704 for (CurItem = sp->PrincipalsListHead; 00705 CurItem != NULL; 00706 CurItem = CurItem->Next) 00707 { 00708 if (EqualSid((PSID)(CurItem + 1), 00709 LookupInfo->Sid)) 00710 { 00711 INT PrincipalIndex; 00712 LVFINDINFO lvfi; 00713 00714 /* find the principal in the list */ 00715 lvfi.flags = LVFI_PARAM; 00716 lvfi.lParam = (LPARAM)CurItem; 00717 PrincipalIndex = ListView_FindItem(sp->hWndPrincipalsList, 00718 -1, 00719 &lvfi); 00720 00721 if (PrincipalIndex != -1) 00722 { 00723 /* update the principal in the list view control */ 00724 UpdatePrincipalListItem(sp, 00725 PrincipalIndex, 00726 CurItem, 00727 LookupInfo->SidRequestResult); 00728 00729 if (ListViewGetSelectedItemData(sp->hWndPrincipalsList) == (LPARAM)CurItem) 00730 { 00731 UpdateControlStates(sp); 00732 } 00733 } 00734 else 00735 { 00736 AddPrincipalListEntry(sp, 00737 CurItem, 00738 -1, 00739 FALSE); 00740 } 00741 break; 00742 } 00743 } 00744 } 00745 00746 static UINT CALLBACK 00747 SecurityPageCallback(IN HWND hwnd, 00748 IN UINT uMsg, 00749 IN LPPROPSHEETPAGE ppsp) 00750 { 00751 PSECURITY_PAGE sp = (PSECURITY_PAGE)ppsp->lParam; 00752 00753 switch (uMsg) 00754 { 00755 case PSPCB_CREATE: 00756 { 00757 return TRUE; 00758 } 00759 case PSPCB_RELEASE: 00760 { 00761 DestroySecurityPage(sp); 00762 return FALSE; 00763 } 00764 } 00765 00766 return FALSE; 00767 } 00768 00769 static VOID 00770 SetAceCheckListColumns(IN HWND hAceCheckList, 00771 IN UINT Button, 00772 IN HWND hLabel) 00773 { 00774 POINT pt; 00775 RECT rcLabel; 00776 00777 GetWindowRect(hLabel, 00778 &rcLabel); 00779 pt.y = 0; 00780 pt.x = (rcLabel.right - rcLabel.left) / 2; 00781 MapWindowPoints(hLabel, 00782 hAceCheckList, 00783 &pt, 00784 1); 00785 00786 SendMessage(hAceCheckList, 00787 CLM_SETCHECKBOXCOLUMN, 00788 Button, 00789 pt.x); 00790 } 00791 00792 static VOID 00793 LoadPermissionsList(IN PSECURITY_PAGE sp, 00794 IN GUID *GuidObjectType, 00795 IN DWORD dwFlags, 00796 OUT SI_ACCESS *DefaultAccess) 00797 { 00798 HRESULT hRet; 00799 PSI_ACCESS AccessList; 00800 ULONG nAccessList, DefaultAccessIndex; 00801 WCHAR szSpecialPermissions[255]; 00802 BOOLEAN SpecialPermissionsPresent = FALSE; 00803 ACCESS_MASK SpecialPermissionsMask = 0; 00804 00805 /* clear the permissions list */ 00806 00807 SendMessage(sp->hAceCheckList, 00808 CLM_CLEAR, 00809 0, 00810 0); 00811 00812 /* query the access rights from the server */ 00813 hRet = sp->psi->lpVtbl->GetAccessRights(sp->psi, 00814 GuidObjectType, 00815 dwFlags, /* FIXME */ 00816 &AccessList, 00817 &nAccessList, 00818 &DefaultAccessIndex); 00819 if (SUCCEEDED(hRet) && nAccessList != 0) 00820 { 00821 LPCWSTR NameStr; 00822 PSI_ACCESS CurAccess, LastAccess; 00823 WCHAR NameBuffer[MAX_PATH]; 00824 00825 /* save the default access rights to be used when adding ACEs later */ 00826 if (DefaultAccess != NULL) 00827 { 00828 *DefaultAccess = AccessList[DefaultAccessIndex]; 00829 } 00830 00831 LastAccess = AccessList + nAccessList; 00832 for (CurAccess = &AccessList[0]; 00833 CurAccess != LastAccess; 00834 CurAccess++) 00835 { 00836 if (CurAccess->dwFlags & dwFlags) 00837 { 00838 /* get the permission name, load it from a string table if necessary */ 00839 if (IS_INTRESOURCE(CurAccess->pszName)) 00840 { 00841 if (!LoadString(sp->ObjectInfo.hInstance, 00842 (UINT)((ULONG_PTR)CurAccess->pszName), 00843 NameBuffer, 00844 sizeof(NameBuffer) / sizeof(NameBuffer[0]))) 00845 { 00846 LoadString(hDllInstance, 00847 IDS_UNKNOWN, 00848 NameBuffer, 00849 sizeof(NameBuffer) / sizeof(NameBuffer[0])); 00850 } 00851 NameStr = NameBuffer; 00852 } 00853 else 00854 { 00855 NameStr = CurAccess->pszName; 00856 } 00857 00858 SendMessage(sp->hAceCheckList, 00859 CLM_ADDITEM, 00860 (WPARAM)CurAccess->mask, 00861 (LPARAM)NameStr); 00862 } 00863 else if (CurAccess->dwFlags & SI_ACCESS_SPECIFIC) 00864 { 00865 SpecialPermissionsPresent = TRUE; 00866 SpecialPermissionsMask |= CurAccess->mask; 00867 } 00868 } 00869 } 00870 00871 /* add the special permissions check item in case the specific access rights 00872 aren't displayed */ 00873 if (SpecialPermissionsPresent && 00874 LoadString(hDllInstance, 00875 IDS_SPECIAL_PERMISSIONS, 00876 szSpecialPermissions, 00877 sizeof(szSpecialPermissions) / sizeof(szSpecialPermissions[0]))) 00878 { 00879 /* add the special permissions check item */ 00880 sp->SpecialPermCheckIndex = (INT)SendMessage(sp->hAceCheckList, 00881 CLM_ADDITEM, 00882 (WPARAM)SpecialPermissionsMask, 00883 (LPARAM)szSpecialPermissions); 00884 if (sp->SpecialPermCheckIndex != -1) 00885 { 00886 SendMessage(sp->hAceCheckList, 00887 CLM_SETITEMSTATE, 00888 (WPARAM)sp->SpecialPermCheckIndex, 00889 CIS_ALLOWDISABLED | CIS_DENYDISABLED | CIS_NONE); 00890 } 00891 } 00892 } 00893 00894 static VOID 00895 ResizeControls(IN PSECURITY_PAGE sp, 00896 IN INT Width, 00897 IN INT Height) 00898 { 00899 HWND hWndAllow, hWndDeny, hWndOwnerEdit; 00900 RECT rcControl, rcControl2, rcControl3, rcWnd; 00901 INT cxWidth, cxEdge, btnSpacing; 00902 POINT pt, pt2; 00903 HDWP dwp; 00904 INT nControls = 8; 00905 LVCOLUMN lvc; 00906 00907 hWndAllow = GetDlgItem(sp->hWnd, 00908 IDC_LABEL_ALLOW); 00909 hWndDeny = GetDlgItem(sp->hWnd, 00910 IDC_LABEL_DENY); 00911 00912 GetWindowRect(sp->hWnd, 00913 &rcWnd); 00914 00915 cxEdge = GetSystemMetrics(SM_CXEDGE); 00916 00917 /* use the left margin of the principal list view control for all control 00918 margins */ 00919 pt.x = 0; 00920 pt.y = 0; 00921 MapWindowPoints(sp->hWndPrincipalsList, 00922 sp->hWnd, 00923 &pt, 00924 1); 00925 cxWidth = Width - (2 * pt.x); 00926 00927 if (sp->ObjectInfo.dwFlags & SI_ADVANCED) 00928 { 00929 nControls += 2; 00930 } 00931 00932 if ((dwp = BeginDeferWindowPos(nControls))) 00933 { 00934 /* resize the owner edit field */ 00935 hWndOwnerEdit = GetDlgItem(sp->hWnd, 00936 IDC_OWNER); 00937 GetWindowRect(hWndOwnerEdit, 00938 &rcControl); 00939 pt2.x = 0; 00940 pt2.y = 0; 00941 MapWindowPoints(hWndOwnerEdit, 00942 sp->hWnd, 00943 &pt2, 00944 1); 00945 if (!(dwp = DeferWindowPos(dwp, 00946 hWndOwnerEdit, 00947 NULL, 00948 0, 00949 0, 00950 Width - pt.x - pt2.x, 00951 rcControl.bottom - rcControl.top, 00952 SWP_NOMOVE | SWP_NOZORDER))) 00953 { 00954 goto EndDeferWnds; 00955 } 00956 00957 /* resize the Principal list view */ 00958 GetWindowRect(sp->hWndPrincipalsList, 00959 &rcControl); 00960 if (!(dwp = DeferWindowPos(dwp, 00961 sp->hWndPrincipalsList, 00962 NULL, 00963 0, 00964 0, 00965 cxWidth, 00966 rcControl.bottom - rcControl.top, 00967 SWP_NOMOVE | SWP_NOZORDER))) 00968 { 00969 goto EndDeferWnds; 00970 } 00971 00972 /* move the Add Principal button */ 00973 GetWindowRect(sp->hBtnAdd, 00974 &rcControl); 00975 GetWindowRect(sp->hBtnRemove, 00976 &rcControl2); 00977 btnSpacing = rcControl2.left - rcControl.right; 00978 pt2.x = 0; 00979 pt2.y = 0; 00980 MapWindowPoints(sp->hBtnAdd, 00981 sp->hWnd, 00982 &pt2, 00983 1); 00984 if (!(dwp = DeferWindowPos(dwp, 00985 sp->hBtnAdd, 00986 NULL, 00987 pt.x + cxWidth - (rcControl2.right - rcControl2.left) - 00988 (rcControl.right - rcControl.left) - 00989 btnSpacing - cxEdge, 00990 pt2.y, 00991 0, 00992 0, 00993 SWP_NOSIZE | SWP_NOZORDER))) 00994 { 00995 goto EndDeferWnds; 00996 } 00997 00998 /* move the Delete Principal button */ 00999 pt2.x = 0; 01000 pt2.y = 0; 01001 MapWindowPoints(sp->hBtnRemove, 01002 sp->hWnd, 01003 &pt2, 01004 1); 01005 if (!(dwp = DeferWindowPos(dwp, 01006 sp->hBtnRemove, 01007 NULL, 01008 pt.x + cxWidth - (rcControl2.right - rcControl2.left) - cxEdge, 01009 pt2.y, 01010 0, 01011 0, 01012 SWP_NOSIZE | SWP_NOZORDER))) 01013 { 01014 goto EndDeferWnds; 01015 } 01016 01017 /* move the Permissions For label */ 01018 GetWindowRect(hWndAllow, 01019 &rcControl); 01020 GetWindowRect(hWndDeny, 01021 &rcControl2); 01022 GetWindowRect(sp->hPermissionsForLabel, 01023 &rcControl3); 01024 pt2.x = 0; 01025 pt2.y = 0; 01026 MapWindowPoints(sp->hPermissionsForLabel, 01027 sp->hWnd, 01028 &pt2, 01029 1); 01030 if (!(dwp = DeferWindowPos(dwp, 01031 sp->hPermissionsForLabel, 01032 NULL, 01033 0, 01034 0, 01035 cxWidth - (rcControl2.right - rcControl2.left) - 01036 (rcControl.right - rcControl.left) - 01037 (2 * btnSpacing) - cxEdge, 01038 rcControl3.bottom - rcControl3.top, 01039 SWP_NOMOVE | SWP_NOZORDER))) 01040 { 01041 goto EndDeferWnds; 01042 } 01043 01044 /* move the Allow label */ 01045 pt2.x = 0; 01046 pt2.y = 0; 01047 MapWindowPoints(hWndAllow, 01048 sp->hWnd, 01049 &pt2, 01050 1); 01051 if (!(dwp = DeferWindowPos(dwp, 01052 hWndAllow, 01053 NULL, 01054 cxWidth - (rcControl2.right - rcControl2.left) - 01055 (rcControl.right - rcControl.left) - 01056 btnSpacing - cxEdge, 01057 pt2.y, 01058 0, 01059 0, 01060 SWP_NOSIZE | SWP_NOZORDER))) 01061 { 01062 goto EndDeferWnds; 01063 } 01064 01065 /* move the Deny label */ 01066 pt2.x = 0; 01067 pt2.y = 0; 01068 MapWindowPoints(hWndDeny, 01069 sp->hWnd, 01070 &pt2, 01071 1); 01072 if (!(dwp = DeferWindowPos(dwp, 01073 hWndDeny, 01074 NULL, 01075 cxWidth - (rcControl2.right - rcControl2.left) - cxEdge, 01076 pt2.y, 01077 0, 01078 0, 01079 SWP_NOSIZE | SWP_NOZORDER))) 01080 { 01081 goto EndDeferWnds; 01082 } 01083 01084 /* resize the Permissions check list box */ 01085 GetWindowRect(sp->hAceCheckList, 01086 &rcControl); 01087 GetWindowRect(sp->hBtnAdvanced, 01088 &rcControl2); 01089 GetWindowRect(GetDlgItem(sp->hWnd, 01090 IDC_LABEL_ADVANCED), 01091 &rcControl3); 01092 if (!(dwp = DeferWindowPos(dwp, 01093 sp->hAceCheckList, 01094 NULL, 01095 0, 01096 0, 01097 cxWidth, 01098 ((sp->ObjectInfo.dwFlags & SI_ADVANCED) ? 01099 Height - (rcControl.top - rcWnd.top) - 01100 (rcControl3.bottom - rcControl3.top) - pt.x - btnSpacing : 01101 Height - (rcControl.top - rcWnd.top) - pt.x), 01102 SWP_NOMOVE | SWP_NOZORDER))) 01103 { 01104 goto EndDeferWnds; 01105 } 01106 01107 if (sp->ObjectInfo.dwFlags & SI_ADVANCED) 01108 { 01109 /* move and resize the Advanced label */ 01110 if (!(dwp = DeferWindowPos(dwp, 01111 GetDlgItem(sp->hWnd, 01112 IDC_LABEL_ADVANCED), 01113 NULL, 01114 pt.x, 01115 Height - (rcControl3.bottom - rcControl3.top) - pt.x, 01116 cxWidth - (rcControl2.right - rcControl2.left) - cxEdge, 01117 rcControl3.bottom - rcControl3.top, 01118 SWP_NOZORDER))) 01119 { 01120 goto EndDeferWnds; 01121 } 01122 01123 /* move and resize the Advanced button */ 01124 if (!(dwp = DeferWindowPos(dwp, 01125 sp->hBtnAdvanced, 01126 NULL, 01127 cxWidth - (rcControl2.right - rcControl2.left) + pt.x, 01128 Height - (rcControl2.bottom - rcControl2.top) - pt.x, 01129 0, 01130 0, 01131 SWP_NOSIZE | SWP_NOZORDER))) 01132 { 01133 goto EndDeferWnds; 01134 } 01135 } 01136 01137 EndDeferWindowPos(dwp); 01138 } 01139 01140 EndDeferWnds: 01141 /* update the width of the principal list view column */ 01142 GetClientRect(sp->hWndPrincipalsList, 01143 &rcControl); 01144 lvc.mask = LVCF_WIDTH; 01145 lvc.cx = rcControl.right; 01146 (void)ListView_SetColumn(sp->hWndPrincipalsList, 01147 0, 01148 &lvc); 01149 01150 /* calculate the columns of the allow/deny checkboxes */ 01151 SetAceCheckListColumns(sp->hAceCheckList, 01152 CLB_ALLOW, 01153 hWndAllow); 01154 SetAceCheckListColumns(sp->hAceCheckList, 01155 CLB_DENY, 01156 hWndDeny); 01157 } 01158 01159 static PACE_HEADER 01160 BuildDefaultPrincipalAce(IN PSECURITY_PAGE sp, 01161 IN PSID pSid) 01162 { 01163 PACCESS_ALLOWED_ACE Ace; 01164 DWORD SidLen; 01165 WORD AceSize; 01166 01167 SidLen = GetLengthSid(pSid); 01168 AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, 01169 SidStart) + (WORD)SidLen; 01170 Ace = HeapAlloc(GetProcessHeap(), 01171 0, 01172 AceSize); 01173 if (Ace != NULL) 01174 { 01175 Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; 01176 Ace->Header.AceFlags = 0; /* FIXME */ 01177 Ace->Header.AceSize = AceSize; 01178 Ace->Mask = sp->DefaultAccess.mask; 01179 01180 if (CopySid(SidLen, 01181 (PSID)&Ace->SidStart, 01182 pSid)) 01183 { 01184 return &Ace->Header; 01185 } 01186 01187 HeapFree(GetProcessHeap(), 01188 0, 01189 Ace); 01190 } 01191 01192 return NULL; 01193 } 01194 01195 static BOOL 01196 AddSelectedPrincipal(IN IDsObjectPicker *pDsObjectPicker, 01197 IN HWND hwndParent OPTIONAL, 01198 IN PSID pSid, 01199 IN PVOID Context OPTIONAL) 01200 { 01201 PACE_HEADER AceHeader; 01202 PSECURITY_PAGE sp = (PSECURITY_PAGE)Context; 01203 01204 AceHeader = BuildDefaultPrincipalAce(sp, 01205 pSid); 01206 if (AceHeader != NULL) 01207 { 01208 PPRINCIPAL_LISTITEM PrincipalListItem; 01209 BOOL LookupDeferred; 01210 01211 PrincipalListItem = AddPrincipalToList(sp, 01212 pSid, 01213 AceHeader, 01214 &LookupDeferred); 01215 01216 if (PrincipalListItem != NULL && LookupDeferred) 01217 { 01218 AddPrincipalListEntry(sp, 01219 PrincipalListItem, 01220 -1, 01221 FALSE); 01222 } 01223 01224 HeapFree(GetProcessHeap(), 01225 0, 01226 AceHeader); 01227 } 01228 01229 return TRUE; 01230 } 01231 01232 static INT_PTR CALLBACK 01233 SecurityPageProc(IN HWND hwndDlg, 01234 IN UINT uMsg, 01235 IN WPARAM wParam, 01236 IN LPARAM lParam) 01237 { 01238 PSECURITY_PAGE sp; 01239 INT_PTR Ret = FALSE; 01240 01241 sp = (PSECURITY_PAGE)GetWindowLongPtr(hwndDlg, 01242 DWL_USER); 01243 if (sp != NULL || uMsg == WM_INITDIALOG) 01244 { 01245 switch (uMsg) 01246 { 01247 case WM_NOTIFY: 01248 { 01249 NMHDR *pnmh = (NMHDR*)lParam; 01250 01251 if (pnmh->hwndFrom == sp->hWndPrincipalsList) 01252 { 01253 switch (pnmh->code) 01254 { 01255 case LVN_ITEMCHANGED: 01256 { 01257 LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; 01258 01259 if ((pnmv->uChanged & LVIF_STATE) && 01260 ((pnmv->uOldState & (LVIS_FOCUSED | LVIS_SELECTED)) || 01261 (pnmv->uNewState & (LVIS_FOCUSED | LVIS_SELECTED)))) 01262 { 01263 UpdateControlStates(sp); 01264 } 01265 break; 01266 } 01267 } 01268 } 01269 else if (pnmh->hwndFrom == sp->hAceCheckList) 01270 { 01271 switch (pnmh->code) 01272 { 01273 case CLN_CHANGINGITEMCHECKBOX: 01274 { 01275 PNMCHANGEITEMCHECKBOX pcicb = (PNMCHANGEITEMCHECKBOX)lParam; 01276 01277 /* make sure only one of both checkboxes is only checked 01278 at the same time */ 01279 if (pcicb->Checked) 01280 { 01281 pcicb->NewState &= ~((pcicb->CheckBox != CLB_DENY) ? CIS_DENY : CIS_ALLOW); 01282 } 01283 break; 01284 } 01285 } 01286 } 01287 else if (pnmh->hwndFrom == sp->hWnd) 01288 { 01289 switch(pnmh->code) 01290 { 01291 case SIDN_LOOKUPSUCCEEDED: 01292 { 01293 PSIDLOOKUPNOTIFYINFO LookupInfo = CONTAINING_RECORD(lParam, 01294 SIDLOOKUPNOTIFYINFO, 01295 nmh); 01296 01297 /* a SID lookup succeeded, update the information */ 01298 UpdatePrincipalInfo(sp, 01299 LookupInfo); 01300 break; 01301 } 01302 } 01303 } 01304 break; 01305 } 01306 01307 case WM_COMMAND: 01308 { 01309 switch (LOWORD(wParam)) 01310 { 01311 case IDC_ADD_PRINCIPAL: 01312 { 01313 HRESULT hRet; 01314 01315 hRet = InitializeObjectPicker(sp->ServerName, 01316 &sp->ObjectInfo, 01317 &sp->pDsObjectPicker); 01318 if (SUCCEEDED(hRet)) 01319 { 01320 hRet = InvokeObjectPickerDialog(sp->pDsObjectPicker, 01321 hwndDlg, 01322 AddSelectedPrincipal, 01323 sp); 01324 if (FAILED(hRet)) 01325 { 01326 MessageBox(hwndDlg, L"InvokeObjectPickerDialog failed!\n", NULL, 0); 01327 } 01328 01329 /* delete the instance */ 01330 FreeObjectPicker(sp->pDsObjectPicker); 01331 } 01332 else 01333 { 01334 MessageBox(hwndDlg, L"InitializeObjectPicker failed!\n", NULL, 0); 01335 } 01336 break; 01337 } 01338 01339 case IDC_REMOVE_PRINCIPAL: 01340 { 01341 PPRINCIPAL_LISTITEM SelectedPrincipal; 01342 01343 SelectedPrincipal = (PPRINCIPAL_LISTITEM)ListViewGetSelectedItemData(sp->hWndPrincipalsList); 01344 if (SelectedPrincipal != NULL) 01345 { 01346 /* FIXME */ 01347 } 01348 break; 01349 } 01350 } 01351 break; 01352 } 01353 01354 case WM_SIZE: 01355 { 01356 ResizeControls(sp, 01357 (INT)LOWORD(lParam), 01358 (INT)HIWORD(lParam)); 01359 break; 01360 } 01361 01362 case WM_INITDIALOG: 01363 { 01364 sp = (PSECURITY_PAGE)((LPPROPSHEETPAGE)lParam)->lParam; 01365 if(sp != NULL) 01366 { 01367 LV_COLUMN lvc; 01368 RECT rcLvClient; 01369 01370 sp->hWnd = hwndDlg; 01371 sp->hWndPrincipalsList = GetDlgItem(hwndDlg, IDC_PRINCIPALS); 01372 sp->hBtnAdd = GetDlgItem(hwndDlg, IDC_ADD_PRINCIPAL); 01373 sp->hBtnRemove = GetDlgItem(hwndDlg, IDC_REMOVE_PRINCIPAL); 01374 sp->hBtnAdvanced = GetDlgItem(hwndDlg, IDC_ADVANCED); 01375 sp->hAceCheckList = GetDlgItem(hwndDlg, IDC_ACE_CHECKLIST); 01376 sp->hPermissionsForLabel = GetDlgItem(hwndDlg, IDC_LABEL_PERMISSIONS_FOR); 01377 01378 sp->SpecialPermCheckIndex = -1; 01379 01380 /* save the pointer to the structure */ 01381 SetWindowLongPtr(hwndDlg, 01382 DWL_USER, 01383 (DWORD_PTR)sp); 01384 01385 (void)ListView_SetExtendedListViewStyleEx(sp->hWndPrincipalsList, 01386 LVS_EX_FULLROWSELECT, 01387 LVS_EX_FULLROWSELECT); 01388 01389 sp->hiPrincipals = ImageList_Create(16, 01390 16, 01391 ILC_COLOR32 | ILC_MASK, 01392 0, 01393 3); 01394 if (sp->hiPrincipals != NULL) 01395 { 01396 HBITMAP hbmImages; 01397 01398 hbmImages = LoadBitmap(hDllInstance, 01399 MAKEINTRESOURCE(IDB_USRGRPIMAGES)); 01400 if (hbmImages != NULL) 01401 { 01402 ImageList_AddMasked(sp->hiPrincipals, 01403 hbmImages, 01404 RGB(255, 01405 0, 01406 255)); 01407 01408 DeleteObject(hbmImages); 01409 } 01410 } 01411 01412 /* setup the listview control */ 01413 if (sp->hiPrincipals != NULL) 01414 { 01415 (void)ListView_SetImageList(sp->hWndPrincipalsList, 01416 sp->hiPrincipals, 01417 LVSIL_SMALL); 01418 } 01419 01420 GetClientRect(sp->hWndPrincipalsList, 01421 &rcLvClient); 01422 01423 /* add a column to the list view */ 01424 lvc.mask = LVCF_FMT | LVCF_WIDTH; 01425 lvc.fmt = LVCFMT_LEFT; 01426 lvc.cx = rcLvClient.right; 01427 (void)ListView_InsertColumn(sp->hWndPrincipalsList, 01428 0, 01429 &lvc); 01430 01431 ReloadPrincipalsList(sp); 01432 01433 ListViewSelectItem(sp->hWndPrincipalsList, 01434 0); 01435 01436 /* calculate the columns of the allow/deny checkboxes */ 01437 SetAceCheckListColumns(sp->hAceCheckList, 01438 CLB_ALLOW, 01439 GetDlgItem(hwndDlg, IDC_LABEL_ALLOW)); 01440 SetAceCheckListColumns(sp->hAceCheckList, 01441 CLB_DENY, 01442 GetDlgItem(hwndDlg, IDC_LABEL_DENY)); 01443 01444 LoadPermissionsList(sp, 01445 NULL, 01446 SI_ACCESS_GENERAL | 01447 ((sp->ObjectInfo.dwFlags & SI_CONTAINER) ? SI_ACCESS_CONTAINER : 0), 01448 &sp->DefaultAccess); 01449 01450 /* hide controls in case the flags aren't present */ 01451 if (sp->ObjectInfo.dwFlags & SI_ADVANCED) 01452 { 01453 /* editing the permissions is least the user can do when 01454 the advanced button is showed */ 01455 sp->ObjectInfo.dwFlags |= SI_EDIT_PERMS; 01456 } 01457 else 01458 { 01459 ShowWindow(sp->hBtnAdvanced, 01460 SW_HIDE); 01461 ShowWindow(GetDlgItem(hwndDlg, IDC_LABEL_ADVANCED), 01462 SW_HIDE); 01463 } 01464 01465 /* enable quicksearch for the permissions checklist control */ 01466 SendMessage(sp->hAceCheckList, 01467 CLM_ENABLEQUICKSEARCH, 01468 TRUE, 01469 0); 01470 01471 UpdateControlStates(sp); 01472 } 01473 01474 Ret = TRUE; 01475 break; 01476 } 01477 } 01478 } 01479 return Ret; 01480 } 01481 01482 01483 /* 01484 * CreateSecurityPage EXPORTED 01485 * 01486 * @implemented 01487 */ 01488 HPROPSHEETPAGE 01489 WINAPI 01490 CreateSecurityPage(IN LPSECURITYINFO psi) 01491 { 01492 PROPSHEETPAGE psp = {0}; 01493 PSECURITY_PAGE sPage; 01494 SI_OBJECT_INFO ObjectInfo = {0}; 01495 HANDLE SidCacheMgr; 01496 LPCWSTR SystemName = NULL; 01497 HRESULT hRet; 01498 01499 if (psi == NULL) 01500 { 01501 SetLastError(ERROR_INVALID_PARAMETER); 01502 01503 DPRINT("No ISecurityInformation class passed!\n"); 01504 return NULL; 01505 } 01506 01507 /* get the object information from the server. Zero the structure before 01508 because some applications seem to return SUCCESS but only seem to set the 01509 fields they care about. */ 01510 hRet = psi->lpVtbl->GetObjectInformation(psi, 01511 &ObjectInfo); 01512 01513 if (FAILED(hRet)) 01514 { 01515 SetLastError(hRet); 01516 01517 DPRINT("CreateSecurityPage() failed! Failed to query the object information!\n"); 01518 return NULL; 01519 } 01520 01521 if ((ObjectInfo.dwFlags & SI_SERVER_IS_DC) && 01522 ObjectInfo.pszServerName != NULL && 01523 ObjectInfo.pszServerName[0] != L'\0') 01524 { 01525 SystemName = ObjectInfo.pszServerName; 01526 } 01527 01528 SidCacheMgr = CreateSidCacheMgr(GetProcessHeap(), 01529 SystemName); 01530 if (SidCacheMgr == NULL) 01531 { 01532 DPRINT("Creating the SID cache failed!\n"); 01533 return NULL; 01534 } 01535 01536 hRet = CoInitialize(NULL); 01537 if (FAILED(hRet)) 01538 { 01539 DestroySidCacheMgr(SidCacheMgr); 01540 DPRINT("CoInitialize failed!\n"); 01541 return NULL; 01542 } 01543 01544 sPage = HeapAlloc(GetProcessHeap(), 01545 HEAP_ZERO_MEMORY, 01546 sizeof(SECURITY_PAGE)); 01547 if (sPage == NULL) 01548 { 01549 DestroySidCacheMgr(SidCacheMgr); 01550 CoUninitialize(); 01551 01552 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 01553 01554 DPRINT("Not enough memory to allocate a SECURITY_PAGE!\n"); 01555 return NULL; 01556 } 01557 01558 ZeroMemory(sPage, 01559 sizeof(*sPage)); 01560 01561 sPage->psi = psi; 01562 sPage->ObjectInfo = ObjectInfo; 01563 sPage->ServerName = SystemName; 01564 sPage->SidCacheMgr = SidCacheMgr; 01565 01566 psp.dwSize = sizeof(PROPSHEETPAGE); 01567 psp.dwFlags = PSP_USECALLBACK; 01568 psp.hInstance = hDllInstance; 01569 psp.pszTemplate = MAKEINTRESOURCE(IDD_SECPAGE); 01570 psp.pfnDlgProc = SecurityPageProc; 01571 psp.lParam = (LPARAM)sPage; 01572 psp.pfnCallback = SecurityPageCallback; 01573 01574 if (ObjectInfo.dwFlags & SI_PAGE_TITLE) 01575 { 01576 psp.pszTitle = ObjectInfo.pszPageTitle; 01577 01578 if (psp.pszTitle != NULL) 01579 { 01580 psp.dwFlags |= PSP_USETITLE; 01581 } 01582 } 01583 else 01584 { 01585 psp.pszTitle = NULL; 01586 } 01587 01588 /* NOTE: the SECURITY_PAGE structure will be freed by the property page 01589 callback! */ 01590 01591 return CreatePropertySheetPage(&psp); 01592 } 01593 01594 01595 /* 01596 * EditSecurity EXPORTED 01597 * 01598 * @implemented 01599 */ 01600 BOOL 01601 WINAPI 01602 EditSecurity(IN HWND hwndOwner, 01603 IN LPSECURITYINFO psi) 01604 { 01605 HRESULT hRet; 01606 SI_OBJECT_INFO ObjectInfo = {0}; 01607 PROPSHEETHEADER psh; 01608 HPROPSHEETPAGE hPages[1]; 01609 LPWSTR lpCaption = NULL; 01610 BOOL Ret; 01611 01612 if (psi == NULL) 01613 { 01614 SetLastError(ERROR_INVALID_PARAMETER); 01615 01616 DPRINT("No ISecurityInformation class passed!\n"); 01617 return FALSE; 01618 } 01619 01620 /* get the object information from the server. Zero the structure before 01621 because some applications seem to return SUCCESS but only seem to set the 01622 fields they care about. */ 01623 hRet = psi->lpVtbl->GetObjectInformation(psi, 01624 &ObjectInfo); 01625 01626 if (FAILED(hRet)) 01627 { 01628 SetLastError(hRet); 01629 01630 DPRINT("GetObjectInformation() failed!\n"); 01631 return FALSE; 01632 } 01633 01634 /* create the page */ 01635 hPages[0] = CreateSecurityPage(psi); 01636 if (hPages[0] == NULL) 01637 { 01638 DPRINT("CreateSecurityPage(), couldn't create property sheet!\n"); 01639 return FALSE; 01640 } 01641 01642 psh.dwSize = sizeof(PROPSHEETHEADER); 01643 psh.dwFlags = PSH_DEFAULT; 01644 psh.hwndParent = hwndOwner; 01645 psh.hInstance = hDllInstance; 01646 01647 /* Set the page title to the object name, make sure the format string 01648 has "%1" NOT "%s" because it uses FormatMessage() to automatically 01649 allocate the right amount of memory. */ 01650 if (LoadAndFormatString(hDllInstance, 01651 IDS_PSP_TITLE, 01652 &lpCaption, 01653 ObjectInfo.pszObjectName)) 01654 { 01655 psh.pszCaption = lpCaption; 01656 } 01657 else 01658 { 01659 psh.pszCaption = ObjectInfo.pszObjectName; 01660 } 01661 01662 psh.nPages = sizeof(hPages) / sizeof(HPROPSHEETPAGE); 01663 psh.nStartPage = 0; 01664 psh.phpage = hPages; 01665 01666 Ret = (PropertySheet(&psh) != -1); 01667 01668 if (lpCaption != NULL) 01669 { 01670 LocalFree((HLOCAL)lpCaption); 01671 } 01672 01673 return Ret; 01674 } 01675 01676 BOOL 01677 WINAPI 01678 DllMain(IN HINSTANCE hinstDLL, 01679 IN DWORD dwReason, 01680 IN LPVOID lpvReserved) 01681 { 01682 switch (dwReason) 01683 { 01684 case DLL_PROCESS_ATTACH: 01685 hDllInstance = hinstDLL; 01686 01687 DisableThreadLibraryCalls(hinstDLL); 01688 01689 if (!RegisterCheckListControl(hinstDLL)) 01690 { 01691 DPRINT("Registering the CHECKLIST_ACLUI class failed!\n"); 01692 return FALSE; 01693 } 01694 break; 01695 01696 case DLL_PROCESS_DETACH: 01697 UnregisterCheckListControl(hinstDLL); 01698 break; 01699 } 01700 01701 return TRUE; 01702 } 01703 Generated on Mon May 28 2012 04:22:06 for ReactOS by
1.7.6.1
|