minor fixes and use a .spec file
[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 #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
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
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
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
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
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
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
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 = 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 HUGEP**)&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
335 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
336 {
337 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
338 }
339