Added parser template and made AVISplitter use it.
[wine] / dlls / setupapi / misc.c
1 /*
2  * Setupapi miscellaneous functions
3  *
4  * Copyright 2005 Eric Kohl
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "setupapi.h"
29
30 #include "wine/unicode.h"
31 #include "wine/debug.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
34
35
36 /**************************************************************************
37  * MyFree [SETUPAPI.@]
38  *
39  * Frees an allocated memory block from the process heap.
40  *
41  * PARAMS
42  *     lpMem [I] pointer to memory block which will be freed
43  *
44  * RETURNS
45  *     None
46  */
47 VOID WINAPI MyFree(LPVOID lpMem)
48 {
49     TRACE("%p\n", lpMem);
50     HeapFree(GetProcessHeap(), 0, lpMem);
51 }
52
53
54 /**************************************************************************
55  * MyMalloc [SETUPAPI.@]
56  *
57  * Allocates memory block from the process heap.
58  *
59  * PARAMS
60  *     dwSize [I] size of the allocated memory block
61  *
62  * RETURNS
63  *     Success: pointer to allocated memory block
64  *     Failure: NULL
65  */
66 LPVOID WINAPI MyMalloc(DWORD dwSize)
67 {
68     TRACE("%lu\n", dwSize);
69     return HeapAlloc(GetProcessHeap(), 0, dwSize);
70 }
71
72
73 /**************************************************************************
74  * MyRealloc [SETUPAPI.@]
75  *
76  * Changes the size of an allocated memory block or allocates a memory
77  * block from the process heap.
78  *
79  * PARAMS
80  *     lpSrc  [I] pointer to memory block which will be resized
81  *     dwSize [I] new size of the memory block
82  *
83  * RETURNS
84  *     Success: pointer to the resized memory block
85  *     Failure: NULL
86  *
87  * NOTES
88  *     If lpSrc is a NULL-pointer, then MyRealloc allocates a memory
89  *     block like MyMalloc.
90  */
91 LPVOID WINAPI MyRealloc(LPVOID lpSrc, DWORD dwSize)
92 {
93     TRACE("%p %lu\n", lpSrc, dwSize);
94
95     if (lpSrc == NULL)
96         return HeapAlloc(GetProcessHeap(), 0, dwSize);
97
98     return HeapReAlloc(GetProcessHeap(), 0, lpSrc, dwSize);
99 }
100
101
102 /**************************************************************************
103  * DuplicateString [SETUPAPI.@]
104  *
105  * Duplicates a unicode string.
106  *
107  * PARAMS
108  *     lpSrc  [I] pointer to the unicode string that will be duplicated
109  *
110  * RETURNS
111  *     Success: pointer to the duplicated unicode string
112  *     Failure: NULL
113  *
114  * NOTES
115  *     Call MyFree() to release the duplicated string.
116  */
117 LPWSTR WINAPI DuplicateString(LPCWSTR lpSrc)
118 {
119     LPWSTR lpDst;
120
121     TRACE("%s\n", debugstr_w(lpSrc));
122
123     lpDst = MyMalloc((lstrlenW(lpSrc) + 1) * sizeof(WCHAR));
124     if (lpDst == NULL)
125         return NULL;
126
127     strcpyW(lpDst, lpSrc);
128
129     return lpDst;
130 }
131
132
133 /**************************************************************************
134  * QueryRegistryValue [SETUPAPI.@]
135  *
136  * Retrieves value data from the registry and allocates memory for the
137  * value data.
138  *
139  * PARAMS
140  *     hKey        [I] Handle of the key to query
141  *     lpValueName [I] Name of value under hkey to query
142  *     lpData      [O] Destination for the values contents,
143  *     lpType      [O] Destination for the value type
144  *     lpcbData    [O] Destination for the size of data
145  *
146  * RETURNS
147  *     Success: ERROR_SUCCESS
148  *     Failure: Otherwise
149  *
150  * NOTES
151  *     Use MyFree to release the lpData buffer.
152  */
153 LONG WINAPI QueryRegistryValue(HKEY hKey,
154                                LPCWSTR lpValueName,
155                                LPBYTE  *lpData,
156                                LPDWORD lpType,
157                                LPDWORD lpcbData)
158 {
159     LONG lError;
160
161     TRACE("%p %s %p %p %p\n",
162           hKey, debugstr_w(lpValueName), lpData, lpType, lpcbData);
163
164     /* Get required buffer size */
165     *lpcbData = 0;
166     lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, NULL, lpcbData);
167     if (lError != ERROR_SUCCESS)
168         return lError;
169
170     /* Allocate buffer */
171     *lpData = MyMalloc(*lpcbData);
172     if (*lpData == NULL)
173         return ERROR_NOT_ENOUGH_MEMORY;
174
175     /* Query registry value */
176     lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, *lpData, lpcbData);
177     if (lError != ERROR_SUCCESS)
178         MyFree(*lpData);
179
180     return lError;
181 }
182
183
184 /**************************************************************************
185  * IsUserAdmin [SETUPAPI.@]
186  *
187  * Checks whether the current user is a member of the Administrators group.
188  *
189  * PARAMS
190  *     None
191  *
192  * RETURNS
193  *     Success: TRUE
194  *     Failure: FALSE
195  */
196 BOOL WINAPI IsUserAdmin(VOID)
197 {
198     SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};
199     HANDLE hToken;
200     DWORD dwSize;
201     PTOKEN_GROUPS lpGroups;
202     PSID lpSid;
203     DWORD i;
204     BOOL bResult = FALSE;
205
206     TRACE("\n");
207
208     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
209     {
210         return FALSE;
211     }
212
213     if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize))
214     {
215         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
216         {
217             CloseHandle(hToken);
218             return FALSE;
219         }
220     }
221
222     lpGroups = MyMalloc(dwSize);
223     if (lpGroups == NULL)
224     {
225         CloseHandle(hToken);
226         return FALSE;
227     }
228
229     if (!GetTokenInformation(hToken, TokenGroups, lpGroups, dwSize, &dwSize))
230     {
231         MyFree(lpGroups);
232         CloseHandle(hToken);
233         return FALSE;
234     }
235
236     CloseHandle(hToken);
237
238     if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
239                                   DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
240                                   &lpSid))
241     {
242         MyFree(lpGroups);
243         return FALSE;
244     }
245
246     for (i = 0; i < lpGroups->GroupCount; i++)
247     {
248         if (EqualSid(lpSid, &lpGroups->Groups[i].Sid))
249         {
250             bResult = TRUE;
251             break;
252         }
253     }
254
255     FreeSid(lpSid);
256     MyFree(lpGroups);
257
258     return bResult;
259 }
260
261
262 /**************************************************************************
263  * MultiByteToUnicode [SETUPAPI.@]
264  *
265  * Converts a multi-byte string to a Unicode string.
266  *
267  * PARAMS
268  *     lpMultiByteStr  [I] Multi-byte string to be converted
269  *     uCodePage       [I] Code page
270  *
271  * RETURNS
272  *     Success: pointer to the converted Unicode string
273  *     Failure: NULL
274  *
275  * NOTE
276  *     Use MyFree to release the returned Unicode string.
277  */
278 LPWSTR WINAPI MultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
279 {
280     LPWSTR lpUnicodeStr;
281     int nLength;
282
283     TRACE("%s %d\n", debugstr_a(lpMultiByteStr), uCodePage);
284
285     nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
286                                   -1, NULL, 0);
287     if (nLength == 0)
288         return NULL;
289
290     lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR));
291     if (lpUnicodeStr == NULL)
292         return NULL;
293
294     if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
295                              nLength, lpUnicodeStr, nLength))
296     {
297         MyFree(lpUnicodeStr);
298         return NULL;
299     }
300
301     return lpUnicodeStr;
302 }
303
304
305 /**************************************************************************
306  * UnicodeToMultiByte [SETUPAPI.@]
307  *
308  * Converts a Unicode string to a multi-byte string.
309  *
310  * PARAMS
311  *     lpUnicodeStr  [I] Unicode string to be converted
312  *     uCodePage     [I] Code page
313  *
314  * RETURNS
315  *     Success: pointer to the converted multi-byte string
316  *     Failure: NULL
317  *
318  * NOTE
319  *     Use MyFree to release the returned multi-byte string.
320  */
321 LPSTR WINAPI UnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage)
322 {
323     LPSTR lpMultiByteStr;
324     int nLength;
325
326     TRACE("%s %d\n", debugstr_w(lpUnicodeStr), uCodePage);
327
328     nLength = WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
329                                   NULL, 0, NULL, NULL);
330     if (nLength == 0)
331         return NULL;
332
333     lpMultiByteStr = MyMalloc(nLength);
334     if (lpMultiByteStr == NULL)
335         return NULL;
336
337     if (!WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
338                              lpMultiByteStr, nLength, NULL, NULL))
339     {
340         MyFree(lpMultiByteStr);
341         return NULL;
342     }
343
344     return lpMultiByteStr;
345 }
346
347
348 /**************************************************************************
349  * DoesUserHavePrivilege [SETUPAPI.@]
350  *
351  * Check whether the current user has got a given privilege.
352  *
353  * PARAMS
354  *     lpPrivilegeName  [I] Name of the privilege to be checked
355  *
356  * RETURNS
357  *     Success: TRUE
358  *     Failure: FALSE
359  */
360 BOOL WINAPI DoesUserHavePrivilege(LPCWSTR lpPrivilegeName)
361 {
362     HANDLE hToken;
363     DWORD dwSize;
364     PTOKEN_PRIVILEGES lpPrivileges;
365     LUID PrivilegeLuid;
366     DWORD i;
367     BOOL bResult = FALSE;
368
369     TRACE("%s\n", debugstr_w(lpPrivilegeName));
370
371     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
372         return FALSE;
373
374     if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize))
375     {
376         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
377         {
378             CloseHandle(hToken);
379             return FALSE;
380         }
381     }
382
383     lpPrivileges = MyMalloc(dwSize);
384     if (lpPrivileges == NULL)
385     {
386         CloseHandle(hToken);
387         return FALSE;
388     }
389
390     if (!GetTokenInformation(hToken, TokenPrivileges, lpPrivileges, dwSize, &dwSize))
391     {
392         MyFree(lpPrivileges);
393         CloseHandle(hToken);
394         return FALSE;
395     }
396
397     CloseHandle(hToken);
398
399     if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, &PrivilegeLuid))
400     {
401         MyFree(lpPrivileges);
402         return FALSE;
403     }
404
405     for (i = 0; i < lpPrivileges->PrivilegeCount; i++)
406     {
407         if (lpPrivileges->Privileges[i].Luid.HighPart == PrivilegeLuid.HighPart &&
408             lpPrivileges->Privileges[i].Luid.LowPart == PrivilegeLuid.LowPart)
409         {
410             bResult = TRUE;
411         }
412     }
413
414     MyFree(lpPrivileges);
415
416     return bResult;
417 }
418
419
420 /**************************************************************************
421  * EnablePrivilege [SETUPAPI.@]
422  *
423  * Enables or disables one of the current users privileges.
424  *
425  * PARAMS
426  *     lpPrivilegeName  [I] Name of the privilege to be changed
427  *     bEnable          [I] TRUE: Enables the privilege
428  *                          FALSE: Disables the privilege
429  *
430  * RETURNS
431  *     Success: TRUE
432  *     Failure: FALSE
433  */
434 BOOL WINAPI EnablePrivilege(LPCWSTR lpPrivilegeName, BOOL bEnable)
435 {
436     TOKEN_PRIVILEGES Privileges;
437     HANDLE hToken;
438     BOOL bResult;
439
440     TRACE("%s %s\n", debugstr_w(lpPrivilegeName), bEnable ? "TRUE" : "FALSE");
441
442     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
443         return FALSE;
444
445     Privileges.PrivilegeCount = 1;
446     Privileges.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;
447
448     if (!LookupPrivilegeValueW(NULL, lpPrivilegeName,
449                                &Privileges.Privileges[0].Luid))
450     {
451         CloseHandle(hToken);
452         return FALSE;
453     }
454
455     bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL);
456
457     CloseHandle(hToken);
458
459     return bResult;
460 }