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 #include "setupapi_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
39 /**************************************************************************
42 * Frees an allocated memory block from the process heap.
45 * lpMem [I] pointer to memory block which will be freed
50 VOID WINAPI MyFree(LPVOID lpMem)
53 HeapFree(GetProcessHeap(), 0, lpMem);
57 /**************************************************************************
58 * MyMalloc [SETUPAPI.@]
60 * Allocates memory block from the process heap.
63 * dwSize [I] size of the allocated memory block
66 * Success: pointer to allocated memory block
69 LPVOID WINAPI MyMalloc(DWORD dwSize)
71 TRACE("%lu\n", dwSize);
72 return HeapAlloc(GetProcessHeap(), 0, dwSize);
76 /**************************************************************************
77 * MyRealloc [SETUPAPI.@]
79 * Changes the size of an allocated memory block or allocates a memory
80 * block from the process heap.
83 * lpSrc [I] pointer to memory block which will be resized
84 * dwSize [I] new size of the memory block
87 * Success: pointer to the resized memory block
91 * If lpSrc is a NULL-pointer, then MyRealloc allocates a memory
92 * block like MyMalloc.
94 LPVOID WINAPI MyRealloc(LPVOID lpSrc, DWORD dwSize)
96 TRACE("%p %lu\n", lpSrc, dwSize);
99 return HeapAlloc(GetProcessHeap(), 0, dwSize);
101 return HeapReAlloc(GetProcessHeap(), 0, lpSrc, dwSize);
105 /**************************************************************************
106 * DuplicateString [SETUPAPI.@]
108 * Duplicates a unicode string.
111 * lpSrc [I] pointer to the unicode string that will be duplicated
114 * Success: pointer to the duplicated unicode string
118 * Call MyFree() to release the duplicated string.
120 LPWSTR WINAPI DuplicateString(LPCWSTR lpSrc)
124 TRACE("%s\n", debugstr_w(lpSrc));
126 lpDst = MyMalloc((lstrlenW(lpSrc) + 1) * sizeof(WCHAR));
130 strcpyW(lpDst, lpSrc);
136 /**************************************************************************
137 * QueryRegistryValue [SETUPAPI.@]
139 * Retrieves value data from the registry and allocates memory for the
143 * hKey [I] Handle of the key to query
144 * lpValueName [I] Name of value under hkey to query
145 * lpData [O] Destination for the values contents,
146 * lpType [O] Destination for the value type
147 * lpcbData [O] Destination for the size of data
150 * Success: ERROR_SUCCESS
154 * Use MyFree to release the lpData buffer.
156 LONG WINAPI QueryRegistryValue(HKEY hKey,
164 TRACE("%p %s %p %p %p\n",
165 hKey, debugstr_w(lpValueName), lpData, lpType, lpcbData);
167 /* Get required buffer size */
169 lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, NULL, lpcbData);
170 if (lError != ERROR_SUCCESS)
173 /* Allocate buffer */
174 *lpData = MyMalloc(*lpcbData);
176 return ERROR_NOT_ENOUGH_MEMORY;
178 /* Query registry value */
179 lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, *lpData, lpcbData);
180 if (lError != ERROR_SUCCESS)
187 /**************************************************************************
188 * IsUserAdmin [SETUPAPI.@]
190 * Checks whether the current user is a member of the Administrators group.
199 BOOL WINAPI IsUserAdmin(VOID)
201 SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};
204 PTOKEN_GROUPS lpGroups;
207 BOOL bResult = FALSE;
211 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
216 if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize))
218 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
225 lpGroups = MyMalloc(dwSize);
226 if (lpGroups == NULL)
232 if (!GetTokenInformation(hToken, TokenGroups, lpGroups, dwSize, &dwSize))
241 if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
242 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
249 for (i = 0; i < lpGroups->GroupCount; i++)
251 if (EqualSid(lpSid, &lpGroups->Groups[i].Sid))
265 /**************************************************************************
266 * MultiByteToUnicode [SETUPAPI.@]
268 * Converts a multi-byte string to a Unicode string.
271 * lpMultiByteStr [I] Multi-byte string to be converted
272 * uCodePage [I] Code page
275 * Success: pointer to the converted Unicode string
279 * Use MyFree to release the returned Unicode string.
281 LPWSTR WINAPI MultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
286 TRACE("%s %d\n", debugstr_a(lpMultiByteStr), uCodePage);
288 nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
293 lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR));
294 if (lpUnicodeStr == NULL)
297 if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
298 nLength, lpUnicodeStr, nLength))
300 MyFree(lpUnicodeStr);
308 /**************************************************************************
309 * UnicodeToMultiByte [SETUPAPI.@]
311 * Converts a Unicode string to a multi-byte string.
314 * lpUnicodeStr [I] Unicode string to be converted
315 * uCodePage [I] Code page
318 * Success: pointer to the converted multi-byte string
322 * Use MyFree to release the returned multi-byte string.
324 LPSTR WINAPI UnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage)
326 LPSTR lpMultiByteStr;
329 TRACE("%s %d\n", debugstr_w(lpUnicodeStr), uCodePage);
331 nLength = WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
332 NULL, 0, NULL, NULL);
336 lpMultiByteStr = MyMalloc(nLength);
337 if (lpMultiByteStr == NULL)
340 if (!WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
341 lpMultiByteStr, nLength, NULL, NULL))
343 MyFree(lpMultiByteStr);
347 return lpMultiByteStr;
351 /**************************************************************************
352 * DoesUserHavePrivilege [SETUPAPI.@]
354 * Check whether the current user has got a given privilege.
357 * lpPrivilegeName [I] Name of the privilege to be checked
363 BOOL WINAPI DoesUserHavePrivilege(LPCWSTR lpPrivilegeName)
367 PTOKEN_PRIVILEGES lpPrivileges;
370 BOOL bResult = FALSE;
372 TRACE("%s\n", debugstr_w(lpPrivilegeName));
374 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
377 if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize))
379 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
386 lpPrivileges = MyMalloc(dwSize);
387 if (lpPrivileges == NULL)
393 if (!GetTokenInformation(hToken, TokenPrivileges, lpPrivileges, dwSize, &dwSize))
395 MyFree(lpPrivileges);
402 if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, &PrivilegeLuid))
404 MyFree(lpPrivileges);
408 for (i = 0; i < lpPrivileges->PrivilegeCount; i++)
410 if (lpPrivileges->Privileges[i].Luid.HighPart == PrivilegeLuid.HighPart &&
411 lpPrivileges->Privileges[i].Luid.LowPart == PrivilegeLuid.LowPart)
417 MyFree(lpPrivileges);
423 /**************************************************************************
424 * EnablePrivilege [SETUPAPI.@]
426 * Enables or disables one of the current users privileges.
429 * lpPrivilegeName [I] Name of the privilege to be changed
430 * bEnable [I] TRUE: Enables the privilege
431 * FALSE: Disables the privilege
437 BOOL WINAPI EnablePrivilege(LPCWSTR lpPrivilegeName, BOOL bEnable)
439 TOKEN_PRIVILEGES Privileges;
443 TRACE("%s %s\n", debugstr_w(lpPrivilegeName), bEnable ? "TRUE" : "FALSE");
445 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
448 Privileges.PrivilegeCount = 1;
449 Privileges.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;
451 if (!LookupPrivilegeValueW(NULL, lpPrivilegeName,
452 &Privileges.Privileges[0].Luid))
458 bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL);
466 BOOL WINAPI DelayedMove(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName)
468 return MoveFileExW(lpExistingFileName, lpNewFileName,
469 MOVEFILE_REPLACE_EXISTING | MOVEFILE_DELAY_UNTIL_REBOOT);
473 BOOL WINAPI FileExists(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFileFindData)
475 WIN32_FIND_DATAW FindData;
480 uErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
482 hFind = FindFirstFileW(lpFileName, &FindData);
483 if (hFind == INVALID_HANDLE_VALUE)
485 dwError = GetLastError();
486 SetErrorMode(uErrorMode);
487 SetLastError(dwError);
494 memcpy(lpFileFindData, &FindData, sizeof(WIN32_FIND_DATAW));