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("%lx %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 %lu\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 %lu\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 /**************************************************************************
467 * DelayedMove [SETUPAPI.@]
469 * Moves a file upon the next reboot.
472 * lpExistingFileName [I] Current file name
473 * lpNewFileName [I] New file name
479 BOOL WINAPI
DelayedMove(LPCWSTR lpExistingFileName
, LPCWSTR lpNewFileName
)
481 if (OsVersionInfo
.dwPlatformId
!= VER_PLATFORM_WIN32_NT
)
483 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
487 return MoveFileExW(lpExistingFileName
, lpNewFileName
,
488 MOVEFILE_REPLACE_EXISTING
| MOVEFILE_DELAY_UNTIL_REBOOT
);
492 /**************************************************************************
493 * FileExists [SETUPAPI.@]
495 * Checks whether a file exists.
498 * lpFileName [I] Name of the file to check
499 * lpNewFileName [O] Optional information about the existing file
505 BOOL WINAPI
FileExists(LPCWSTR lpFileName
, LPWIN32_FIND_DATAW lpFileFindData
)
507 WIN32_FIND_DATAW FindData
;
512 uErrorMode
= SetErrorMode(SEM_FAILCRITICALERRORS
);
514 hFind
= FindFirstFileW(lpFileName
, &FindData
);
515 if (hFind
== INVALID_HANDLE_VALUE
)
517 dwError
= GetLastError();
518 SetErrorMode(uErrorMode
);
519 SetLastError(dwError
);
526 memcpy(lpFileFindData
, &FindData
, sizeof(WIN32_FIND_DATAW
));
528 SetErrorMode(uErrorMode
);
534 /**************************************************************************
535 * CaptureStringArg [SETUPAPI.@]
537 * Captures a UNICODE string.
540 * lpSrc [I] UNICODE string to be captured
541 * lpDst [O] Pointer to the captured UNICODE string
544 * Success: ERROR_SUCCESS
545 * Failure: ERROR_INVALID_PARAMETER
548 * Call MyFree to release the captured UNICODE string.
550 DWORD WINAPI
CaptureStringArg(LPCWSTR pSrc
, LPWSTR
*pDst
)
553 return ERROR_INVALID_PARAMETER
;
555 *pDst
= DuplicateString(pSrc
);
557 return ERROR_SUCCESS
;
561 /**************************************************************************
562 * CaptureAndConvertAnsiArg [SETUPAPI.@]
564 * Captures an ANSI string and converts it to a UNICODE string.
567 * lpSrc [I] ANSI string to be captured
568 * lpDst [O] Pointer to the captured UNICODE string
571 * Success: ERROR_SUCCESS
572 * Failure: ERROR_INVALID_PARAMETER
575 * Call MyFree to release the captured UNICODE string.
577 DWORD WINAPI
CaptureAndConvertAnsiArg(LPCSTR pSrc
, LPWSTR
*pDst
)
580 return ERROR_INVALID_PARAMETER
;
582 *pDst
= MultiByteToUnicode(pSrc
, CP_ACP
);
584 return ERROR_SUCCESS
;