ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

aclui.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.