078d1a19a548ea7c193b550c0b6780601812abbe
[reactos.git] / reactos / lib / aclui / misc.c
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS Access Control List Editor
22 * FILE: lib/aclui/misc.c
23 * PURPOSE: Access Control List Editor
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 *
26 * UPDATE HISTORY:
27 * 07/01/2005 Created
28 */
29 #define INITGUID
30 #include <windows.h>
31 #include <aclui.h>
32
33 #include <precomp.h>
34
35 static PCWSTR ObjectPickerAttributes[] =
36 {
37 L"ObjectSid",
38 };
39
40 static INT
41 LengthOfStrResource(IN HINSTANCE hInst,
42 IN UINT uID)
43 {
44 HRSRC hrSrc;
45 HGLOBAL hRes;
46 LPWSTR lpName, lpStr;
47
48 if (hInst == NULL)
49 {
50 return -1;
51 }
52
53 /* There are always blocks of 16 strings */
54 lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
55
56 /* Find the string table block */
57 if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
58 (hRes = LoadResource(hInst, hrSrc)) &&
59 (lpStr = LockResource(hRes)))
60 {
61 UINT x;
62
63 /* Find the string we're looking for */
64 uID &= 0xF; /* position in the block, same as % 16 */
65 for (x = 0; x < uID; x++)
66 {
67 lpStr += (*lpStr) + 1;
68 }
69
70 /* Found the string */
71 return (int)(*lpStr);
72 }
73 return -1;
74 }
75
76 static INT
77 AllocAndLoadString(OUT LPWSTR *lpTarget,
78 IN HINSTANCE hInst,
79 IN UINT uID)
80 {
81 INT ln;
82
83 ln = LengthOfStrResource(hInst,
84 uID);
85 if (ln++ > 0)
86 {
87 (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
88 ln * sizeof(WCHAR));
89 if ((*lpTarget) != NULL)
90 {
91 INT Ret;
92 if (!(Ret = LoadStringW(hInst, uID, *lpTarget, ln)))
93 {
94 LocalFree((HLOCAL)(*lpTarget));
95 }
96 return Ret;
97 }
98 }
99 return 0;
100 }
101
102 DWORD
103 LoadAndFormatString(IN HINSTANCE hInstance,
104 IN UINT uID,
105 OUT LPWSTR *lpTarget,
106 ...)
107 {
108 DWORD Ret = 0;
109 LPWSTR lpFormat;
110 va_list lArgs;
111
112 if (AllocAndLoadString(&lpFormat,
113 hInstance,
114 uID) > 0)
115 {
116 va_start(lArgs, lpTarget);
117 /* let's use FormatMessage to format it because it has the ability to allocate
118 memory automatically */
119 Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
120 lpFormat,
121 0,
122 0,
123 (LPWSTR)lpTarget,
124 0,
125 &lArgs);
126 va_end(lArgs);
127
128 LocalFree((HLOCAL)lpFormat);
129 }
130
131 return Ret;
132 }
133
134 BOOL
135 OpenLSAPolicyHandle(IN LPWSTR SystemName,
136 IN ACCESS_MASK DesiredAccess,
137 OUT PLSA_HANDLE PolicyHandle)
138 {
139 LSA_OBJECT_ATTRIBUTES LsaObjectAttributes;
140 LSA_UNICODE_STRING LsaSystemName, *psn;
141 NTSTATUS Status;
142
143 ZeroMemory(&LsaObjectAttributes, sizeof(LSA_OBJECT_ATTRIBUTES));
144
145 if (SystemName != NULL)
146 {
147 LsaSystemName.Buffer = SystemName;
148 LsaSystemName.Length = wcslen(SystemName) * sizeof(WCHAR);
149 LsaSystemName.MaximumLength = LsaSystemName.Length + sizeof(WCHAR);
150 psn = &LsaSystemName;
151 }
152 else
153 {
154 psn = NULL;
155 }
156
157 Status = LsaOpenPolicy(psn,
158 &LsaObjectAttributes,
159 DesiredAccess,
160 PolicyHandle);
161 if (!NT_SUCCESS(Status))
162 {
163 SetLastError(LsaNtStatusToWinError(Status));
164 return FALSE;
165 }
166
167 return TRUE;
168 }
169
170 LPARAM
171 ListViewGetSelectedItemData(IN HWND hwnd)
172 {
173 int Index;
174
175 Index = ListView_GetNextItem(hwnd,
176 -1,
177 LVNI_SELECTED);
178 if (Index != -1)
179 {
180 LVITEM li;
181
182 li.mask = LVIF_PARAM;
183 li.iItem = Index;
184 li.iSubItem = 0;
185
186 if (ListView_GetItem(hwnd,
187 &li))
188 {
189 return li.lParam;
190 }
191 }
192
193 return 0;
194 }
195
196 BOOL
197 ListViewSelectItem(IN HWND hwnd,
198 IN INT Index)
199 {
200 LVITEM li;
201
202 li.mask = LVIF_STATE;
203 li.iItem = Index;
204 li.iSubItem = 0;
205 li.state = LVIS_SELECTED;
206 li.stateMask = LVIS_SELECTED;
207
208 return ListView_SetItem(hwnd,
209 &li);
210 }
211
212 HRESULT
213 InitializeObjectPicker(IN PCWSTR ServerName,
214 IN PSI_OBJECT_INFO ObjectInfo,
215 OUT IDsObjectPicker **pDsObjectPicker)
216 {
217 HRESULT hRet;
218
219 *pDsObjectPicker = NULL;
220
221 hRet = CoCreateInstance(&CLSID_DsObjectPicker,
222 NULL,
223 CLSCTX_INPROC_SERVER,
224 &IID_IDsObjectPicker,
225 (LPVOID*)pDsObjectPicker);
226 if (SUCCEEDED(hRet))
227 {
228 DSOP_INIT_INFO InitInfo;
229 UINT i;
230 DSOP_SCOPE_INIT_INFO Scopes[] =
231 {
232 {
233 sizeof(DSOP_SCOPE_INIT_INFO),
234 DSOP_SCOPE_TYPE_TARGET_COMPUTER,
235 DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS | DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS |
236 DSOP_SCOPE_FLAG_STARTING_SCOPE,
237 {
238 {
239 0,
240 0,
241 0
242 },
243 DSOP_DOWNLEVEL_FILTER_USERS | DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS |
244 DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS | DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS
245 },
246 NULL,
247 NULL,
248 S_OK
249 },
250 };
251
252 InitInfo.cbSize = sizeof(InitInfo);
253 InitInfo.pwzTargetComputer = ServerName;
254 InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]);
255 InitInfo.aDsScopeInfos = Scopes;
256 InitInfo.flOptions = DSOP_FLAG_MULTISELECT | DSOP_SCOPE_TYPE_TARGET_COMPUTER;
257 InitInfo.cAttributesToFetch = sizeof(ObjectPickerAttributes) / sizeof(ObjectPickerAttributes[0]);
258 InitInfo.apwzAttributeNames = ObjectPickerAttributes;
259
260 for (i = 0; i < InitInfo.cDsScopeInfos; i++)
261 {
262 if ((ObjectInfo->dwFlags & SI_SERVER_IS_DC) &&
263 (InitInfo.aDsScopeInfos[i].flType & DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN))
264 {
265 /* only set the domain controller string if we know the target
266 computer is a domain controller and the scope type is an
267 up-level domain to which the target computer is joined */
268 InitInfo.aDsScopeInfos[i].pwzDcName = InitInfo.pwzTargetComputer;
269 }
270 }
271
272 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
273 &InitInfo);
274
275 if (FAILED(hRet))
276 {
277 /* delete the object picker in case initialization failed! */
278 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
279 }
280 }
281
282 return hRet;
283 }
284
285 HRESULT
286 InvokeObjectPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
287 IN HWND hwndParent OPTIONAL,
288 IN POBJPICK_SELECTED_SID SelectedSidCallback,
289 IN PVOID Context OPTIONAL)
290 {
291 IDataObject *pdo = NULL;
292 HRESULT hRet;
293
294 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
295 hwndParent,
296 &pdo);
297 if (hRet == S_OK)
298 {
299 STGMEDIUM stm;
300 FORMATETC fe;
301
302 fe.cfFormat = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
303 fe.ptd = NULL;
304 fe.dwAspect = DVASPECT_CONTENT;
305 fe.lindex = -1;
306 fe.tymed = TYMED_HGLOBAL;
307
308 hRet = pdo->lpVtbl->GetData(pdo,
309 &fe,
310 &stm);
311 if (SUCCEEDED(hRet))
312 {
313 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
314 if (SelectionList != NULL)
315 {
316 LPVARIANT vSid;
317 PSID pSid;
318 UINT i;
319 BOOL contLoop = TRUE;
320
321 for (i = 0; i < SelectionList->cItems && contLoop; i++)
322 {
323 vSid = SelectionList->aDsSelection[i].pvarFetchedAttributes;
324
325 if (vSid != NULL && V_VT(vSid) == (VT_ARRAY | VT_UI1))
326 {
327 hRet = SafeArrayAccessData(V_ARRAY(vSid),
328 (void HUGEP**)&pSid);
329 if (FAILED(hRet))
330 {
331 break;
332 }
333
334 if (pSid != NULL)
335 {
336 contLoop = SelectedSidCallback(pDsObjectPicker,
337 hwndParent,
338 pSid,
339 Context);
340 }
341
342 SafeArrayUnaccessData(V_ARRAY(vSid));
343 }
344 }
345
346 GlobalUnlock(stm.hGlobal);
347 }
348
349 ReleaseStgMedium(&stm);
350 }
351
352 pdo->lpVtbl->Release(pdo);
353 }
354
355 return hRet;
356 }
357
358 VOID
359 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
360 {
361 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
362 }
363