ws2_32: Rewrite setsockopt to be more readable.
[wine/hacks.git] / dlls / setupapi / devinst.c
blobfbf6ded37d83a8c9940a70783b2945f70e9638fd
1 /*
2 * SetupAPI device installer
4 * Copyright 2000 Andreas Mohr for CodeWeavers
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winnt.h"
29 #include "winreg.h"
30 #include "winternl.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "winnls.h"
34 #include "setupapi.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
37 #include "cfgmgr32.h"
38 #include "initguid.h"
39 #include "winioctl.h"
40 #include "rpc.h"
41 #include "rpcdce.h"
43 #include "setupapi_private.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
48 /* Unicode constants */
49 static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0};
50 static const WCHAR Class[] = {'C','l','a','s','s',0};
51 static const WCHAR ClassInstall32[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
52 static const WCHAR NoDisplayClass[] = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
53 static const WCHAR NoInstallClass[] = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};
54 static const WCHAR NoUseClass[] = {'N','o','U','s','e','C','l','a','s','s',0};
55 static const WCHAR NtExtension[] = {'.','N','T',0};
56 static const WCHAR NtPlatformExtension[] = {'.','N','T','x','8','6',0};
57 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
58 static const WCHAR WinExtension[] = {'.','W','i','n',0};
60 /* Registry key and value names */
61 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
62 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
63 'C','o','n','t','r','o','l','\\',
64 'C','l','a','s','s',0};
66 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
67 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
68 'C','o','n','t','r','o','l','\\',
69 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
71 /* is used to identify if a DeviceInfoSet pointer is
72 valid or not */
73 #define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056
75 struct DeviceInfoSet
77 DWORD magic; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */
78 GUID ClassGuid;
79 HWND hwndParent;
82 /***********************************************************************
83 * SetupDiBuildClassInfoList (SETUPAPI.@)
85 * Returns a list of setup class GUIDs that identify the classes
86 * that are installed on a local machine.
88 * PARAMS
89 * Flags [I] control exclusion of classes from the list.
90 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
91 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
92 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
94 * RETURNS
95 * Success: TRUE.
96 * Failure: FALSE.
98 BOOL WINAPI SetupDiBuildClassInfoList(
99 DWORD Flags,
100 LPGUID ClassGuidList,
101 DWORD ClassGuidListSize,
102 PDWORD RequiredSize)
104 TRACE("\n");
105 return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
106 ClassGuidListSize, RequiredSize,
107 NULL, NULL);
110 /***********************************************************************
111 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
113 * Returns a list of setup class GUIDs that identify the classes
114 * that are installed on a local or remote macine.
116 * PARAMS
117 * Flags [I] control exclusion of classes from the list.
118 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
119 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
120 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
121 * MachineName [I] name of a remote machine.
122 * Reserved [I] must be NULL.
124 * RETURNS
125 * Success: TRUE.
126 * Failure: FALSE.
128 BOOL WINAPI SetupDiBuildClassInfoListExA(
129 DWORD Flags,
130 LPGUID ClassGuidList,
131 DWORD ClassGuidListSize,
132 PDWORD RequiredSize,
133 LPCSTR MachineName,
134 PVOID Reserved)
136 LPWSTR MachineNameW = NULL;
137 BOOL bResult;
139 TRACE("\n");
141 if (MachineName)
143 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
144 if (MachineNameW == NULL) return FALSE;
147 bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
148 ClassGuidListSize, RequiredSize,
149 MachineNameW, Reserved);
151 MyFree(MachineNameW);
153 return bResult;
156 /***********************************************************************
157 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
159 * Returns a list of setup class GUIDs that identify the classes
160 * that are installed on a local or remote macine.
162 * PARAMS
163 * Flags [I] control exclusion of classes from the list.
164 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
165 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
166 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
167 * MachineName [I] name of a remote machine.
168 * Reserved [I] must be NULL.
170 * RETURNS
171 * Success: TRUE.
172 * Failure: FALSE.
174 BOOL WINAPI SetupDiBuildClassInfoListExW(
175 DWORD Flags,
176 LPGUID ClassGuidList,
177 DWORD ClassGuidListSize,
178 PDWORD RequiredSize,
179 LPCWSTR MachineName,
180 PVOID Reserved)
182 WCHAR szKeyName[40];
183 HKEY hClassesKey;
184 HKEY hClassKey;
185 DWORD dwLength;
186 DWORD dwIndex;
187 LONG lError;
188 DWORD dwGuidListIndex = 0;
190 TRACE("\n");
192 if (RequiredSize != NULL)
193 *RequiredSize = 0;
195 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
196 KEY_ALL_ACCESS,
197 DIOCR_INSTALLER,
198 MachineName,
199 Reserved);
200 if (hClassesKey == INVALID_HANDLE_VALUE)
202 return FALSE;
205 for (dwIndex = 0; ; dwIndex++)
207 dwLength = 40;
208 lError = RegEnumKeyExW(hClassesKey,
209 dwIndex,
210 szKeyName,
211 &dwLength,
212 NULL,
213 NULL,
214 NULL,
215 NULL);
216 TRACE("RegEnumKeyExW() returns %d\n", lError);
217 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
219 TRACE("Key name: %p\n", szKeyName);
221 if (RegOpenKeyExW(hClassesKey,
222 szKeyName,
224 KEY_ALL_ACCESS,
225 &hClassKey))
227 RegCloseKey(hClassesKey);
228 return FALSE;
231 if (!RegQueryValueExW(hClassKey,
232 NoUseClass,
233 NULL,
234 NULL,
235 NULL,
236 NULL))
238 TRACE("'NoUseClass' value found!\n");
239 RegCloseKey(hClassKey);
240 continue;
243 if ((Flags & DIBCI_NOINSTALLCLASS) &&
244 (!RegQueryValueExW(hClassKey,
245 NoInstallClass,
246 NULL,
247 NULL,
248 NULL,
249 NULL)))
251 TRACE("'NoInstallClass' value found!\n");
252 RegCloseKey(hClassKey);
253 continue;
256 if ((Flags & DIBCI_NODISPLAYCLASS) &&
257 (!RegQueryValueExW(hClassKey,
258 NoDisplayClass,
259 NULL,
260 NULL,
261 NULL,
262 NULL)))
264 TRACE("'NoDisplayClass' value found!\n");
265 RegCloseKey(hClassKey);
266 continue;
269 RegCloseKey(hClassKey);
271 TRACE("Guid: %p\n", szKeyName);
272 if (dwGuidListIndex < ClassGuidListSize)
274 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
276 szKeyName[37] = 0;
278 TRACE("Guid: %p\n", &szKeyName[1]);
280 UuidFromStringW(&szKeyName[1],
281 &ClassGuidList[dwGuidListIndex]);
284 dwGuidListIndex++;
287 if (lError != ERROR_SUCCESS)
288 break;
291 RegCloseKey(hClassesKey);
293 if (RequiredSize != NULL)
294 *RequiredSize = dwGuidListIndex;
296 if (ClassGuidListSize < dwGuidListIndex)
298 SetLastError(ERROR_INSUFFICIENT_BUFFER);
299 return FALSE;
302 return TRUE;
305 /***********************************************************************
306 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
308 BOOL WINAPI SetupDiClassGuidsFromNameA(
309 LPCSTR ClassName,
310 LPGUID ClassGuidList,
311 DWORD ClassGuidListSize,
312 PDWORD RequiredSize)
314 return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
315 ClassGuidListSize, RequiredSize,
316 NULL, NULL);
319 /***********************************************************************
320 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
322 BOOL WINAPI SetupDiClassGuidsFromNameW(
323 LPCWSTR ClassName,
324 LPGUID ClassGuidList,
325 DWORD ClassGuidListSize,
326 PDWORD RequiredSize)
328 return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
329 ClassGuidListSize, RequiredSize,
330 NULL, NULL);
333 /***********************************************************************
334 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
336 BOOL WINAPI SetupDiClassGuidsFromNameExA(
337 LPCSTR ClassName,
338 LPGUID ClassGuidList,
339 DWORD ClassGuidListSize,
340 PDWORD RequiredSize,
341 LPCSTR MachineName,
342 PVOID Reserved)
344 LPWSTR ClassNameW = NULL;
345 LPWSTR MachineNameW = NULL;
346 BOOL bResult;
348 FIXME("\n");
350 ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);
351 if (ClassNameW == NULL)
352 return FALSE;
354 if (MachineName)
356 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
357 if (MachineNameW == NULL)
359 MyFree(ClassNameW);
360 return FALSE;
364 bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
365 ClassGuidListSize, RequiredSize,
366 MachineNameW, Reserved);
368 MyFree(MachineNameW);
369 MyFree(ClassNameW);
371 return bResult;
374 /***********************************************************************
375 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
377 BOOL WINAPI SetupDiClassGuidsFromNameExW(
378 LPCWSTR ClassName,
379 LPGUID ClassGuidList,
380 DWORD ClassGuidListSize,
381 PDWORD RequiredSize,
382 LPCWSTR MachineName,
383 PVOID Reserved)
385 WCHAR szKeyName[40];
386 WCHAR szClassName[256];
387 HKEY hClassesKey;
388 HKEY hClassKey;
389 DWORD dwLength;
390 DWORD dwIndex;
391 LONG lError;
392 DWORD dwGuidListIndex = 0;
394 if (RequiredSize != NULL)
395 *RequiredSize = 0;
397 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
398 KEY_ALL_ACCESS,
399 DIOCR_INSTALLER,
400 MachineName,
401 Reserved);
402 if (hClassesKey == INVALID_HANDLE_VALUE)
404 return FALSE;
407 for (dwIndex = 0; ; dwIndex++)
409 dwLength = 40;
410 lError = RegEnumKeyExW(hClassesKey,
411 dwIndex,
412 szKeyName,
413 &dwLength,
414 NULL,
415 NULL,
416 NULL,
417 NULL);
418 TRACE("RegEnumKeyExW() returns %d\n", lError);
419 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
421 TRACE("Key name: %p\n", szKeyName);
423 if (RegOpenKeyExW(hClassesKey,
424 szKeyName,
426 KEY_ALL_ACCESS,
427 &hClassKey))
429 RegCloseKey(hClassesKey);
430 return FALSE;
433 dwLength = 256 * sizeof(WCHAR);
434 if (!RegQueryValueExW(hClassKey,
435 Class,
436 NULL,
437 NULL,
438 (LPBYTE)szClassName,
439 &dwLength))
441 TRACE("Class name: %p\n", szClassName);
443 if (strcmpiW(szClassName, ClassName) == 0)
445 TRACE("Found matching class name\n");
447 TRACE("Guid: %p\n", szKeyName);
448 if (dwGuidListIndex < ClassGuidListSize)
450 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
452 szKeyName[37] = 0;
454 TRACE("Guid: %p\n", &szKeyName[1]);
456 UuidFromStringW(&szKeyName[1],
457 &ClassGuidList[dwGuidListIndex]);
460 dwGuidListIndex++;
464 RegCloseKey(hClassKey);
467 if (lError != ERROR_SUCCESS)
468 break;
471 RegCloseKey(hClassesKey);
473 if (RequiredSize != NULL)
474 *RequiredSize = dwGuidListIndex;
476 if (ClassGuidListSize < dwGuidListIndex)
478 SetLastError(ERROR_INSUFFICIENT_BUFFER);
479 return FALSE;
482 return TRUE;
485 /***********************************************************************
486 * SetupDiClassNameFromGuidA (SETUPAPI.@)
488 BOOL WINAPI SetupDiClassNameFromGuidA(
489 const GUID* ClassGuid,
490 PSTR ClassName,
491 DWORD ClassNameSize,
492 PDWORD RequiredSize)
494 return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
495 ClassNameSize, RequiredSize,
496 NULL, NULL);
499 /***********************************************************************
500 * SetupDiClassNameFromGuidW (SETUPAPI.@)
502 BOOL WINAPI SetupDiClassNameFromGuidW(
503 const GUID* ClassGuid,
504 PWSTR ClassName,
505 DWORD ClassNameSize,
506 PDWORD RequiredSize)
508 return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
509 ClassNameSize, RequiredSize,
510 NULL, NULL);
513 /***********************************************************************
514 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
516 BOOL WINAPI SetupDiClassNameFromGuidExA(
517 const GUID* ClassGuid,
518 PSTR ClassName,
519 DWORD ClassNameSize,
520 PDWORD RequiredSize,
521 PCSTR MachineName,
522 PVOID Reserved)
524 WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
525 LPWSTR MachineNameW = NULL;
526 BOOL ret;
528 if (MachineName)
529 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
530 ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
531 NULL, MachineNameW, Reserved);
532 if (ret)
534 int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
535 ClassNameSize, NULL, NULL);
537 if (!ClassNameSize && RequiredSize)
538 *RequiredSize = len;
540 MyFree(MachineNameW);
541 return ret;
544 /***********************************************************************
545 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
547 BOOL WINAPI SetupDiClassNameFromGuidExW(
548 const GUID* ClassGuid,
549 PWSTR ClassName,
550 DWORD ClassNameSize,
551 PDWORD RequiredSize,
552 PCWSTR MachineName,
553 PVOID Reserved)
555 HKEY hKey;
556 DWORD dwLength;
558 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
559 KEY_ALL_ACCESS,
560 DIOCR_INSTALLER,
561 MachineName,
562 Reserved);
563 if (hKey == INVALID_HANDLE_VALUE)
565 return FALSE;
568 if (RequiredSize != NULL)
570 dwLength = 0;
571 if (RegQueryValueExW(hKey,
572 Class,
573 NULL,
574 NULL,
575 NULL,
576 &dwLength))
578 RegCloseKey(hKey);
579 return FALSE;
582 *RequiredSize = dwLength / sizeof(WCHAR);
585 dwLength = ClassNameSize * sizeof(WCHAR);
586 if (RegQueryValueExW(hKey,
587 Class,
588 NULL,
589 NULL,
590 (LPBYTE)ClassName,
591 &dwLength))
593 RegCloseKey(hKey);
594 return FALSE;
597 RegCloseKey(hKey);
599 return TRUE;
602 /***********************************************************************
603 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
605 HDEVINFO WINAPI
606 SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
607 HWND hwndParent)
609 return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
612 /***********************************************************************
613 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
615 HDEVINFO WINAPI
616 SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
617 HWND hwndParent,
618 PCSTR MachineName,
619 PVOID Reserved)
621 LPWSTR MachineNameW = NULL;
622 HDEVINFO hDevInfo;
624 TRACE("\n");
626 if (MachineName)
628 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
629 if (MachineNameW == NULL)
630 return (HDEVINFO)INVALID_HANDLE_VALUE;
633 hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
634 MachineNameW, Reserved);
636 MyFree(MachineNameW);
638 return hDevInfo;
641 /***********************************************************************
642 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
644 * Create an empty DeviceInfoSet list.
646 * PARAMS
647 * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated
648 * with this list.
649 * hwndParent [I] hwnd needed for interface related actions.
650 * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
651 * local regestry will be used.
652 * Reserved [I] must be NULL
654 * RETURNS
655 * Success: empty list.
656 * Failure: INVALID_HANDLE_VALUE.
658 HDEVINFO WINAPI
659 SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
660 HWND hwndParent,
661 PCWSTR MachineName,
662 PVOID Reserved)
664 struct DeviceInfoSet *list = NULL;
665 DWORD size = sizeof(struct DeviceInfoSet);
667 TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
668 debugstr_w(MachineName), Reserved);
670 if (MachineName != NULL)
672 FIXME("remote support is not implemented\n");
673 SetLastError(ERROR_INVALID_MACHINENAME);
674 return (HDEVINFO)INVALID_HANDLE_VALUE;
677 if (Reserved != NULL)
679 SetLastError(ERROR_INVALID_PARAMETER);
680 return (HDEVINFO)INVALID_HANDLE_VALUE;
683 list = HeapAlloc(GetProcessHeap(), 0, size);
684 if (!list)
686 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
687 return (HDEVINFO)INVALID_HANDLE_VALUE;
690 list->magic = SETUP_DEVICE_INFO_SET_MAGIC;
691 list->hwndParent = hwndParent;
692 memcpy(&list->ClassGuid,
693 ClassGuid ? ClassGuid : &GUID_NULL,
694 sizeof(list->ClassGuid));
696 return (HDEVINFO)list;
699 /***********************************************************************
700 * SetupDiCreateDeviceInfoA (SETUPAPI.@)
702 BOOL WINAPI SetupDiCreateDeviceInfoA(
703 HDEVINFO DeviceInfoSet,
704 PCSTR DeviceName,
705 CONST GUID *ClassGuid,
706 PCSTR DeviceDescription,
707 HWND hwndParent,
708 DWORD CreationFlags,
709 PSP_DEVINFO_DATA DeviceInfoData)
711 BOOL ret = FALSE;
712 LPWSTR DeviceNameW = NULL;
713 LPWSTR DeviceDescriptionW = NULL;
715 if (DeviceName)
717 DeviceNameW = MultiByteToUnicode(DeviceName, CP_ACP);
718 if (DeviceNameW == NULL) return FALSE;
720 if (DeviceDescription)
722 DeviceDescriptionW = MultiByteToUnicode(DeviceDescription, CP_ACP);
723 if (DeviceDescriptionW == NULL)
725 MyFree(DeviceNameW);
726 return FALSE;
730 ret = SetupDiCreateDeviceInfoW(DeviceInfoSet, DeviceNameW, ClassGuid, DeviceDescriptionW,
731 hwndParent, CreationFlags, DeviceInfoData);
733 MyFree(DeviceNameW);
734 MyFree(DeviceDescriptionW);
736 return ret;
739 /***********************************************************************
740 * SetupDiCreateDeviceInfoW (SETUPAPI.@)
742 BOOL WINAPI SetupDiCreateDeviceInfoW(
743 HDEVINFO DeviceInfoSet,
744 PCWSTR DeviceName,
745 CONST GUID *ClassGuid,
746 PCWSTR DeviceDescription,
747 HWND hwndParent,
748 DWORD CreationFlags,
749 PSP_DEVINFO_DATA DeviceInfoData)
751 TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet, debugstr_w(DeviceName),
752 debugstr_guid(ClassGuid), debugstr_w(DeviceDescription),
753 hwndParent, CreationFlags, DeviceInfoData);
755 FIXME("stub\n");
757 return FALSE;
760 /***********************************************************************
761 * SetupDiEnumDeviceInfo (SETUPAPI.@)
763 BOOL WINAPI SetupDiEnumDeviceInfo(
764 HDEVINFO devinfo,
765 DWORD index,
766 PSP_DEVINFO_DATA info)
768 FIXME("%p %d %p\n", devinfo, index, info);
770 if(info==NULL)
771 return FALSE;
772 if(info->cbSize < sizeof(*info))
773 return FALSE;
775 return FALSE;
778 /***********************************************************************
779 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
781 BOOL WINAPI SetupDiGetActualSectionToInstallA(
782 HINF InfHandle,
783 PCSTR InfSectionName,
784 PSTR InfSectionWithExt,
785 DWORD InfSectionWithExtSize,
786 PDWORD RequiredSize,
787 PSTR *Extension)
789 FIXME("\n");
790 return FALSE;
793 /***********************************************************************
794 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
796 BOOL WINAPI SetupDiGetActualSectionToInstallW(
797 HINF InfHandle,
798 PCWSTR InfSectionName,
799 PWSTR InfSectionWithExt,
800 DWORD InfSectionWithExtSize,
801 PDWORD RequiredSize,
802 PWSTR *Extension)
804 WCHAR szBuffer[MAX_PATH];
805 DWORD dwLength;
806 DWORD dwFullLength;
807 LONG lLineCount = -1;
809 lstrcpyW(szBuffer, InfSectionName);
810 dwLength = lstrlenW(szBuffer);
812 if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
814 /* Test section name with '.NTx86' extension */
815 lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
816 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
818 if (lLineCount == -1)
820 /* Test section name with '.NT' extension */
821 lstrcpyW(&szBuffer[dwLength], NtExtension);
822 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
825 else
827 /* Test section name with '.Win' extension */
828 lstrcpyW(&szBuffer[dwLength], WinExtension);
829 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
832 if (lLineCount == -1)
834 /* Test section name without extension */
835 szBuffer[dwLength] = 0;
836 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
839 if (lLineCount == -1)
841 SetLastError(ERROR_INVALID_PARAMETER);
842 return FALSE;
845 dwFullLength = lstrlenW(szBuffer);
847 if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
849 if (InfSectionWithExtSize < (dwFullLength + 1))
851 SetLastError(ERROR_INSUFFICIENT_BUFFER);
852 return FALSE;
855 lstrcpyW(InfSectionWithExt, szBuffer);
856 if (Extension != NULL)
858 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
862 if (RequiredSize != NULL)
864 *RequiredSize = dwFullLength + 1;
867 return TRUE;
870 /***********************************************************************
871 * SetupDiGetClassDescriptionA (SETUPAPI.@)
873 BOOL WINAPI SetupDiGetClassDescriptionA(
874 const GUID* ClassGuid,
875 PSTR ClassDescription,
876 DWORD ClassDescriptionSize,
877 PDWORD RequiredSize)
879 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
880 ClassDescriptionSize,
881 RequiredSize, NULL, NULL);
884 /***********************************************************************
885 * SetupDiGetClassDescriptionW (SETUPAPI.@)
887 BOOL WINAPI SetupDiGetClassDescriptionW(
888 const GUID* ClassGuid,
889 PWSTR ClassDescription,
890 DWORD ClassDescriptionSize,
891 PDWORD RequiredSize)
893 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
894 ClassDescriptionSize,
895 RequiredSize, NULL, NULL);
898 /***********************************************************************
899 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
901 BOOL WINAPI SetupDiGetClassDescriptionExA(
902 const GUID* ClassGuid,
903 PSTR ClassDescription,
904 DWORD ClassDescriptionSize,
905 PDWORD RequiredSize,
906 PCSTR MachineName,
907 PVOID Reserved)
909 FIXME("\n");
910 return FALSE;
913 /***********************************************************************
914 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
916 BOOL WINAPI SetupDiGetClassDescriptionExW(
917 const GUID* ClassGuid,
918 PWSTR ClassDescription,
919 DWORD ClassDescriptionSize,
920 PDWORD RequiredSize,
921 PCWSTR MachineName,
922 PVOID Reserved)
924 HKEY hKey;
925 DWORD dwLength;
927 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
928 KEY_ALL_ACCESS,
929 DIOCR_INSTALLER,
930 MachineName,
931 Reserved);
932 if (hKey == INVALID_HANDLE_VALUE)
934 WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError());
935 return FALSE;
938 if (RequiredSize != NULL)
940 dwLength = 0;
941 if (RegQueryValueExW(hKey,
942 NULL,
943 NULL,
944 NULL,
945 NULL,
946 &dwLength))
948 RegCloseKey(hKey);
949 return FALSE;
952 *RequiredSize = dwLength / sizeof(WCHAR);
955 dwLength = ClassDescriptionSize * sizeof(WCHAR);
956 if (RegQueryValueExW(hKey,
957 NULL,
958 NULL,
959 NULL,
960 (LPBYTE)ClassDescription,
961 &dwLength))
963 RegCloseKey(hKey);
964 return FALSE;
967 RegCloseKey(hKey);
969 return TRUE;
972 /***********************************************************************
973 * SetupDiGetClassDevsA (SETUPAPI.@)
975 HDEVINFO WINAPI SetupDiGetClassDevsA(
976 CONST GUID *class,
977 LPCSTR enumstr,
978 HWND parent,
979 DWORD flags)
981 HDEVINFO ret;
982 LPWSTR enumstrW = NULL;
984 if (enumstr)
986 int len = MultiByteToWideChar(CP_ACP, 0, enumstr, -1, NULL, 0);
987 enumstrW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
988 if (!enumstrW)
990 ret = (HDEVINFO)INVALID_HANDLE_VALUE;
991 goto end;
993 MultiByteToWideChar(CP_ACP, 0, enumstr, -1, enumstrW, len);
995 ret = SetupDiGetClassDevsW(class, enumstrW, parent, flags);
996 HeapFree(GetProcessHeap(), 0, enumstrW);
998 end:
999 return ret;
1002 /***********************************************************************
1003 * SetupDiGetClassDevsW (SETUPAPI.@)
1005 HDEVINFO WINAPI SetupDiGetClassDevsW(
1006 CONST GUID *class,
1007 LPCWSTR enumstr,
1008 HWND parent,
1009 DWORD flags)
1011 HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;
1013 TRACE("%s %s %p 0x%08x\n", debugstr_guid(class), debugstr_w(enumstr),
1014 parent, flags);
1016 if(flags & DIGCF_DEVICEINTERFACE)
1018 if(!class)
1019 SetLastError(ERROR_INVALID_PARAMETER);
1020 else
1022 /* WinXP always succeeds, returns empty list for unknown classes */
1023 FIXME(": returning empty list\n");
1024 ret = SetupDiCreateDeviceInfoList(class, parent);
1027 else if (enumstr)
1028 FIXME(": unimplemented for enumerator strings (%s)\n",
1029 debugstr_w(enumstr));
1030 else if (flags & DIGCF_ALLCLASSES)
1031 FIXME(": unimplemented for DIGCF_ALLCLASSES\n");
1032 else
1034 FIXME("(%s): stub\n", debugstr_guid(class));
1036 return ret;
1039 /***********************************************************************
1040 * SetupDiGetClassDevsExW (SETUPAPI.@)
1042 HDEVINFO WINAPI SetupDiGetClassDevsExW(
1043 CONST GUID *class,
1044 PCWSTR enumstr,
1045 HWND parent,
1046 DWORD flags,
1047 HDEVINFO deviceset,
1048 PCWSTR machine,
1049 PVOID reserved)
1051 FIXME("stub\n");
1052 return FALSE;
1055 /***********************************************************************
1056 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
1058 BOOL WINAPI SetupDiEnumDeviceInterfaces(
1059 HDEVINFO devinfo,
1060 PSP_DEVINFO_DATA DeviceInfoData,
1061 CONST GUID * InterfaceClassGuid,
1062 DWORD MemberIndex,
1063 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1065 BOOL ret = FALSE;
1067 FIXME("%p, %p, %s, 0x%08x, %p\n", devinfo, DeviceInfoData,
1068 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
1070 if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE)
1072 struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
1073 if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
1074 SetLastError(ERROR_NO_MORE_ITEMS);
1075 else
1076 SetLastError(ERROR_INVALID_HANDLE);
1078 else
1079 SetLastError(ERROR_INVALID_HANDLE);
1080 return ret;
1083 /***********************************************************************
1084 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
1086 * Destroy a DeviceInfoList and free all used memory of the list.
1088 * PARAMS
1089 * devinfo [I] DeviceInfoList pointer to list to destroy
1091 * RETURNS
1092 * Success: non zero value.
1093 * Failure: zero value.
1095 BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
1097 BOOL ret = FALSE;
1099 TRACE("%p\n", devinfo);
1100 if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE)
1102 struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
1104 if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
1106 HeapFree(GetProcessHeap(), 0, list);
1107 ret = TRUE;
1111 if (ret == FALSE)
1112 SetLastError(ERROR_INVALID_HANDLE);
1114 return ret;
1117 /***********************************************************************
1118 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1120 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
1121 HDEVINFO DeviceInfoSet,
1122 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1123 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
1124 DWORD DeviceInterfaceDetailDataSize,
1125 PDWORD RequiredSize,
1126 PSP_DEVINFO_DATA DeviceInfoData)
1128 BOOL ret = FALSE;
1130 FIXME("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
1131 DeviceInterfaceData, DeviceInterfaceDetailData,
1132 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1134 SetLastError(ERROR_INVALID_HANDLE);
1135 return ret;
1138 /***********************************************************************
1139 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1141 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
1142 HDEVINFO DeviceInfoSet,
1143 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1144 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
1145 DWORD DeviceInterfaceDetailDataSize,
1146 PDWORD RequiredSize,
1147 PSP_DEVINFO_DATA DeviceInfoData)
1149 FIXME("(%p, %p, %p, %d, %p, %p): stub\n", DeviceInfoSet,
1150 DeviceInterfaceData, DeviceInterfaceDetailData,
1151 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
1152 return FALSE;
1155 /***********************************************************************
1156 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1158 BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
1159 HDEVINFO devinfo,
1160 PSP_DEVINFO_DATA DeviceInfoData,
1161 DWORD Property,
1162 PDWORD PropertyRegDataType,
1163 PBYTE PropertyBuffer,
1164 DWORD PropertyBufferSize,
1165 PDWORD RequiredSize)
1167 FIXME("%04x %p %d %p %p %d %p\n", (DWORD)devinfo, DeviceInfoData,
1168 Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
1169 RequiredSize);
1170 return FALSE;
1173 /***********************************************************************
1174 * SetupDiInstallClassA (SETUPAPI.@)
1176 BOOL WINAPI SetupDiInstallClassA(
1177 HWND hwndParent,
1178 PCSTR InfFileName,
1179 DWORD Flags,
1180 HSPFILEQ FileQueue)
1182 UNICODE_STRING FileNameW;
1183 BOOL Result;
1185 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
1187 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1188 return FALSE;
1191 Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
1193 RtlFreeUnicodeString(&FileNameW);
1195 return Result;
1198 static HKEY CreateClassKey(HINF hInf)
1200 WCHAR FullBuffer[MAX_PATH];
1201 WCHAR Buffer[MAX_PATH];
1202 DWORD RequiredSize;
1203 HKEY hClassKey;
1205 if (!SetupGetLineTextW(NULL,
1206 hInf,
1207 Version,
1208 ClassGUID,
1209 Buffer,
1210 MAX_PATH,
1211 &RequiredSize))
1213 return INVALID_HANDLE_VALUE;
1216 lstrcpyW(FullBuffer, ControlClass);
1217 lstrcatW(FullBuffer, Buffer);
1219 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1220 FullBuffer,
1222 KEY_ALL_ACCESS,
1223 &hClassKey))
1225 if (!SetupGetLineTextW(NULL,
1226 hInf,
1227 Version,
1228 Class,
1229 Buffer,
1230 MAX_PATH,
1231 &RequiredSize))
1233 return INVALID_HANDLE_VALUE;
1236 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
1237 FullBuffer,
1239 NULL,
1240 REG_OPTION_NON_VOLATILE,
1241 KEY_ALL_ACCESS,
1242 NULL,
1243 &hClassKey,
1244 NULL))
1246 return INVALID_HANDLE_VALUE;
1251 if (RegSetValueExW(hClassKey,
1252 Class,
1254 REG_SZ,
1255 (LPBYTE)Buffer,
1256 RequiredSize * sizeof(WCHAR)))
1258 RegCloseKey(hClassKey);
1259 RegDeleteKeyW(HKEY_LOCAL_MACHINE,
1260 FullBuffer);
1261 return INVALID_HANDLE_VALUE;
1264 return hClassKey;
1267 /***********************************************************************
1268 * SetupDiInstallClassW (SETUPAPI.@)
1270 BOOL WINAPI SetupDiInstallClassW(
1271 HWND hwndParent,
1272 PCWSTR InfFileName,
1273 DWORD Flags,
1274 HSPFILEQ FileQueue)
1276 WCHAR SectionName[MAX_PATH];
1277 DWORD SectionNameLength = 0;
1278 HINF hInf;
1279 BOOL bFileQueueCreated = FALSE;
1280 HKEY hClassKey;
1283 FIXME("\n");
1285 if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
1287 SetLastError(ERROR_INVALID_PARAMETER);
1288 return FALSE;
1291 /* Open the .inf file */
1292 hInf = SetupOpenInfFileW(InfFileName,
1293 NULL,
1294 INF_STYLE_WIN4,
1295 NULL);
1296 if (hInf == INVALID_HANDLE_VALUE)
1299 return FALSE;
1302 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1303 hClassKey = CreateClassKey(hInf);
1304 if (hClassKey == INVALID_HANDLE_VALUE)
1306 SetupCloseInfFile(hInf);
1307 return FALSE;
1311 /* Try to append a layout file */
1312 #if 0
1313 SetupOpenAppendInfFileW(NULL, hInf, NULL);
1314 #endif
1316 /* Retrieve the actual section name */
1317 SetupDiGetActualSectionToInstallW(hInf,
1318 ClassInstall32,
1319 SectionName,
1320 MAX_PATH,
1321 &SectionNameLength,
1322 NULL);
1324 #if 0
1325 if (!(Flags & DI_NOVCP))
1327 FileQueue = SetupOpenFileQueue();
1328 if (FileQueue == INVALID_HANDLE_VALUE)
1330 SetupCloseInfFile(hInf);
1331 return FALSE;
1334 bFileQueueCreated = TRUE;
1337 #endif
1339 SetupInstallFromInfSectionW(NULL,
1340 hInf,
1341 SectionName,
1342 SPINST_REGISTRY,
1343 hClassKey,
1344 NULL,
1346 NULL,
1347 NULL,
1348 INVALID_HANDLE_VALUE,
1349 NULL);
1351 /* FIXME: More code! */
1353 if (bFileQueueCreated)
1354 SetupCloseFileQueue(FileQueue);
1356 SetupCloseInfFile(hInf);
1358 return TRUE;
1362 /***********************************************************************
1363 * SetupDiOpenClassRegKey (SETUPAPI.@)
1365 HKEY WINAPI SetupDiOpenClassRegKey(
1366 const GUID* ClassGuid,
1367 REGSAM samDesired)
1369 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1370 DIOCR_INSTALLER, NULL, NULL);
1374 /***********************************************************************
1375 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1377 HKEY WINAPI SetupDiOpenClassRegKeyExA(
1378 const GUID* ClassGuid,
1379 REGSAM samDesired,
1380 DWORD Flags,
1381 PCSTR MachineName,
1382 PVOID Reserved)
1384 PWSTR MachineNameW = NULL;
1385 HKEY hKey;
1387 TRACE("\n");
1389 if (MachineName)
1391 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
1392 if (MachineNameW == NULL)
1393 return INVALID_HANDLE_VALUE;
1396 hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1397 Flags, MachineNameW, Reserved);
1399 MyFree(MachineNameW);
1401 return hKey;
1405 /***********************************************************************
1406 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1408 HKEY WINAPI SetupDiOpenClassRegKeyExW(
1409 const GUID* ClassGuid,
1410 REGSAM samDesired,
1411 DWORD Flags,
1412 PCWSTR MachineName,
1413 PVOID Reserved)
1415 LPWSTR lpGuidString;
1416 WCHAR bracedGuidString[39];
1417 HKEY hClassesKey;
1418 HKEY hClassKey;
1419 LPCWSTR lpKeyName;
1421 if (MachineName != NULL)
1423 FIXME("Remote access not supported yet!\n");
1424 return INVALID_HANDLE_VALUE;
1427 if (Flags == DIOCR_INSTALLER)
1429 lpKeyName = ControlClass;
1431 else if (Flags == DIOCR_INTERFACE)
1433 lpKeyName = DeviceClasses;
1435 else
1437 ERR("Invalid Flags parameter!\n");
1438 SetLastError(ERROR_INVALID_PARAMETER);
1439 return INVALID_HANDLE_VALUE;
1442 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1443 lpKeyName,
1445 KEY_ALL_ACCESS,
1446 &hClassesKey))
1448 return INVALID_HANDLE_VALUE;
1451 if (ClassGuid == NULL)
1452 return hClassesKey;
1454 if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
1456 RegCloseKey(hClassesKey);
1457 return INVALID_HANDLE_VALUE;
1459 bracedGuidString[0] = '{';
1460 memcpy(&bracedGuidString[1], lpGuidString, 36*sizeof(WCHAR));
1461 bracedGuidString[37] = '}';
1462 bracedGuidString[38] = 0;
1463 RpcStringFreeW(&lpGuidString);
1465 if (RegOpenKeyExW(hClassesKey,
1466 bracedGuidString,
1468 KEY_ALL_ACCESS,
1469 &hClassKey))
1471 RegCloseKey(hClassesKey);
1472 return INVALID_HANDLE_VALUE;
1475 RegCloseKey(hClassesKey);
1477 return hClassKey;
1480 /***********************************************************************
1481 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1483 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
1484 HDEVINFO DeviceInfoSet,
1485 PCWSTR DevicePath,
1486 DWORD OpenFlags,
1487 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1489 FIXME("%p %s %08x %p\n",
1490 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
1491 return FALSE;
1494 /***********************************************************************
1495 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1497 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
1498 HDEVINFO DeviceInfoSet,
1499 PCSTR DevicePath,
1500 DWORD OpenFlags,
1501 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1503 FIXME("%p %s %08x %p\n", DeviceInfoSet,
1504 debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
1505 return FALSE;
1508 /***********************************************************************
1509 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1511 BOOL WINAPI SetupDiSetClassInstallParamsA(
1512 HDEVINFO DeviceInfoSet,
1513 PSP_DEVINFO_DATA DeviceInfoData,
1514 PSP_CLASSINSTALL_HEADER ClassInstallParams,
1515 DWORD ClassInstallParamsSize)
1517 FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData,
1518 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
1519 return FALSE;
1522 /***********************************************************************
1523 * SetupDiCallClassInstaller (SETUPAPI.@)
1525 BOOL WINAPI SetupDiCallClassInstaller(
1526 DI_FUNCTION InstallFunction,
1527 HDEVINFO DeviceInfoSet,
1528 PSP_DEVINFO_DATA DeviceInfoData)
1530 FIXME("%d %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
1531 return FALSE;
1534 /***********************************************************************
1535 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1537 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
1538 HDEVINFO DeviceInfoSet,
1539 PSP_DEVINFO_DATA DeviceInfoData,
1540 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
1542 FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
1543 return FALSE;
1546 /***********************************************************************
1547 * SetupDiOpenDevRegKey (SETUPAPI.@)
1549 HKEY WINAPI SetupDiOpenDevRegKey(
1550 HDEVINFO DeviceInfoSet,
1551 PSP_DEVINFO_DATA DeviceInfoData,
1552 DWORD Scope,
1553 DWORD HwProfile,
1554 DWORD KeyType,
1555 REGSAM samDesired)
1557 FIXME("%p %p %d %d %d %x\n", DeviceInfoSet, DeviceInfoData,
1558 Scope, HwProfile, KeyType, samDesired);
1559 return INVALID_HANDLE_VALUE;