2 * Setupapi miscellaneous functions
4 * Copyright 2005 Eric Kohl
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.
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.
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
30 #include "wine/unicode.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
36 /**************************************************************************
39 * Frees an allocated memory block from the process heap.
42 * lpMem [I] pointer to memory block which will be freed
47 VOID WINAPI MyFree(LPVOID lpMem)
50 HeapFree(GetProcessHeap(), 0, lpMem);
54 /**************************************************************************
55 * MyMalloc [SETUPAPI.@]
57 * Allocates memory block from the process heap.
60 * dwSize [I] size of the allocated memory block
63 * Success: pointer to allocated memory block
66 LPVOID WINAPI MyMalloc(DWORD dwSize)
68 TRACE("%lu\n", dwSize);
69 return HeapAlloc(GetProcessHeap(), 0, dwSize);
73 /**************************************************************************
74 * MyRealloc [SETUPAPI.@]
76 * Changes the size of an allocated memory block or allocates a memory
77 * block from the process heap.
80 * lpSrc [I] pointer to memory block which will be resized
81 * dwSize [I] new size of the memory block
84 * Success: pointer to the resized memory block
88 * If lpSrc is a NULL-pointer, then MyRealloc allocates a memory
89 * block like MyMalloc.
91 LPVOID WINAPI MyRealloc(LPVOID lpSrc, DWORD dwSize)
93 TRACE("%p %lu\n", lpSrc, dwSize);
96 return HeapAlloc(GetProcessHeap(), 0, dwSize);
98 return HeapReAlloc(GetProcessHeap(), 0, lpSrc, dwSize);
102 /**************************************************************************
103 * DuplicateString [SETUPAPI.@]
105 * Duplicates a unicode string.
108 * lpSrc [I] pointer to the unicode string that will be duplicated
111 * Success: pointer to the duplicated unicode string
115 * Call MyFree() to release the duplicated string.
117 LPWSTR WINAPI DuplicateString(LPCWSTR lpSrc)
121 TRACE("%s\n", debugstr_w(lpSrc));
123 lpDst = MyMalloc((lstrlenW(lpSrc) + 1) * sizeof(WCHAR));
127 strcpyW(lpDst, lpSrc);
133 /**************************************************************************
134 * QueryRegistryValue [SETUPAPI.@]
136 * Retrieves value data from the registry and allocates memory for the
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
147 * Success: ERROR_SUCCESS
151 * Use MyFree to release the lpData buffer.
153 LONG WINAPI QueryRegistryValue(HKEY hKey,
161 TRACE("%p %s %p %p %p\n",
162 hKey, debugstr_w(lpValueName), lpData, lpType, lpcbData);
164 /* Get required buffer size */
166 lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, NULL, lpcbData);
167 if (lError != ERROR_SUCCESS)
170 /* Allocate buffer */
171 *lpData = MyMalloc(*lpcbData);
173 return ERROR_NOT_ENOUGH_MEMORY;
175 /* Query registry value */
176 lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, *lpData, lpcbData);
177 if (lError != ERROR_SUCCESS)
184 /**************************************************************************
185 * IsUserAdmin [SETUPAPI.@]
187 * Checks whether the current user is a member of the Administrators group.
196 BOOL WINAPI IsUserAdmin(VOID)
198 SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};
201 PTOKEN_GROUPS lpGroups;
204 BOOL bResult = FALSE;
208 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
213 if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize))
215 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
222 lpGroups = MyMalloc(dwSize);
223 if (lpGroups == NULL)
229 if (!GetTokenInformation(hToken, TokenGroups, lpGroups, dwSize, &dwSize))
238 if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
239 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
246 for (i = 0; i < lpGroups->GroupCount; i++)
248 if (EqualSid(lpSid, &lpGroups->Groups[i].Sid))
262 /**************************************************************************
263 * MultiByteToUnicode [SETUPAPI.@]
265 * Converts a multi-byte string to a Unicode string.
268 * lpMultiByteStr [I] Multi-byte string to be converted
269 * uCodePage [I] Code page
272 * Success: pointer to the converted Unicode string
276 * Use MyFree to release the returned Unicode string.
278 LPWSTR WINAPI MultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
283 TRACE("%s %d\n", debugstr_a(lpMultiByteStr), uCodePage);
285 nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
290 lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR));
291 if (lpUnicodeStr == NULL)
294 if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
295 nLength, lpUnicodeStr, nLength))
297 MyFree(lpUnicodeStr);
305 /**************************************************************************
306 * UnicodeToMultiByte [SETUPAPI.@]
308 * Converts a Unicode string to a multi-byte string.
311 * lpUnicodeStr [I] Unicode string to be converted
312 * uCodePage [I] Code page
315 * Success: pointer to the converted multi-byte string
319 * Use MyFree to release the returned multi-byte string.
321 LPSTR WINAPI UnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage)
323 LPSTR lpMultiByteStr;
326 TRACE("%s %d\n", debugstr_w(lpUnicodeStr), uCodePage);
328 nLength = WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
329 NULL, 0, NULL, NULL);
333 lpMultiByteStr = MyMalloc(nLength);
334 if (lpMultiByteStr == NULL)
337 if (!WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
338 lpMultiByteStr, nLength, NULL, NULL))
340 MyFree(lpMultiByteStr);
344 return lpMultiByteStr;
348 /**************************************************************************
349 * DoesUserHavePrivilege [SETUPAPI.@]
351 * Check whether the current user has got a given privilege.
354 * lpPrivilegeName [I] Name of the privilege to be checked
360 BOOL WINAPI DoesUserHavePrivilege(LPCWSTR lpPrivilegeName)
364 PTOKEN_PRIVILEGES lpPrivileges;
367 BOOL bResult = FALSE;
369 TRACE("%s\n", debugstr_w(lpPrivilegeName));
371 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
374 if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize))
376 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
383 lpPrivileges = MyMalloc(dwSize);
384 if (lpPrivileges == NULL)
390 if (!GetTokenInformation(hToken, TokenPrivileges, lpPrivileges, dwSize, &dwSize))
392 MyFree(lpPrivileges);
399 if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, &PrivilegeLuid))
401 MyFree(lpPrivileges);
405 for (i = 0; i < lpPrivileges->PrivilegeCount; i++)
407 if (lpPrivileges->Privileges[i].Luid.HighPart == PrivilegeLuid.HighPart &&
408 lpPrivileges->Privileges[i].Luid.LowPart == PrivilegeLuid.LowPart)
414 MyFree(lpPrivileges);
420 /**************************************************************************
421 * EnablePrivilege [SETUPAPI.@]
423 * Enables or disables one of the current users privileges.
426 * lpPrivilegeName [I] Name of the privilege to be changed
427 * bEnable [I] TRUE: Enables the privilege
428 * FALSE: Disables the privilege
434 BOOL WINAPI EnablePrivilege(LPCWSTR lpPrivilegeName, BOOL bEnable)
436 TOKEN_PRIVILEGES Privileges;
440 TRACE("%s %s\n", debugstr_w(lpPrivilegeName), bEnable ? "TRUE" : "FALSE");
442 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
445 Privileges.PrivilegeCount = 1;
446 Privileges.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;
448 if (!LookupPrivilegeValueW(NULL, lpPrivilegeName,
449 &Privileges.Privileges[0].Luid))
455 bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL);