misc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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. #include <stdarg.h>
  21. #include "windef.h"
  22. #include "winbase.h"
  23. #include "wingdi.h"
  24. #include "winuser.h"
  25. #include "winreg.h"
  26. #include "setupapi.h"
  27. #include "wine/unicode.h"
  28. #include "wine/debug.h"
  29. WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
  30. /**************************************************************************
  31. * MyFree [SETUPAPI.@]
  32. *
  33. * Frees an allocated memory block from the process heap.
  34. *
  35. * PARAMS
  36. * lpMem [I] pointer to memory block which will be freed
  37. *
  38. * RETURNS
  39. * None
  40. */
  41. VOID WINAPI MyFree(LPVOID lpMem)
  42. {
  43. TRACE("%p\n", lpMem);
  44. HeapFree(GetProcessHeap(), 0, lpMem);
  45. }
  46. /**************************************************************************
  47. * MyMalloc [SETUPAPI.@]
  48. *
  49. * Allocates memory block from the process heap.
  50. *
  51. * PARAMS
  52. * dwSize [I] size of the allocated memory block
  53. *
  54. * RETURNS
  55. * Success: pointer to allocated memory block
  56. * Failure: NULL
  57. */
  58. LPVOID WINAPI MyMalloc(DWORD dwSize)
  59. {
  60. TRACE("%lu\n", dwSize);
  61. return HeapAlloc(GetProcessHeap(), 0, dwSize);
  62. }
  63. /**************************************************************************
  64. * MyRealloc [SETUPAPI.@]
  65. *
  66. * Changes the size of an allocated memory block or allocates a memory
  67. * block from the process heap.
  68. *
  69. * PARAMS
  70. * lpSrc [I] pointer to memory block which will be resized
  71. * dwSize [I] new size of the memory block
  72. *
  73. * RETURNS
  74. * Success: pointer to the resized memory block
  75. * Failure: NULL
  76. *
  77. * NOTES
  78. * If lpSrc is a NULL-pointer, then MyRealloc allocates a memory
  79. * block like MyMalloc.
  80. */
  81. LPVOID WINAPI MyRealloc(LPVOID lpSrc, DWORD dwSize)
  82. {
  83. TRACE("%p %lu\n", lpSrc, dwSize);
  84. if (lpSrc == NULL)
  85. return HeapAlloc(GetProcessHeap(), 0, dwSize);
  86. return HeapReAlloc(GetProcessHeap(), 0, lpSrc, dwSize);
  87. }
  88. /**************************************************************************
  89. * DuplicateString [SETUPAPI.@]
  90. *
  91. * Duplicates a unicode string.
  92. *
  93. * PARAMS
  94. * lpSrc [I] pointer to the unicode string that will be duplicated
  95. *
  96. * RETURNS
  97. * Success: pointer to the duplicated unicode string
  98. * Failure: NULL
  99. *
  100. * NOTES
  101. * Call MyFree() to release the duplicated string.
  102. */
  103. LPWSTR WINAPI DuplicateString(LPCWSTR lpSrc)
  104. {
  105. LPWSTR lpDst;
  106. TRACE("%s\n", debugstr_w(lpSrc));
  107. lpDst = MyMalloc((lstrlenW(lpSrc) + 1) * sizeof(WCHAR));
  108. if (lpDst == NULL)
  109. return NULL;
  110. strcpyW(lpDst, lpSrc);
  111. return lpDst;
  112. }
  113. /**************************************************************************
  114. * QueryRegistryValue [SETUPAPI.@]
  115. *
  116. * Retrieves value data from the registry and allocates memory for the
  117. * value data.
  118. *
  119. * PARAMS
  120. * hKey [I] Handle of the key to query
  121. * lpValueName [I] Name of value under hkey to query
  122. * lpData [O] Destination for the values contents,
  123. * lpType [O] Destination for the value type
  124. * lpcbData [O] Destination for the size of data
  125. *
  126. * RETURNS
  127. * Success: ERROR_SUCCESS
  128. * Failure: Otherwise
  129. *
  130. * NOTES
  131. * Use MyFree to release the lpData buffer.
  132. */
  133. LONG WINAPI QueryRegistryValue(HKEY hKey,
  134. LPCWSTR lpValueName,
  135. LPBYTE *lpData,
  136. LPDWORD lpType,
  137. LPDWORD lpcbData)
  138. {
  139. LONG lError;
  140. TRACE("%p %s %p %p %p\n",
  141. hKey, debugstr_w(lpValueName), lpData, lpType, lpcbData);
  142. /* Get required buffer size */
  143. *lpcbData = 0;
  144. lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, NULL, lpcbData);
  145. if (lError != ERROR_SUCCESS)
  146. return lError;
  147. /* Allocate buffer */
  148. *lpData = MyMalloc(*lpcbData);
  149. if (*lpData == NULL)
  150. return ERROR_NOT_ENOUGH_MEMORY;
  151. /* Query registry value */
  152. lError = RegQueryValueExW(hKey, lpValueName, 0, lpType, *lpData, lpcbData);
  153. if (lError != ERROR_SUCCESS)
  154. MyFree(*lpData);
  155. return lError;
  156. }
  157. /**************************************************************************
  158. * IsUserAdmin [SETUPAPI.@]
  159. *
  160. * Checks whether the current user is a member of the Administrators group.
  161. *
  162. * PARAMS
  163. * None
  164. *
  165. * RETURNS
  166. * Success: TRUE
  167. * Failure: FALSE
  168. */
  169. BOOL WINAPI IsUserAdmin(VOID)
  170. {
  171. SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY};
  172. HANDLE hToken;
  173. DWORD dwSize;
  174. PTOKEN_GROUPS lpGroups;
  175. PSID lpSid;
  176. DWORD i;
  177. BOOL bResult = FALSE;
  178. TRACE("\n");
  179. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  180. {
  181. return FALSE;
  182. }
  183. if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize))
  184. {
  185. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  186. {
  187. CloseHandle(hToken);
  188. return FALSE;
  189. }
  190. }
  191. lpGroups = MyMalloc(dwSize);
  192. if (lpGroups == NULL)
  193. {
  194. CloseHandle(hToken);
  195. return FALSE;
  196. }
  197. if (!GetTokenInformation(hToken, TokenGroups, lpGroups, dwSize, &dwSize))
  198. {
  199. MyFree(lpGroups);
  200. CloseHandle(hToken);
  201. return FALSE;
  202. }
  203. CloseHandle(hToken);
  204. if (!AllocateAndInitializeSid(&Authority, 2, SECURITY_BUILTIN_DOMAIN_RID,
  205. DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
  206. &lpSid))
  207. {
  208. MyFree(lpGroups);
  209. return FALSE;
  210. }
  211. for (i = 0; i < lpGroups->GroupCount; i++)
  212. {
  213. if (EqualSid(lpSid, &lpGroups->Groups[i].Sid))
  214. {
  215. bResult = TRUE;
  216. break;
  217. }
  218. }
  219. FreeSid(lpSid);
  220. MyFree(lpGroups);
  221. return bResult;
  222. }
  223. /**************************************************************************
  224. * MultiByteToUnicode [SETUPAPI.@]
  225. *
  226. * Converts a multi-byte string to a Unicode string.
  227. *
  228. * PARAMS
  229. * lpMultiByteStr [I] Multi-byte string to be converted
  230. * uCodePage [I] Code page
  231. *
  232. * RETURNS
  233. * Success: pointer to the converted Unicode string
  234. * Failure: NULL
  235. *
  236. * NOTE
  237. * Use MyFree to release the returned Unicode string.
  238. */
  239. LPWSTR WINAPI MultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
  240. {
  241. LPWSTR lpUnicodeStr;
  242. int nLength;
  243. TRACE("%s %d\n", debugstr_a(lpMultiByteStr), uCodePage);
  244. nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
  245. -1, NULL, 0);
  246. if (nLength == 0)
  247. return NULL;
  248. lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR));
  249. if (lpUnicodeStr == NULL)
  250. return NULL;
  251. if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
  252. nLength, lpUnicodeStr, nLength))
  253. {
  254. MyFree(lpUnicodeStr);
  255. return NULL;
  256. }
  257. return lpUnicodeStr;
  258. }
  259. /**************************************************************************
  260. * UnicodeToMultiByte [SETUPAPI.@]
  261. *
  262. * Converts a Unicode string to a multi-byte string.
  263. *
  264. * PARAMS
  265. * lpUnicodeStr [I] Unicode string to be converted
  266. * uCodePage [I] Code page
  267. *
  268. * RETURNS
  269. * Success: pointer to the converted multi-byte string
  270. * Failure: NULL
  271. *
  272. * NOTE
  273. * Use MyFree to release the returned multi-byte string.
  274. */
  275. LPSTR WINAPI UnicodeToMultiByte(LPCWSTR lpUnicodeStr, UINT uCodePage)
  276. {
  277. LPSTR lpMultiByteStr;
  278. int nLength;
  279. TRACE("%s %d\n", debugstr_w(lpUnicodeStr), uCodePage);
  280. nLength = WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
  281. NULL, 0, NULL, NULL);
  282. if (nLength == 0)
  283. return NULL;
  284. lpMultiByteStr = MyMalloc(nLength);
  285. if (lpMultiByteStr == NULL)
  286. return NULL;
  287. if (!WideCharToMultiByte(uCodePage, 0, lpUnicodeStr, -1,
  288. lpMultiByteStr, nLength, NULL, NULL))
  289. {
  290. MyFree(lpMultiByteStr);
  291. return NULL;
  292. }
  293. return lpMultiByteStr;
  294. }
  295. /**************************************************************************
  296. * DoesUserHavePrivilege [SETUPAPI.@]
  297. *
  298. * Check whether the current user has got a given privilege.
  299. *
  300. * PARAMS
  301. * lpPrivilegeName [I] Name of the privilege to be checked
  302. *
  303. * RETURNS
  304. * Success: TRUE
  305. * Failure: FALSE
  306. */
  307. BOOL WINAPI DoesUserHavePrivilege(LPCWSTR lpPrivilegeName)
  308. {
  309. HANDLE hToken;
  310. DWORD dwSize;
  311. PTOKEN_PRIVILEGES lpPrivileges;
  312. LUID PrivilegeLuid;
  313. DWORD i;
  314. BOOL bResult = FALSE;
  315. TRACE("%s\n", debugstr_w(lpPrivilegeName));
  316. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  317. return FALSE;
  318. if (!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize))
  319. {
  320. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  321. {
  322. CloseHandle(hToken);
  323. return FALSE;
  324. }
  325. }
  326. lpPrivileges = MyMalloc(dwSize);
  327. if (lpPrivileges == NULL)
  328. {
  329. CloseHandle(hToken);
  330. return FALSE;
  331. }
  332. if (!GetTokenInformation(hToken, TokenPrivileges, lpPrivileges, dwSize, &dwSize))
  333. {
  334. MyFree(lpPrivileges);
  335. CloseHandle(hToken);
  336. return FALSE;
  337. }
  338. CloseHandle(hToken);
  339. if (!LookupPrivilegeValueW(NULL, lpPrivilegeName, &PrivilegeLuid))
  340. {
  341. MyFree(lpPrivileges);
  342. return FALSE;
  343. }
  344. for (i = 0; i < lpPrivileges->PrivilegeCount; i++)
  345. {
  346. if (lpPrivileges->Privileges[i].Luid.HighPart == PrivilegeLuid.HighPart &&
  347. lpPrivileges->Privileges[i].Luid.LowPart == PrivilegeLuid.LowPart)
  348. {
  349. bResult = TRUE;
  350. }
  351. }
  352. MyFree(lpPrivileges);
  353. return bResult;
  354. }
  355. /**************************************************************************
  356. * EnablePrivilege [SETUPAPI.@]
  357. *
  358. * Enables or disables one of the current users privileges.
  359. *
  360. * PARAMS
  361. * lpPrivilegeName [I] Name of the privilege to be changed
  362. * bEnable [I] TRUE: Enables the privilege
  363. * FALSE: Disables the privilege
  364. *
  365. * RETURNS
  366. * Success: TRUE
  367. * Failure: FALSE
  368. */
  369. BOOL WINAPI EnablePrivilege(LPCWSTR lpPrivilegeName, BOOL bEnable)
  370. {
  371. TOKEN_PRIVILEGES Privileges;
  372. HANDLE hToken;
  373. BOOL bResult;
  374. TRACE("%s %s\n", debugstr_w(lpPrivilegeName), bEnable ? "TRUE" : "FALSE");
  375. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  376. return FALSE;
  377. Privileges.PrivilegeCount = 1;
  378. Privileges.Privileges[0].Attributes = (bEnable) ? SE_PRIVILEGE_ENABLED : 0;
  379. if (!LookupPrivilegeValueW(NULL, lpPrivilegeName,
  380. &Privileges.Privileges[0].Luid))
  381. {
  382. CloseHandle(hToken);
  383. return FALSE;
  384. }
  385. bResult = AdjustTokenPrivileges(hToken, FALSE, &Privileges, 0, NULL, NULL);
  386. CloseHandle(hToken);
  387. return bResult;
  388. }