Changes in crossover-wine-src-6.1.0 except for configure
[wine/hacks.git] / dlls / setupapi / devinst.c
blob7fd4ba01791d6dfb6b4a550e9823d8a93639b13b
1 /*
2 * SetupAPI device installer
4 * Copyright 2000 Andreas Mohr for CodeWeavers
5 * Copyright 2004 Aric Stewart for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "config.h"
23 #include "wine/port.h"
25 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnt.h"
30 #include "winreg.h"
31 #include "winternl.h"
32 #include "wingdi.h"
33 #include "winuser.h"
34 #include "winnls.h"
35 #include "setupapi.h"
36 #include "wine/debug.h"
37 #include "wine/unicode.h"
38 #include "cfgmgr32.h"
39 #include "initguid.h"
40 #include "winioctl.h"
41 #include "rpc.h"
42 #include "rpcdce.h"
43 #include "dbt.h"
44 #include "setupapi_private.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
49 /* Unicode constants */
50 static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0};
51 static const WCHAR Class[] = {'C','l','a','s','s',0};
52 static const WCHAR ClassInstall32[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
53 static const WCHAR NoDisplayClass[] = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
54 static const WCHAR NoInstallClass[] = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};
55 static const WCHAR NoUseClass[] = {'N','o','U','s','e','C','l','a','s','s',0};
56 static const WCHAR NtExtension[] = {'.','N','T',0};
57 static const WCHAR NtPlatformExtension[] = {'.','N','T','x','8','6',0};
58 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
59 static const WCHAR WinExtension[] = {'.','W','i','n',0};
61 /* Registry key and value names */
62 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
63 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
64 'C','o','n','t','r','o','l','\\',
65 'C','l','a','s','s',0};
67 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
68 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
69 'C','o','n','t','r','o','l','\\',
70 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
72 /* is used to identify if a DeviceInfoSet pointer is
73 valid or not */
74 #define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056
76 struct DeviceInfoSet
78 DWORD magic; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */
79 GUID ClassGuid;
80 HWND hwndParent;
83 /***********************************************************************
84 * SetupDiBuildClassInfoList (SETUPAPI.@)
86 * Returns a list of setup class GUIDs that identify the classes
87 * that are installed on a local machine.
89 * PARAMS
90 * Flags [I] control exclusion of classes from the list.
91 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
92 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
93 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
95 * RETURNS
96 * Success: TRUE.
97 * Failure: FALSE.
99 BOOL WINAPI SetupDiBuildClassInfoList(
100 DWORD Flags,
101 LPGUID ClassGuidList,
102 DWORD ClassGuidListSize,
103 PDWORD RequiredSize)
105 TRACE("\n");
106 return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
107 ClassGuidListSize, RequiredSize,
108 NULL, NULL);
111 /***********************************************************************
112 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
114 * Returns a list of setup class GUIDs that identify the classes
115 * that are installed on a local or remote macine.
117 * PARAMS
118 * Flags [I] control exclusion of classes from the list.
119 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
120 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
121 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
122 * MachineName [I] name of a remote machine.
123 * Reserved [I] must be NULL.
125 * RETURNS
126 * Success: TRUE.
127 * Failure: FALSE.
129 BOOL WINAPI SetupDiBuildClassInfoListExA(
130 DWORD Flags,
131 LPGUID ClassGuidList,
132 DWORD ClassGuidListSize,
133 PDWORD RequiredSize,
134 LPCSTR MachineName,
135 PVOID Reserved)
137 LPWSTR MachineNameW = NULL;
138 BOOL bResult;
140 TRACE("\n");
142 if (MachineName)
144 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
145 if (MachineNameW == NULL) return FALSE;
148 bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
149 ClassGuidListSize, RequiredSize,
150 MachineNameW, Reserved);
152 MyFree(MachineNameW);
154 return bResult;
157 /***********************************************************************
158 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
160 * Returns a list of setup class GUIDs that identify the classes
161 * that are installed on a local or remote macine.
163 * PARAMS
164 * Flags [I] control exclusion of classes from the list.
165 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
166 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
167 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
168 * MachineName [I] name of a remote machine.
169 * Reserved [I] must be NULL.
171 * RETURNS
172 * Success: TRUE.
173 * Failure: FALSE.
175 BOOL WINAPI SetupDiBuildClassInfoListExW(
176 DWORD Flags,
177 LPGUID ClassGuidList,
178 DWORD ClassGuidListSize,
179 PDWORD RequiredSize,
180 LPCWSTR MachineName,
181 PVOID Reserved)
183 WCHAR szKeyName[40];
184 HKEY hClassesKey;
185 HKEY hClassKey;
186 DWORD dwLength;
187 DWORD dwIndex;
188 LONG lError;
189 DWORD dwGuidListIndex = 0;
191 TRACE("\n");
193 if (RequiredSize != NULL)
194 *RequiredSize = 0;
196 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
197 KEY_ALL_ACCESS,
198 DIOCR_INSTALLER,
199 MachineName,
200 Reserved);
201 if (hClassesKey == INVALID_HANDLE_VALUE)
203 return FALSE;
206 for (dwIndex = 0; ; dwIndex++)
208 dwLength = 40;
209 lError = RegEnumKeyExW(hClassesKey,
210 dwIndex,
211 szKeyName,
212 &dwLength,
213 NULL,
214 NULL,
215 NULL,
216 NULL);
217 TRACE("RegEnumKeyExW() returns %d\n", lError);
218 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
220 TRACE("Key name: %p\n", szKeyName);
222 if (RegOpenKeyExW(hClassesKey,
223 szKeyName,
225 KEY_ALL_ACCESS,
226 &hClassKey))
228 RegCloseKey(hClassesKey);
229 return FALSE;
232 if (!RegQueryValueExW(hClassKey,
233 NoUseClass,
234 NULL,
235 NULL,
236 NULL,
237 NULL))
239 TRACE("'NoUseClass' value found!\n");
240 RegCloseKey(hClassKey);
241 continue;
244 if ((Flags & DIBCI_NOINSTALLCLASS) &&
245 (!RegQueryValueExW(hClassKey,
246 NoInstallClass,
247 NULL,
248 NULL,
249 NULL,
250 NULL)))
252 TRACE("'NoInstallClass' value found!\n");
253 RegCloseKey(hClassKey);
254 continue;
257 if ((Flags & DIBCI_NODISPLAYCLASS) &&
258 (!RegQueryValueExW(hClassKey,
259 NoDisplayClass,
260 NULL,
261 NULL,
262 NULL,
263 NULL)))
265 TRACE("'NoDisplayClass' value found!\n");
266 RegCloseKey(hClassKey);
267 continue;
270 RegCloseKey(hClassKey);
272 TRACE("Guid: %p\n", szKeyName);
273 if (dwGuidListIndex < ClassGuidListSize)
275 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
277 szKeyName[37] = 0;
279 TRACE("Guid: %p\n", &szKeyName[1]);
281 UuidFromStringW(&szKeyName[1],
282 &ClassGuidList[dwGuidListIndex]);
285 dwGuidListIndex++;
288 if (lError != ERROR_SUCCESS)
289 break;
292 RegCloseKey(hClassesKey);
294 if (RequiredSize != NULL)
295 *RequiredSize = dwGuidListIndex;
297 if (ClassGuidListSize < dwGuidListIndex)
299 SetLastError(ERROR_INSUFFICIENT_BUFFER);
300 return FALSE;
303 return TRUE;
306 /***********************************************************************
307 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
309 BOOL WINAPI SetupDiClassGuidsFromNameA(
310 LPCSTR ClassName,
311 LPGUID ClassGuidList,
312 DWORD ClassGuidListSize,
313 PDWORD RequiredSize)
315 return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
316 ClassGuidListSize, RequiredSize,
317 NULL, NULL);
320 /***********************************************************************
321 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
323 BOOL WINAPI SetupDiClassGuidsFromNameW(
324 LPCWSTR ClassName,
325 LPGUID ClassGuidList,
326 DWORD ClassGuidListSize,
327 PDWORD RequiredSize)
329 return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
330 ClassGuidListSize, RequiredSize,
331 NULL, NULL);
334 /***********************************************************************
335 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
337 BOOL WINAPI SetupDiClassGuidsFromNameExA(
338 LPCSTR ClassName,
339 LPGUID ClassGuidList,
340 DWORD ClassGuidListSize,
341 PDWORD RequiredSize,
342 LPCSTR MachineName,
343 PVOID Reserved)
345 LPWSTR ClassNameW = NULL;
346 LPWSTR MachineNameW = NULL;
347 BOOL bResult;
349 FIXME("\n");
351 ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);
352 if (ClassNameW == NULL)
353 return FALSE;
355 if (MachineName)
357 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
358 if (MachineNameW == NULL)
360 MyFree(ClassNameW);
361 return FALSE;
365 bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
366 ClassGuidListSize, RequiredSize,
367 MachineNameW, Reserved);
369 MyFree(MachineNameW);
370 MyFree(ClassNameW);
372 return bResult;
375 /***********************************************************************
376 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
378 BOOL WINAPI SetupDiClassGuidsFromNameExW(
379 LPCWSTR ClassName,
380 LPGUID ClassGuidList,
381 DWORD ClassGuidListSize,
382 PDWORD RequiredSize,
383 LPCWSTR MachineName,
384 PVOID Reserved)
386 WCHAR szKeyName[40];
387 WCHAR szClassName[256];
388 HKEY hClassesKey;
389 HKEY hClassKey;
390 DWORD dwLength;
391 DWORD dwIndex;
392 LONG lError;
393 DWORD dwGuidListIndex = 0;
395 if (RequiredSize != NULL)
396 *RequiredSize = 0;
398 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
399 KEY_ALL_ACCESS,
400 DIOCR_INSTALLER,
401 MachineName,
402 Reserved);
403 if (hClassesKey == INVALID_HANDLE_VALUE)
405 return FALSE;
408 for (dwIndex = 0; ; dwIndex++)
410 dwLength = 40;
411 lError = RegEnumKeyExW(hClassesKey,
412 dwIndex,
413 szKeyName,
414 &dwLength,
415 NULL,
416 NULL,
417 NULL,
418 NULL);
419 TRACE("RegEnumKeyExW() returns %d\n", lError);
420 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
422 TRACE("Key name: %p\n", szKeyName);
424 if (RegOpenKeyExW(hClassesKey,
425 szKeyName,
427 KEY_ALL_ACCESS,
428 &hClassKey))
430 RegCloseKey(hClassesKey);
431 return FALSE;
434 dwLength = 256 * sizeof(WCHAR);
435 if (!RegQueryValueExW(hClassKey,
436 Class,
437 NULL,
438 NULL,
439 (LPBYTE)szClassName,
440 &dwLength))
442 TRACE("Class name: %p\n", szClassName);
444 if (strcmpiW(szClassName, ClassName) == 0)
446 TRACE("Found matching class name\n");
448 TRACE("Guid: %p\n", szKeyName);
449 if (dwGuidListIndex < ClassGuidListSize)
451 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
453 szKeyName[37] = 0;
455 TRACE("Guid: %p\n", &szKeyName[1]);
457 UuidFromStringW(&szKeyName[1],
458 &ClassGuidList[dwGuidListIndex]);
461 dwGuidListIndex++;
465 RegCloseKey(hClassKey);
468 if (lError != ERROR_SUCCESS)
469 break;
472 RegCloseKey(hClassesKey);
474 if (RequiredSize != NULL)
475 *RequiredSize = dwGuidListIndex;
477 if (ClassGuidListSize < dwGuidListIndex)
479 SetLastError(ERROR_INSUFFICIENT_BUFFER);
480 return FALSE;
483 return TRUE;
486 /***********************************************************************
487 * SetupDiClassNameFromGuidA (SETUPAPI.@)
489 BOOL WINAPI SetupDiClassNameFromGuidA(
490 const GUID* ClassGuid,
491 PSTR ClassName,
492 DWORD ClassNameSize,
493 PDWORD RequiredSize)
495 return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
496 ClassNameSize, RequiredSize,
497 NULL, NULL);
500 /***********************************************************************
501 * SetupDiClassNameFromGuidW (SETUPAPI.@)
503 BOOL WINAPI SetupDiClassNameFromGuidW(
504 const GUID* ClassGuid,
505 PWSTR ClassName,
506 DWORD ClassNameSize,
507 PDWORD RequiredSize)
509 return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
510 ClassNameSize, RequiredSize,
511 NULL, NULL);
514 /***********************************************************************
515 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
517 BOOL WINAPI SetupDiClassNameFromGuidExA(
518 const GUID* ClassGuid,
519 PSTR ClassName,
520 DWORD ClassNameSize,
521 PDWORD RequiredSize,
522 PCSTR MachineName,
523 PVOID Reserved)
525 WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
526 LPWSTR MachineNameW = NULL;
527 BOOL ret;
529 if (MachineName)
530 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
531 ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
532 NULL, MachineNameW, Reserved);
533 if (ret)
535 int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
536 ClassNameSize, NULL, NULL);
538 if (!ClassNameSize && RequiredSize)
539 *RequiredSize = len;
541 MyFree(MachineNameW);
542 return ret;
545 /***********************************************************************
546 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
548 BOOL WINAPI SetupDiClassNameFromGuidExW(
549 const GUID* ClassGuid,
550 PWSTR ClassName,
551 DWORD ClassNameSize,
552 PDWORD RequiredSize,
553 PCWSTR MachineName,
554 PVOID Reserved)
556 HKEY hKey;
557 DWORD dwLength;
559 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
560 KEY_ALL_ACCESS,
561 DIOCR_INSTALLER,
562 MachineName,
563 Reserved);
564 if (hKey == INVALID_HANDLE_VALUE)
566 return FALSE;
569 if (RequiredSize != NULL)
571 dwLength = 0;
572 if (RegQueryValueExW(hKey,
573 Class,
574 NULL,
575 NULL,
576 NULL,
577 &dwLength))
579 RegCloseKey(hKey);
580 return FALSE;
583 *RequiredSize = dwLength / sizeof(WCHAR);
586 dwLength = ClassNameSize * sizeof(WCHAR);
587 if (RegQueryValueExW(hKey,
588 Class,
589 NULL,
590 NULL,
591 (LPBYTE)ClassName,
592 &dwLength))
594 RegCloseKey(hKey);
595 return FALSE;
598 RegCloseKey(hKey);
600 return TRUE;
603 /***********************************************************************
604 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
606 HDEVINFO WINAPI
607 SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
608 HWND hwndParent)
610 return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
613 /***********************************************************************
614 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
616 HDEVINFO WINAPI
617 SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
618 HWND hwndParent,
619 PCSTR MachineName,
620 PVOID Reserved)
622 LPWSTR MachineNameW = NULL;
623 HDEVINFO hDevInfo;
625 TRACE("\n");
627 if (MachineName)
629 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
630 if (MachineNameW == NULL)
631 return (HDEVINFO)INVALID_HANDLE_VALUE;
634 hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
635 MachineNameW, Reserved);
637 MyFree(MachineNameW);
639 return hDevInfo;
642 /***********************************************************************
643 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
645 * Create an empty DeviceInfoSet list.
647 * PARAMS
648 * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated
649 * with this list.
650 * hwndParent [I] hwnd needed for interface related actions.
651 * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
652 * local registry will be used.
653 * Reserved [I] must be NULL
655 * RETURNS
656 * Success: empty list.
657 * Failure: INVALID_HANDLE_VALUE.
659 HDEVINFO WINAPI
660 SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
661 HWND hwndParent,
662 PCWSTR MachineName,
663 PVOID Reserved)
665 devinfo_struct *list = NULL;
666 DWORD size = sizeof(devinfo_struct);
668 TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
669 debugstr_w(MachineName), Reserved);
671 if (MachineName != NULL)
673 FIXME("remote support is not implemented\n");
674 SetLastError(ERROR_INVALID_MACHINENAME);
675 return (HDEVINFO)INVALID_HANDLE_VALUE;
678 if (Reserved != NULL)
680 SetLastError(ERROR_INVALID_PARAMETER);
681 return (HDEVINFO)INVALID_HANDLE_VALUE;
684 list = HeapAlloc(GetProcessHeap(), 0, size);
685 if (!list)
687 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
688 return (HDEVINFO)INVALID_HANDLE_VALUE;
691 memset(list,0,sizeof(devinfo_struct));
692 list->magic = SETUP_DEVICE_INFO_SET_MAGIC;
693 list->hwndParent = hwndParent;
694 memcpy(&list->ClassGuid,
695 ClassGuid ? ClassGuid : &GUID_NULL,
696 sizeof(list->ClassGuid));
698 return (HDEVINFO)list;
701 /***********************************************************************
702 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
704 BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
706 devinfo_struct *info = (devinfo_struct*)devinfo;
708 TRACE("%p\n", devinfo);
710 if (!info)
711 return TRUE;
713 if (info->count > 0)
715 int i;
716 for (i = 0; i < info->count; i++)
718 if (info->devices[i].hardwareid)
719 HeapFree(GetProcessHeap(),0,info->devices[i].hardwareid);
721 HeapFree(GetProcessHeap(),0,info->devices);
724 HeapFree(GetProcessHeap(),0,info);
726 return TRUE;
729 /***********************************************************************
730 * SetupDiCreateDeviceInfoA (SETUPAPI.@)
732 BOOL WINAPI SetupDiCreateDeviceInfoA(
733 HDEVINFO DeviceInfoSet,
734 PCSTR DeviceName,
735 CONST GUID *ClassGuid,
736 PCSTR DeviceDescription,
737 HWND hwndParent,
738 DWORD CreationFlags,
739 PSP_DEVINFO_DATA DeviceInfoData)
741 BOOL ret = FALSE;
742 LPWSTR DeviceNameW = NULL;
743 LPWSTR DeviceDescriptionW = NULL;
745 if (DeviceName)
747 DeviceNameW = MultiByteToUnicode(DeviceName, CP_ACP);
748 if (DeviceNameW == NULL) return FALSE;
750 if (DeviceDescription)
752 DeviceDescriptionW = MultiByteToUnicode(DeviceDescription, CP_ACP);
753 if (DeviceDescriptionW == NULL)
755 MyFree(DeviceNameW);
756 return FALSE;
760 ret = SetupDiCreateDeviceInfoW(DeviceInfoSet, DeviceNameW, ClassGuid, DeviceDescriptionW,
761 hwndParent, CreationFlags, DeviceInfoData);
763 MyFree(DeviceNameW);
764 MyFree(DeviceDescriptionW);
766 return ret;
769 /***********************************************************************
770 * SetupDiCreateDeviceInfoW (SETUPAPI.@)
772 BOOL WINAPI SetupDiCreateDeviceInfoW(
773 HDEVINFO DeviceInfoSet,
774 PCWSTR DeviceName,
775 CONST GUID *ClassGuid,
776 PCWSTR DeviceDescription,
777 HWND hwndParent,
778 DWORD CreationFlags,
779 PSP_DEVINFO_DATA DeviceInfoData)
781 TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet, debugstr_w(DeviceName),
782 debugstr_guid(ClassGuid), debugstr_w(DeviceDescription),
783 hwndParent, CreationFlags, DeviceInfoData);
785 FIXME("stub\n");
787 return FALSE;
790 /***********************************************************************
791 * SetupDiEnumDeviceInfo (SETUPAPI.@)
793 BOOL WINAPI SetupDiEnumDeviceInfo(
794 HDEVINFO devinfo,
795 DWORD index,
796 PSP_DEVINFO_DATA info)
798 DWORD rc;
799 devinfo_struct *tree = (devinfo_struct*)devinfo;
801 TRACE("%p %d %p\n", devinfo, index, info );
803 if(info==NULL)
804 return FALSE;
805 if(info->cbSize < sizeof(*info))
806 return FALSE;
807 if (tree == NULL)
808 return FALSE;
810 if (index >= tree->count)
812 SetLastError(ERROR_NO_MORE_ITEMS);
813 return FALSE;
816 memcpy(&(info->ClassGuid),&(tree->devices[index].guid),sizeof(GUID));
817 info->Reserved = (ULONG_PTR)&(tree->devices[index]);
820 * Used by cfgmgr32... this is BAD BAD not threadsafe
821 * also it should be a handle that can be used to retrieve data like this
822 * not the straight up data.... but this hack works for the ipod
824 tree->devices[index].registry_fn(&(tree->devices[index]), SPDRP_DEVICE_ID,
825 NULL, NULL, 0, &rc, FALSE);
826 info->DevInst = (DWORD)(tree->devices[index].deviceId);
828 return TRUE;
831 /***********************************************************************
832 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
834 BOOL WINAPI SetupDiEnumDeviceInterfaces(
835 HDEVINFO DeviceInfoSet,
836 PSP_DEVINFO_DATA DeviceInfoData,
837 CONST GUID * InterfaceClassGuid,
838 DWORD MemberIndex,
839 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
841 devinfo_struct *tree = (devinfo_struct*)DeviceInfoSet;
843 TRACE("(%p, %p, %s, %i %p\n",DeviceInfoSet, DeviceInfoData,
844 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
846 if (!tree)
847 return FALSE;
849 if (MemberIndex >= tree->count)
851 SetLastError(ERROR_NO_MORE_ITEMS);
852 return FALSE;
855 memcpy(&(DeviceInterfaceData->InterfaceClassGuid),
856 &(tree->devices[MemberIndex].guid),sizeof(GUID));
857 DeviceInterfaceData->Flags = tree->devices[MemberIndex].flags;
858 DeviceInterfaceData->Reserved = (ULONG_PTR)&(tree->devices[MemberIndex]);
860 return TRUE;
863 /***********************************************************************
864 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
866 BOOL WINAPI SetupDiGetActualSectionToInstallA(
867 HINF InfHandle,
868 PCSTR InfSectionName,
869 PSTR InfSectionWithExt,
870 DWORD InfSectionWithExtSize,
871 PDWORD RequiredSize,
872 PSTR *Extension)
874 FIXME("\n");
875 return FALSE;
878 /***********************************************************************
879 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
881 BOOL WINAPI SetupDiGetActualSectionToInstallW(
882 HINF InfHandle,
883 PCWSTR InfSectionName,
884 PWSTR InfSectionWithExt,
885 DWORD InfSectionWithExtSize,
886 PDWORD RequiredSize,
887 PWSTR *Extension)
889 WCHAR szBuffer[MAX_PATH];
890 DWORD dwLength;
891 DWORD dwFullLength;
892 LONG lLineCount = -1;
894 lstrcpyW(szBuffer, InfSectionName);
895 dwLength = lstrlenW(szBuffer);
897 if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
899 /* Test section name with '.NTx86' extension */
900 lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
901 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
903 if (lLineCount == -1)
905 /* Test section name with '.NT' extension */
906 lstrcpyW(&szBuffer[dwLength], NtExtension);
907 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
910 else
912 /* Test section name with '.Win' extension */
913 lstrcpyW(&szBuffer[dwLength], WinExtension);
914 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
917 if (lLineCount == -1)
919 /* Test section name without extension */
920 szBuffer[dwLength] = 0;
921 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
924 if (lLineCount == -1)
926 SetLastError(ERROR_INVALID_PARAMETER);
927 return FALSE;
930 dwFullLength = lstrlenW(szBuffer);
932 if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
934 if (InfSectionWithExtSize < (dwFullLength + 1))
936 SetLastError(ERROR_INSUFFICIENT_BUFFER);
937 return FALSE;
940 lstrcpyW(InfSectionWithExt, szBuffer);
941 if (Extension != NULL)
943 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
947 if (RequiredSize != NULL)
949 *RequiredSize = dwFullLength + 1;
952 return TRUE;
955 /***********************************************************************
956 * SetupDiGetClassDescriptionA (SETUPAPI.@)
958 BOOL WINAPI SetupDiGetClassDescriptionA(
959 const GUID* ClassGuid,
960 PSTR ClassDescription,
961 DWORD ClassDescriptionSize,
962 PDWORD RequiredSize)
964 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
965 ClassDescriptionSize,
966 RequiredSize, NULL, NULL);
969 /***********************************************************************
970 * SetupDiGetClassDescriptionW (SETUPAPI.@)
972 BOOL WINAPI SetupDiGetClassDescriptionW(
973 const GUID* ClassGuid,
974 PWSTR ClassDescription,
975 DWORD ClassDescriptionSize,
976 PDWORD RequiredSize)
978 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
979 ClassDescriptionSize,
980 RequiredSize, NULL, NULL);
983 /***********************************************************************
984 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
986 BOOL WINAPI SetupDiGetClassDescriptionExA(
987 const GUID* ClassGuid,
988 PSTR ClassDescription,
989 DWORD ClassDescriptionSize,
990 PDWORD RequiredSize,
991 PCSTR MachineName,
992 PVOID Reserved)
994 FIXME("\n");
995 return FALSE;
998 /***********************************************************************
999 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
1001 BOOL WINAPI SetupDiGetClassDescriptionExW(
1002 const GUID* ClassGuid,
1003 PWSTR ClassDescription,
1004 DWORD ClassDescriptionSize,
1005 PDWORD RequiredSize,
1006 PCWSTR MachineName,
1007 PVOID Reserved)
1009 HKEY hKey;
1010 DWORD dwLength;
1012 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
1013 KEY_ALL_ACCESS,
1014 DIOCR_INSTALLER,
1015 MachineName,
1016 Reserved);
1017 if (hKey == INVALID_HANDLE_VALUE)
1019 WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError());
1020 return FALSE;
1023 if (RequiredSize != NULL)
1025 dwLength = 0;
1026 if (RegQueryValueExW(hKey,
1027 NULL,
1028 NULL,
1029 NULL,
1030 NULL,
1031 &dwLength))
1033 RegCloseKey(hKey);
1034 return FALSE;
1037 *RequiredSize = dwLength / sizeof(WCHAR);
1040 dwLength = ClassDescriptionSize * sizeof(WCHAR);
1041 if (RegQueryValueExW(hKey,
1042 NULL,
1043 NULL,
1044 NULL,
1045 (LPBYTE)ClassDescription,
1046 &dwLength))
1048 RegCloseKey(hKey);
1049 return FALSE;
1052 RegCloseKey(hKey);
1054 return TRUE;
1057 /***********************************************************************
1058 * SetupDiGetClassDevsA (SETUPAPI.@)
1060 HDEVINFO WINAPI SetupDiGetClassDevsA(
1061 CONST GUID *class,
1062 LPCSTR enumstr,
1063 HWND parent,
1064 DWORD flags)
1066 devinfo_struct *info;
1068 TRACE("%s %s %p %08x\n",debugstr_guid(class),enumstr,parent,flags);
1070 /* TODO: make this thread safe*/
1071 info = HeapAlloc(GetProcessHeap(),0,sizeof(devinfo_struct));
1072 memset(info,0,sizeof(devinfo_struct));
1073 info->flags = flags;
1074 info->unicode = FALSE;
1075 /* setting the winehq structure members */
1076 info->magic = SETUP_DEVICE_INFO_SET_MAGIC;
1077 info->hwndParent = parent;
1078 memcpy(&info->ClassGuid,
1079 class ? class: &GUID_NULL,
1080 sizeof(info->ClassGuid));
1082 USB_GetDeviceDevs(info,class,enumstr);
1084 return (HDEVINFO)info;
1087 /***********************************************************************
1088 * SetupDiGetClassDevsW (SETUPAPI.@)
1090 HDEVINFO WINAPI SetupDiGetClassDevsW(
1091 CONST GUID *class,
1092 LPCWSTR enumstr,
1093 HWND parent,
1094 DWORD flags)
1096 TRACE("%s %s %p 0x%08x\n", debugstr_guid(class), debugstr_w(enumstr), parent, flags);
1098 /* WinXP always succeeds, returns empty list for unknown classes */
1099 FIXME("returning empty list\n");
1100 return SetupDiCreateDeviceInfoList(class, parent);
1103 /***********************************************************************
1104 * SetupDiGetClassDevsExW (SETUPAPI.@)
1106 HDEVINFO WINAPI SetupDiGetClassDevsExW(
1107 CONST GUID *class,
1108 PCWSTR enumstr,
1109 HWND parent,
1110 DWORD flags,
1111 HDEVINFO deviceset,
1112 PCWSTR machine,
1113 PVOID reserved)
1115 FIXME("stub\n");
1116 return FALSE;
1119 /***********************************************************************
1120 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
1122 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
1123 HDEVINFO DeviceInfoSet,
1124 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1125 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
1126 DWORD DeviceInterfaceDetailDataSize,
1127 PDWORD RequiredSize,
1128 PSP_DEVINFO_DATA DeviceInfoData)
1130 devnode *node = (devnode*)DeviceInterfaceData->Reserved;
1132 FIXME("%p %p %p %i %p %p\n",DeviceInfoSet, DeviceInterfaceData,
1133 DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize,
1134 RequiredSize, DeviceInfoData);
1136 node->registry_fn(node, SPDRP_DEVICE_PATH, NULL,
1137 (LPBYTE)DeviceInterfaceDetailData->DevicePath,
1138 DeviceInterfaceDetailDataSize, RequiredSize, FALSE);
1140 SetLastError(0);
1141 return TRUE;
1144 /***********************************************************************
1145 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
1147 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
1148 HDEVINFO DeviceInfoSet,
1149 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
1150 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
1151 DWORD DeviceInterfaceDetailDataSize,
1152 PDWORD RequiredSize,
1153 PSP_DEVINFO_DATA DeviceInfoData)
1155 FIXME("\n");
1156 return FALSE;
1159 /***********************************************************************
1160 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
1162 BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
1163 HDEVINFO devinfo,
1164 PSP_DEVINFO_DATA DeviceInfoData,
1165 DWORD Property,
1166 PDWORD PropertyRegDataType,
1167 PBYTE PropertyBuffer,
1168 DWORD PropertyBufferSize,
1169 PDWORD RequiredSize)
1171 devnode *node = (devnode*)DeviceInfoData->Reserved;
1173 TRACE("%p %p %d %p %p %d %p\n", devinfo, DeviceInfoData,
1174 Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
1175 RequiredSize);
1177 if (!node)
1178 return FALSE;
1180 return (BOOL)node->registry_fn(node, Property, PropertyRegDataType,
1181 PropertyBuffer, PropertyBufferSize, RequiredSize, FALSE);
1184 /***********************************************************************
1185 * SetupDiInstallClassA (SETUPAPI.@)
1187 BOOL WINAPI SetupDiInstallClassA(
1188 HWND hwndParent,
1189 PCSTR InfFileName,
1190 DWORD Flags,
1191 HSPFILEQ FileQueue)
1193 UNICODE_STRING FileNameW;
1194 BOOL Result;
1196 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
1198 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1199 return FALSE;
1202 Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
1204 RtlFreeUnicodeString(&FileNameW);
1206 return Result;
1209 static HKEY CreateClassKey(HINF hInf)
1211 WCHAR FullBuffer[MAX_PATH];
1212 WCHAR Buffer[MAX_PATH];
1213 DWORD RequiredSize;
1214 HKEY hClassKey;
1216 if (!SetupGetLineTextW(NULL,
1217 hInf,
1218 Version,
1219 ClassGUID,
1220 Buffer,
1221 MAX_PATH,
1222 &RequiredSize))
1224 return INVALID_HANDLE_VALUE;
1227 lstrcpyW(FullBuffer, ControlClass);
1228 lstrcatW(FullBuffer, Buffer);
1230 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1231 FullBuffer,
1233 KEY_ALL_ACCESS,
1234 &hClassKey))
1236 if (!SetupGetLineTextW(NULL,
1237 hInf,
1238 Version,
1239 Class,
1240 Buffer,
1241 MAX_PATH,
1242 &RequiredSize))
1244 return INVALID_HANDLE_VALUE;
1247 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
1248 FullBuffer,
1250 NULL,
1251 REG_OPTION_NON_VOLATILE,
1252 KEY_ALL_ACCESS,
1253 NULL,
1254 &hClassKey,
1255 NULL))
1257 return INVALID_HANDLE_VALUE;
1262 if (RegSetValueExW(hClassKey,
1263 Class,
1265 REG_SZ,
1266 (LPBYTE)Buffer,
1267 RequiredSize * sizeof(WCHAR)))
1269 RegCloseKey(hClassKey);
1270 RegDeleteKeyW(HKEY_LOCAL_MACHINE,
1271 FullBuffer);
1272 return INVALID_HANDLE_VALUE;
1275 return hClassKey;
1278 /***********************************************************************
1279 * SetupDiInstallClassW (SETUPAPI.@)
1281 BOOL WINAPI SetupDiInstallClassW(
1282 HWND hwndParent,
1283 PCWSTR InfFileName,
1284 DWORD Flags,
1285 HSPFILEQ FileQueue)
1287 WCHAR SectionName[MAX_PATH];
1288 DWORD SectionNameLength = 0;
1289 HINF hInf;
1290 BOOL bFileQueueCreated = FALSE;
1291 HKEY hClassKey;
1294 FIXME("\n");
1296 if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
1298 SetLastError(ERROR_INVALID_PARAMETER);
1299 return FALSE;
1302 /* Open the .inf file */
1303 hInf = SetupOpenInfFileW(InfFileName,
1304 NULL,
1305 INF_STYLE_WIN4,
1306 NULL);
1307 if (hInf == INVALID_HANDLE_VALUE)
1310 return FALSE;
1313 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
1314 hClassKey = CreateClassKey(hInf);
1315 if (hClassKey == INVALID_HANDLE_VALUE)
1317 SetupCloseInfFile(hInf);
1318 return FALSE;
1322 /* Try to append a layout file */
1323 #if 0
1324 SetupOpenAppendInfFileW(NULL, hInf, NULL);
1325 #endif
1327 /* Retrieve the actual section name */
1328 SetupDiGetActualSectionToInstallW(hInf,
1329 ClassInstall32,
1330 SectionName,
1331 MAX_PATH,
1332 &SectionNameLength,
1333 NULL);
1335 #if 0
1336 if (!(Flags & DI_NOVCP))
1338 FileQueue = SetupOpenFileQueue();
1339 if (FileQueue == INVALID_HANDLE_VALUE)
1341 SetupCloseInfFile(hInf);
1342 return FALSE;
1345 bFileQueueCreated = TRUE;
1348 #endif
1350 SetupInstallFromInfSectionW(NULL,
1351 hInf,
1352 SectionName,
1353 SPINST_REGISTRY,
1354 hClassKey,
1355 NULL,
1357 NULL,
1358 NULL,
1359 INVALID_HANDLE_VALUE,
1360 NULL);
1362 /* FIXME: More code! */
1364 if (bFileQueueCreated)
1365 SetupCloseFileQueue(FileQueue);
1367 SetupCloseInfFile(hInf);
1369 return TRUE;
1373 /***********************************************************************
1374 * SetupDiOpenClassRegKey (SETUPAPI.@)
1376 HKEY WINAPI SetupDiOpenClassRegKey(
1377 const GUID* ClassGuid,
1378 REGSAM samDesired)
1380 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1381 DIOCR_INSTALLER, NULL, NULL);
1385 /***********************************************************************
1386 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1388 HKEY WINAPI SetupDiOpenClassRegKeyExA(
1389 const GUID* ClassGuid,
1390 REGSAM samDesired,
1391 DWORD Flags,
1392 PCSTR MachineName,
1393 PVOID Reserved)
1395 PWSTR MachineNameW = NULL;
1396 HKEY hKey;
1398 TRACE("\n");
1400 if (MachineName)
1402 MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
1403 if (MachineNameW == NULL)
1404 return INVALID_HANDLE_VALUE;
1407 hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1408 Flags, MachineNameW, Reserved);
1410 MyFree(MachineNameW);
1412 return hKey;
1416 /***********************************************************************
1417 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1419 HKEY WINAPI SetupDiOpenClassRegKeyExW(
1420 const GUID* ClassGuid,
1421 REGSAM samDesired,
1422 DWORD Flags,
1423 PCWSTR MachineName,
1424 PVOID Reserved)
1426 LPWSTR lpGuidString;
1427 WCHAR bracedGuidString[39];
1428 HKEY hClassesKey;
1429 HKEY hClassKey;
1430 LPCWSTR lpKeyName;
1432 if (MachineName != NULL)
1434 FIXME("Remote access not supported yet!\n");
1435 return INVALID_HANDLE_VALUE;
1438 if (Flags == DIOCR_INSTALLER)
1440 lpKeyName = ControlClass;
1442 else if (Flags == DIOCR_INTERFACE)
1444 lpKeyName = DeviceClasses;
1446 else
1448 ERR("Invalid Flags parameter!\n");
1449 SetLastError(ERROR_INVALID_PARAMETER);
1450 return INVALID_HANDLE_VALUE;
1453 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1454 lpKeyName,
1456 KEY_ALL_ACCESS,
1457 &hClassesKey))
1459 return INVALID_HANDLE_VALUE;
1462 if (ClassGuid == NULL)
1463 return hClassesKey;
1465 if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
1467 RegCloseKey(hClassesKey);
1468 return INVALID_HANDLE_VALUE;
1470 bracedGuidString[0] = '{';
1471 memcpy(&bracedGuidString[1], lpGuidString, 36*sizeof(WCHAR));
1472 bracedGuidString[37] = '}';
1473 bracedGuidString[38] = 0;
1474 RpcStringFreeW(&lpGuidString);
1476 if (RegOpenKeyExW(hClassesKey,
1477 bracedGuidString,
1479 KEY_ALL_ACCESS,
1480 &hClassKey))
1482 RegCloseKey(hClassesKey);
1483 return INVALID_HANDLE_VALUE;
1486 RegCloseKey(hClassesKey);
1488 return hClassKey;
1491 /***********************************************************************
1492 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
1494 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
1495 HDEVINFO DeviceInfoSet,
1496 PCWSTR DevicePath,
1497 DWORD OpenFlags,
1498 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1500 FIXME("%p %s %08x %p\n",
1501 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
1502 return FALSE;
1505 /***********************************************************************
1506 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1508 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
1509 HDEVINFO DeviceInfoSet,
1510 PCSTR DevicePath,
1511 DWORD OpenFlags,
1512 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1514 FIXME("%p %s %08x %p\n", DeviceInfoSet,
1515 debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
1516 return FALSE;
1519 /***********************************************************************
1520 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1522 BOOL WINAPI SetupDiSetClassInstallParamsA(
1523 HDEVINFO DeviceInfoSet,
1524 PSP_DEVINFO_DATA DeviceInfoData,
1525 PSP_CLASSINSTALL_HEADER ClassInstallParams,
1526 DWORD ClassInstallParamsSize)
1528 FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData,
1529 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
1530 return TRUE;
1533 /***********************************************************************
1534 * SetupDiCallClassInstaller (SETUPAPI.@)
1536 BOOL WINAPI SetupDiCallClassInstaller(
1537 DI_FUNCTION InstallFunction,
1538 HDEVINFO DeviceInfoSet,
1539 PSP_DEVINFO_DATA DeviceInfoData)
1541 FIXME("%d %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
1542 return TRUE;
1545 /***********************************************************************
1546 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1548 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
1549 HDEVINFO DeviceInfoSet,
1550 PSP_DEVINFO_DATA DeviceInfoData,
1551 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
1553 FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
1554 return TRUE;
1557 /***********************************************************************
1558 * SetupDiOpenDevRegKey (SETUPAPI.@)
1560 HKEY WINAPI SetupDiOpenDevRegKey(
1561 HDEVINFO DeviceInfoSet,
1562 PSP_DEVINFO_DATA DeviceInfoData,
1563 DWORD Scope,
1564 DWORD HwProfile,
1565 DWORD KeyType,
1566 REGSAM samDesired)
1568 FIXME("%p %p %d %d %d %x\n", DeviceInfoSet, DeviceInfoData,
1569 Scope, HwProfile, KeyType, samDesired);
1570 return INVALID_HANDLE_VALUE;