xref: /reactos/dll/win32/aclui/misc.c (revision c2c66aff)
1 /*
2  * ReactOS Access Control List Editor
3  * Copyright (C) 2004-2005 ReactOS Team
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 /*
20  * PROJECT:         ReactOS Access Control List Editor
21  * FILE:            lib/aclui/misc.c
22  * PURPOSE:         Access Control List Editor
23  * PROGRAMMER:      Thomas Weidenmueller <w3seek@reactos.com>
24  *
25  * UPDATE HISTORY:
26  *      07/01/2005  Created
27  */
28 
29 #include "precomp.h"
30 
31 #define NDEBUG
32 #include <debug.h>
33 
34 static PCWSTR ObjectPickerAttributes[] =
35 {
36     L"ObjectSid",
37 };
38 
39 static INT
LengthOfStrResource(IN HINSTANCE hInst,IN UINT uID)40 LengthOfStrResource(IN HINSTANCE hInst,
41                     IN UINT uID)
42 {
43     HRSRC hrSrc;
44     HGLOBAL hRes;
45     LPWSTR lpName, lpStr;
46 
47     if (hInst == NULL)
48     {
49         return -1;
50     }
51 
52     /* There are always blocks of 16 strings */
53     lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
54 
55     /* Find the string table block */
56     if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
57         (hRes = LoadResource(hInst, hrSrc)) &&
58         (lpStr = LockResource(hRes)))
59     {
60         UINT x;
61 
62         /* Find the string we're looking for */
63         uID &= 0xF; /* position in the block, same as % 16 */
64         for (x = 0; x < uID; x++)
65         {
66             lpStr += (*lpStr) + 1;
67         }
68 
69         /* Found the string */
70         return (int)(*lpStr);
71     }
72     return -1;
73 }
74 
75 static INT
AllocAndLoadString(OUT LPWSTR * lpTarget,IN HINSTANCE hInst,IN UINT uID)76 AllocAndLoadString(OUT LPWSTR *lpTarget,
77                    IN HINSTANCE hInst,
78                    IN UINT uID)
79 {
80     INT ln;
81 
82     ln = LengthOfStrResource(hInst,
83                              uID);
84     if (ln++ > 0)
85     {
86         (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
87                                          ln * sizeof(WCHAR));
88         if ((*lpTarget) != NULL)
89         {
90             INT Ret;
91             if (!(Ret = LoadStringW(hInst, uID, *lpTarget, ln)))
92             {
93                 LocalFree((HLOCAL)(*lpTarget));
94             }
95             return Ret;
96         }
97     }
98     return 0;
99 }
100 
101 DWORD
LoadAndFormatString(IN HINSTANCE hInstance,IN UINT uID,OUT LPWSTR * lpTarget,...)102 LoadAndFormatString(IN HINSTANCE hInstance,
103                     IN UINT uID,
104                     OUT LPWSTR *lpTarget,
105                     ...)
106 {
107     DWORD Ret = 0;
108     LPWSTR lpFormat;
109     va_list lArgs;
110 
111     if (AllocAndLoadString(&lpFormat,
112                            hInstance,
113                            uID) > 0)
114     {
115         va_start(lArgs, lpTarget);
116         /* let's use FormatMessage to format it because it has the ability to allocate
117            memory automatically */
118         Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
119                              lpFormat,
120                              0,
121                              0,
122                              (LPWSTR)lpTarget,
123                              0,
124                              &lArgs);
125         va_end(lArgs);
126 
127         LocalFree((HLOCAL)lpFormat);
128     }
129 
130     return Ret;
131 }
132 
133 LPARAM
ListViewGetSelectedItemData(IN HWND hwnd)134 ListViewGetSelectedItemData(IN HWND hwnd)
135 {
136     int Index;
137 
138     Index = ListView_GetNextItem(hwnd,
139                                  -1,
140                                  LVNI_SELECTED);
141     if (Index != -1)
142     {
143         LVITEM li;
144 
145         li.mask = LVIF_PARAM;
146         li.iItem = Index;
147         li.iSubItem = 0;
148 
149         if (ListView_GetItem(hwnd,
150                              &li))
151         {
152             return li.lParam;
153         }
154     }
155 
156     return 0;
157 }
158 
159 BOOL
ListViewSelectItem(IN HWND hwnd,IN INT Index)160 ListViewSelectItem(IN HWND hwnd,
161                    IN INT Index)
162 {
163     LVITEM li;
164 
165     li.mask = LVIF_STATE;
166     li.iItem = Index;
167     li.iSubItem = 0;
168     li.state = LVIS_SELECTED;
169     li.stateMask = LVIS_SELECTED;
170 
171     return ListView_SetItem(hwnd,
172                             &li);
173 }
174 
175 HRESULT
InitializeObjectPicker(IN PCWSTR ServerName,IN PSI_OBJECT_INFO ObjectInfo,OUT IDsObjectPicker ** pDsObjectPicker)176 InitializeObjectPicker(IN PCWSTR ServerName,
177                        IN PSI_OBJECT_INFO ObjectInfo,
178                        OUT IDsObjectPicker **pDsObjectPicker)
179 {
180     HRESULT hRet;
181 
182     *pDsObjectPicker = NULL;
183 
184     hRet = CoCreateInstance(&CLSID_DsObjectPicker,
185                             NULL,
186                             CLSCTX_INPROC_SERVER,
187                             &IID_IDsObjectPicker,
188                             (LPVOID*)pDsObjectPicker);
189     if (SUCCEEDED(hRet))
190     {
191         DSOP_INIT_INFO InitInfo;
192         UINT i;
193         static DSOP_SCOPE_INIT_INFO Scopes[] =
194         {
195             {
196                 sizeof(DSOP_SCOPE_INIT_INFO),
197                 DSOP_SCOPE_TYPE_TARGET_COMPUTER,
198                 DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS | DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS |
199                     DSOP_SCOPE_FLAG_STARTING_SCOPE,
200                 {
201                     {
202                         0,
203                         0,
204                         0
205                     },
206                     DSOP_DOWNLEVEL_FILTER_USERS | DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS |
207                         DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS | DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS
208                 },
209                 NULL,
210                 NULL,
211                 S_OK
212             },
213         };
214 
215         InitInfo.cbSize = sizeof(InitInfo);
216         InitInfo.pwzTargetComputer = ServerName;
217         InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]);
218         InitInfo.aDsScopeInfos = Scopes;
219         InitInfo.flOptions = DSOP_FLAG_MULTISELECT;
220         InitInfo.cAttributesToFetch = sizeof(ObjectPickerAttributes) / sizeof(ObjectPickerAttributes[0]);
221         InitInfo.apwzAttributeNames = ObjectPickerAttributes;
222 
223         for (i = 0; i < InitInfo.cDsScopeInfos; i++)
224         {
225             if ((ObjectInfo->dwFlags & SI_SERVER_IS_DC) &&
226                 (InitInfo.aDsScopeInfos[i].flType & DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN))
227             {
228                 /* only set the domain controller string if we know the target
229                    computer is a domain controller and the scope type is an
230                    up-level domain to which the target computer is joined */
231                 InitInfo.aDsScopeInfos[i].pwzDcName = InitInfo.pwzTargetComputer;
232             }
233         }
234 
235         hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
236                                                       &InitInfo);
237 
238         if (FAILED(hRet))
239         {
240             /* delete the object picker in case initialization failed! */
241             (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
242         }
243     }
244 
245     return hRet;
246 }
247 
248 HRESULT
InvokeObjectPickerDialog(IN IDsObjectPicker * pDsObjectPicker,IN HWND hwndParent OPTIONAL,IN POBJPICK_SELECTED_SID SelectedSidCallback,IN PVOID Context OPTIONAL)249 InvokeObjectPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
250                          IN HWND hwndParent  OPTIONAL,
251                          IN POBJPICK_SELECTED_SID SelectedSidCallback,
252                          IN PVOID Context  OPTIONAL)
253 {
254     IDataObject *pdo = NULL;
255     HRESULT hRet;
256 
257     hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
258                                                  hwndParent,
259                                                  &pdo);
260     if (hRet == S_OK)
261     {
262         STGMEDIUM stm;
263         FORMATETC fe;
264 
265         fe.cfFormat = (WORD)RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
266         fe.ptd = NULL;
267         fe.dwAspect = DVASPECT_CONTENT;
268         fe.lindex = -1;
269         fe.tymed = TYMED_HGLOBAL;
270 
271         hRet = pdo->lpVtbl->GetData(pdo,
272                                     &fe,
273                                     &stm);
274         if (SUCCEEDED(hRet))
275         {
276             PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
277             if (SelectionList != NULL)
278             {
279                 LPVARIANT vSid;
280                 PSID pSid;
281                 UINT i;
282                 BOOL contLoop = TRUE;
283 
284                 for (i = 0; i < SelectionList->cItems && contLoop; i++)
285                 {
286                     vSid = SelectionList->aDsSelection[i].pvarFetchedAttributes;
287 
288                     if (vSid != NULL && V_VT(vSid) == (VT_ARRAY | VT_UI1))
289                     {
290                         hRet = SafeArrayAccessData(V_ARRAY(vSid),
291                                                    (void **)&pSid);
292                         if (FAILED(hRet))
293                         {
294                             break;
295                         }
296 
297                         if (pSid != NULL)
298                         {
299                             contLoop = SelectedSidCallback(pDsObjectPicker,
300                                                            hwndParent,
301                                                            pSid,
302                                                            Context);
303                         }
304 
305                         SafeArrayUnaccessData(V_ARRAY(vSid));
306                     }
307                 }
308 
309                 GlobalUnlock(stm.hGlobal);
310 
311                 if (SUCCEEDED(hRet))
312                 {
313                     /* return S_OK instead of possible other success codes if
314                        everything went well */
315                     hRet = S_OK;
316                 }
317             }
318             else
319             {
320                 /* unable to translate the selection pointer handle, indicate
321                    failure */
322                 hRet = E_FAIL;
323             }
324 
325             ReleaseStgMedium(&stm);
326         }
327 
328         pdo->lpVtbl->Release(pdo);
329     }
330 
331     return hRet;
332 }
333 
334 VOID
FreeObjectPicker(IN IDsObjectPicker * pDsObjectPicker)335 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
336 {
337     pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
338 }
339