Branch setupapi (again)
[reactos.git] / reactos / lib / setupapi / devinst.c
1 /*
2 * SetupAPI device installer
3 *
4 * Copyright 2000 Andreas Mohr for CodeWeavers
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
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdarg.h>
25
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
38 #include "rpc.h"
39 #include "rpcdce.h"
40
41
42 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
43
44 /* Unicode constants */
45 static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0};
46 static const WCHAR Class[] = {'C','l','a','s','s',0};
47 static const WCHAR ClassInstall32[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
48 static const WCHAR NoDisplayClass[] = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
49 static const WCHAR NoInstallClass[] = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};
50 static const WCHAR NoUseClass[] = {'N','o','U','s','e','C','l','a','s','s',0};
51 static const WCHAR NtExtension[] = {'.','N','T',0};
52 static const WCHAR NtPlatformExtension[] = {'.','N','T','x','8','6',0};
53 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
54 static const WCHAR WinExtension[] = {'.','W','i','n',0};
55
56 /* Registry key and value names */
57 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
58 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
59 'C','o','n','t','r','o','l','\\',
60 'C','l','a','s','s',0};
61
62 static const WCHAR DeviceClasses[] = {'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 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
66
67 /***********************************************************************
68 * SetupDiBuildClassInfoList (SETUPAPI.@)
69 */
70 BOOL WINAPI SetupDiBuildClassInfoList(
71 DWORD Flags,
72 LPGUID ClassGuidList,
73 DWORD ClassGuidListSize,
74 PDWORD RequiredSize)
75 {
76 TRACE("\n");
77 return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
78 ClassGuidListSize, RequiredSize,
79 NULL, NULL);
80 }
81
82 /***********************************************************************
83 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
84 */
85 BOOL WINAPI SetupDiBuildClassInfoListExA(
86 DWORD Flags,
87 LPGUID ClassGuidList,
88 DWORD ClassGuidListSize,
89 PDWORD RequiredSize,
90 LPCSTR MachineName,
91 PVOID Reserved)
92 {
93 FIXME("\n");
94 return FALSE;
95 }
96
97 /***********************************************************************
98 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
99 */
100 BOOL WINAPI SetupDiBuildClassInfoListExW(
101 DWORD Flags,
102 LPGUID ClassGuidList,
103 DWORD ClassGuidListSize,
104 PDWORD RequiredSize,
105 LPCWSTR MachineName,
106 PVOID Reserved)
107 {
108 WCHAR szKeyName[40];
109 HKEY hClassesKey;
110 HKEY hClassKey;
111 DWORD dwLength;
112 DWORD dwIndex;
113 LONG lError;
114 DWORD dwGuidListIndex = 0;
115
116 TRACE("\n");
117
118 if (RequiredSize != NULL)
119 *RequiredSize = 0;
120
121 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
122 KEY_ALL_ACCESS,
123 DIOCR_INSTALLER,
124 MachineName,
125 Reserved);
126 if (hClassesKey == INVALID_HANDLE_VALUE)
127 {
128 return FALSE;
129 }
130
131 for (dwIndex = 0; ; dwIndex++)
132 {
133 dwLength = 40;
134 lError = RegEnumKeyExW(hClassesKey,
135 dwIndex,
136 szKeyName,
137 &dwLength,
138 NULL,
139 NULL,
140 NULL,
141 NULL);
142 TRACE("RegEnumKeyExW() returns %ld\n", lError);
143 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
144 {
145 TRACE("Key name: %p\n", szKeyName);
146
147 if (RegOpenKeyExW(hClassesKey,
148 szKeyName,
149 0,
150 KEY_ALL_ACCESS,
151 &hClassKey))
152 {
153 RegCloseKey(hClassesKey);
154 return FALSE;
155 }
156
157 if (!RegQueryValueExW(hClassKey,
158 NoUseClass,
159 NULL,
160 NULL,
161 NULL,
162 NULL))
163 {
164 TRACE("'NoUseClass' value found!\n");
165 RegCloseKey(hClassKey);
166 continue;
167 }
168
169 if ((Flags & DIBCI_NOINSTALLCLASS) &&
170 (!RegQueryValueExW(hClassKey,
171 NoInstallClass,
172 NULL,
173 NULL,
174 NULL,
175 NULL)))
176 {
177 TRACE("'NoInstallClass' value found!\n");
178 RegCloseKey(hClassKey);
179 continue;
180 }
181
182 if ((Flags & DIBCI_NODISPLAYCLASS) &&
183 (!RegQueryValueExW(hClassKey,
184 NoDisplayClass,
185 NULL,
186 NULL,
187 NULL,
188 NULL)))
189 {
190 TRACE("'NoDisplayClass' value found!\n");
191 RegCloseKey(hClassKey);
192 continue;
193 }
194
195 RegCloseKey(hClassKey);
196
197 TRACE("Guid: %p\n", szKeyName);
198 if (dwGuidListIndex < ClassGuidListSize)
199 {
200 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
201 {
202 szKeyName[37] = 0;
203 }
204 TRACE("Guid: %p\n", &szKeyName[1]);
205
206 UuidFromStringW(&szKeyName[1],
207 &ClassGuidList[dwGuidListIndex]);
208 }
209
210 dwGuidListIndex++;
211 }
212
213 if (lError != ERROR_SUCCESS)
214 break;
215 }
216
217 RegCloseKey(hClassesKey);
218
219 if (RequiredSize != NULL)
220 *RequiredSize = dwGuidListIndex;
221
222 if (ClassGuidListSize < dwGuidListIndex)
223 {
224 SetLastError(ERROR_INSUFFICIENT_BUFFER);
225 return FALSE;
226 }
227
228 return TRUE;
229 }
230
231 /***********************************************************************
232 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
233 */
234 BOOL WINAPI SetupDiClassGuidsFromNameA(
235 LPCSTR ClassName,
236 LPGUID ClassGuidList,
237 DWORD ClassGuidListSize,
238 PDWORD RequiredSize)
239 {
240 return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
241 ClassGuidListSize, RequiredSize,
242 NULL, NULL);
243 }
244
245 /***********************************************************************
246 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
247 */
248 BOOL WINAPI SetupDiClassGuidsFromNameW(
249 LPCWSTR ClassName,
250 LPGUID ClassGuidList,
251 DWORD ClassGuidListSize,
252 PDWORD RequiredSize)
253 {
254 return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
255 ClassGuidListSize, RequiredSize,
256 NULL, NULL);
257 }
258
259 /***********************************************************************
260 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
261 */
262 BOOL WINAPI SetupDiClassGuidsFromNameExA(
263 LPCSTR ClassName,
264 LPGUID ClassGuidList,
265 DWORD ClassGuidListSize,
266 PDWORD RequiredSize,
267 LPCSTR MachineName,
268 PVOID Reserved)
269 {
270 FIXME("\n");
271 return FALSE;
272 }
273
274 /***********************************************************************
275 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
276 */
277 BOOL WINAPI SetupDiClassGuidsFromNameExW(
278 LPCWSTR ClassName,
279 LPGUID ClassGuidList,
280 DWORD ClassGuidListSize,
281 PDWORD RequiredSize,
282 LPCWSTR MachineName,
283 PVOID Reserved)
284 {
285 WCHAR szKeyName[40];
286 WCHAR szClassName[256];
287 HKEY hClassesKey;
288 HKEY hClassKey;
289 DWORD dwLength;
290 DWORD dwIndex;
291 LONG lError;
292 DWORD dwGuidListIndex = 0;
293
294 if (RequiredSize != NULL)
295 *RequiredSize = 0;
296
297 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
298 KEY_ALL_ACCESS,
299 DIOCR_INSTALLER,
300 MachineName,
301 Reserved);
302 if (hClassesKey == INVALID_HANDLE_VALUE)
303 {
304 return FALSE;
305 }
306
307 for (dwIndex = 0; ; dwIndex++)
308 {
309 dwLength = 40;
310 lError = RegEnumKeyExW(hClassesKey,
311 dwIndex,
312 szKeyName,
313 &dwLength,
314 NULL,
315 NULL,
316 NULL,
317 NULL);
318 TRACE("RegEnumKeyExW() returns %ld\n", lError);
319 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
320 {
321 TRACE("Key name: %p\n", szKeyName);
322
323 if (RegOpenKeyExW(hClassesKey,
324 szKeyName,
325 0,
326 KEY_ALL_ACCESS,
327 &hClassKey))
328 {
329 RegCloseKey(hClassesKey);
330 return FALSE;
331 }
332
333 dwLength = 256 * sizeof(WCHAR);
334 if (!RegQueryValueExW(hClassKey,
335 Class,
336 NULL,
337 NULL,
338 (LPBYTE)szClassName,
339 &dwLength))
340 {
341 TRACE("Class name: %p\n", szClassName);
342
343 if (strcmpiW(szClassName, ClassName) == 0)
344 {
345 TRACE("Found matching class name\n");
346
347 TRACE("Guid: %p\n", szKeyName);
348 if (dwGuidListIndex < ClassGuidListSize)
349 {
350 if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
351 {
352 szKeyName[37] = 0;
353 }
354 TRACE("Guid: %p\n", &szKeyName[1]);
355
356 UuidFromStringW(&szKeyName[1],
357 &ClassGuidList[dwGuidListIndex]);
358 }
359
360 dwGuidListIndex++;
361 }
362 }
363
364 RegCloseKey(hClassKey);
365 }
366
367 if (lError != ERROR_SUCCESS)
368 break;
369 }
370
371 RegCloseKey(hClassesKey);
372
373 if (RequiredSize != NULL)
374 *RequiredSize = dwGuidListIndex;
375
376 if (ClassGuidListSize < dwGuidListIndex)
377 {
378 SetLastError(ERROR_INSUFFICIENT_BUFFER);
379 return FALSE;
380 }
381
382 return TRUE;
383 }
384
385 /***********************************************************************
386 * SetupDiClassNameFromGuidA (SETUPAPI.@)
387 */
388 BOOL WINAPI SetupDiClassNameFromGuidA(
389 const GUID* ClassGuid,
390 PSTR ClassName,
391 DWORD ClassNameSize,
392 PDWORD RequiredSize)
393 {
394 return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
395 ClassNameSize, RequiredSize,
396 NULL, NULL);
397 }
398
399 /***********************************************************************
400 * SetupDiClassNameFromGuidW (SETUPAPI.@)
401 */
402 BOOL WINAPI SetupDiClassNameFromGuidW(
403 const GUID* ClassGuid,
404 PWSTR ClassName,
405 DWORD ClassNameSize,
406 PDWORD RequiredSize)
407 {
408 return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
409 ClassNameSize, RequiredSize,
410 NULL, NULL);
411 }
412
413 /***********************************************************************
414 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
415 */
416 BOOL WINAPI SetupDiClassNameFromGuidExA(
417 const GUID* ClassGuid,
418 PSTR ClassName,
419 DWORD ClassNameSize,
420 PDWORD RequiredSize,
421 PCSTR MachineName,
422 PVOID Reserved)
423 {
424 FIXME("\n");
425 return FALSE;
426 }
427
428 /***********************************************************************
429 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
430 */
431 BOOL WINAPI SetupDiClassNameFromGuidExW(
432 const GUID* ClassGuid,
433 PWSTR ClassName,
434 DWORD ClassNameSize,
435 PDWORD RequiredSize,
436 PCWSTR MachineName,
437 PVOID Reserved)
438 {
439 HKEY hKey;
440 DWORD dwLength;
441
442 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
443 KEY_ALL_ACCESS,
444 DIOCR_INSTALLER,
445 MachineName,
446 Reserved);
447 if (hKey == INVALID_HANDLE_VALUE)
448 {
449 return FALSE;
450 }
451
452 if (RequiredSize != NULL)
453 {
454 dwLength = 0;
455 if (RegQueryValueExW(hKey,
456 Class,
457 NULL,
458 NULL,
459 NULL,
460 &dwLength))
461 {
462 RegCloseKey(hKey);
463 return FALSE;
464 }
465
466 *RequiredSize = dwLength / sizeof(WCHAR);
467 }
468
469 dwLength = ClassNameSize * sizeof(WCHAR);
470 if (RegQueryValueExW(hKey,
471 Class,
472 NULL,
473 NULL,
474 (LPBYTE)ClassName,
475 &dwLength))
476 {
477 RegCloseKey(hKey);
478 return FALSE;
479 }
480
481 RegCloseKey(hKey);
482
483 return TRUE;
484 }
485
486 /***********************************************************************
487 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
488 */
489 HDEVINFO WINAPI
490 SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
491 HWND hwndParent)
492 {
493 return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
494 }
495
496 /***********************************************************************
497 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
498 */
499 HDEVINFO WINAPI
500 SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
501 HWND hwndParent,
502 PCSTR MachineName,
503 PVOID Reserved)
504 {
505 FIXME("\n");
506 return (HDEVINFO)INVALID_HANDLE_VALUE;
507 }
508
509 /***********************************************************************
510 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
511 */
512 HDEVINFO WINAPI
513 SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
514 HWND hwndParent,
515 PCWSTR MachineName,
516 PVOID Reserved)
517 {
518 FIXME("\n");
519 return (HDEVINFO)INVALID_HANDLE_VALUE;
520 }
521
522 /***********************************************************************
523 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
524 */
525 BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
526 {
527 FIXME("%p\n", devinfo);
528 return FALSE;
529 }
530
531 /***********************************************************************
532 * SetupDiEnumDeviceInfo (SETUPAPI.@)
533 */
534 BOOL WINAPI SetupDiEnumDeviceInfo(
535 HDEVINFO devinfo,
536 DWORD index,
537 PSP_DEVINFO_DATA info)
538 {
539 FIXME("%p %ld %p\n", devinfo, index, info);
540
541 if(info==NULL)
542 return FALSE;
543 if(info->cbSize < sizeof(*info))
544 return FALSE;
545
546 return FALSE;
547 }
548
549 /***********************************************************************
550 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
551 */
552 BOOL WINAPI SetupDiEnumDeviceInterfaces(
553 HDEVINFO DeviceInfoSet,
554 PSP_DEVINFO_DATA DeviceInfoData,
555 CONST GUID * InterfaceClassGuid,
556 DWORD MemberIndex,
557 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
558 {
559 FIXME("\n");
560 return FALSE;
561 }
562
563 /***********************************************************************
564 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
565 */
566 BOOL WINAPI SetupDiGetActualSectionToInstallA(
567 HINF InfHandle,
568 PCSTR InfSectionName,
569 PSTR InfSectionWithExt,
570 DWORD InfSectionWithExtSize,
571 PDWORD RequiredSize,
572 PSTR *Extension)
573 {
574 FIXME("\n");
575 return FALSE;
576 }
577
578 /***********************************************************************
579 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
580 */
581 BOOL WINAPI SetupDiGetActualSectionToInstallW(
582 HINF InfHandle,
583 PCWSTR InfSectionName,
584 PWSTR InfSectionWithExt,
585 DWORD InfSectionWithExtSize,
586 PDWORD RequiredSize,
587 PWSTR *Extension)
588 {
589 WCHAR szBuffer[MAX_PATH];
590 OSVERSIONINFOW OsVersionInfo;
591 DWORD dwLength;
592 DWORD dwFullLength;
593 LONG lLineCount = -1;
594
595 OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
596 if (!GetVersionExW(&OsVersionInfo))
597 {
598 return FALSE;
599 }
600
601 lstrcpyW(szBuffer, InfSectionName);
602 dwLength = lstrlenW(szBuffer);
603
604 if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
605 {
606 /* Test section name with '.NTx86' extension */
607 lstrcpyW(&szBuffer[dwLength], NtPlatformExtension);
608 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
609
610 if (lLineCount == -1)
611 {
612 /* Test section name with '.NT' extension */
613 lstrcpyW(&szBuffer[dwLength], NtExtension);
614 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
615 }
616 }
617 else
618 {
619 /* Test section name with '.Win' extension */
620 lstrcpyW(&szBuffer[dwLength], WinExtension);
621 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
622 }
623
624 if (lLineCount == -1)
625 {
626 /* Test section name without extension */
627 szBuffer[dwLength] = 0;
628 lLineCount = SetupGetLineCountW(InfHandle, szBuffer);
629 }
630
631 if (lLineCount == -1)
632 {
633 SetLastError(ERROR_INVALID_PARAMETER);
634 return FALSE;
635 }
636
637 dwFullLength = lstrlenW(szBuffer);
638
639 if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
640 {
641 if (InfSectionWithExtSize < (dwFullLength + 1))
642 {
643 SetLastError(ERROR_INSUFFICIENT_BUFFER);
644 return FALSE;
645 }
646
647 lstrcpyW(InfSectionWithExt, szBuffer);
648 if (Extension != NULL)
649 {
650 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
651 }
652 }
653
654 if (RequiredSize != NULL)
655 {
656 *RequiredSize = dwFullLength + 1;
657 }
658
659 return TRUE;
660 }
661
662 /***********************************************************************
663 * SetupDiGetClassDescriptionA (SETUPAPI.@)
664 */
665 BOOL WINAPI SetupDiGetClassDescriptionA(
666 const GUID* ClassGuid,
667 PSTR ClassDescription,
668 DWORD ClassDescriptionSize,
669 PDWORD RequiredSize)
670 {
671 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
672 ClassDescriptionSize,
673 RequiredSize, NULL, NULL);
674 }
675
676 /***********************************************************************
677 * SetupDiGetClassDescriptionW (SETUPAPI.@)
678 */
679 BOOL WINAPI SetupDiGetClassDescriptionW(
680 const GUID* ClassGuid,
681 PWSTR ClassDescription,
682 DWORD ClassDescriptionSize,
683 PDWORD RequiredSize)
684 {
685 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
686 ClassDescriptionSize,
687 RequiredSize, NULL, NULL);
688 }
689
690 /***********************************************************************
691 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
692 */
693 BOOL WINAPI SetupDiGetClassDescriptionExA(
694 const GUID* ClassGuid,
695 PSTR ClassDescription,
696 DWORD ClassDescriptionSize,
697 PDWORD RequiredSize,
698 PCSTR MachineName,
699 PVOID Reserved)
700 {
701 FIXME("\n");
702 return FALSE;
703 }
704
705 /***********************************************************************
706 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
707 */
708 BOOL WINAPI SetupDiGetClassDescriptionExW(
709 const GUID* ClassGuid,
710 PWSTR ClassDescription,
711 DWORD ClassDescriptionSize,
712 PDWORD RequiredSize,
713 PCWSTR MachineName,
714 PVOID Reserved)
715 {
716 HKEY hKey;
717 DWORD dwLength;
718
719 hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
720 KEY_ALL_ACCESS,
721 DIOCR_INSTALLER,
722 MachineName,
723 Reserved);
724 if (hKey == INVALID_HANDLE_VALUE)
725 {
726 WARN("SetupDiOpenClassRegKeyExW() failed (Error %lu)\n", GetLastError());
727 return FALSE;
728 }
729
730 if (RequiredSize != NULL)
731 {
732 dwLength = 0;
733 if (RegQueryValueExW(hKey,
734 NULL,
735 NULL,
736 NULL,
737 NULL,
738 &dwLength))
739 {
740 RegCloseKey(hKey);
741 return FALSE;
742 }
743
744 *RequiredSize = dwLength / sizeof(WCHAR);
745 }
746
747 dwLength = ClassDescriptionSize * sizeof(WCHAR);
748 if (RegQueryValueExW(hKey,
749 NULL,
750 NULL,
751 NULL,
752 (LPBYTE)ClassDescription,
753 &dwLength))
754 {
755 RegCloseKey(hKey);
756 return FALSE;
757 }
758
759 RegCloseKey(hKey);
760
761 return TRUE;
762 }
763
764 /***********************************************************************
765 * SetupDiGetClassDevsA (SETUPAPI.@)
766 */
767 HDEVINFO WINAPI SetupDiGetClassDevsA(
768 CONST GUID *class,
769 LPCSTR enumstr,
770 HWND parent,
771 DWORD flags)
772 {
773 FIXME("%s %s %p %08lx\n",debugstr_guid(class),enumstr,parent,flags);
774
775 return (HDEVINFO) INVALID_HANDLE_VALUE;
776 }
777
778 /***********************************************************************
779 * SetupDiGetClassDevsW (SETUPAPI.@)
780 */
781 HDEVINFO WINAPI SetupDiGetClassDevsW(
782 CONST GUID *class,
783 LPCWSTR enumstr,
784 HWND parent,
785 DWORD flags)
786 {
787 FIXME("%s %s %p %08lx\n",debugstr_guid(class),debugstr_w(enumstr),parent,flags);
788
789 return (HDEVINFO) INVALID_HANDLE_VALUE;
790 }
791
792 /***********************************************************************
793 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
794 */
795 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
796 HDEVINFO DeviceInfoSet,
797 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
798 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
799 DWORD DeviceInterfaceDetailDataSize,
800 PDWORD RequiredSize,
801 PSP_DEVINFO_DATA DeviceInfoData)
802 {
803 FIXME("\n");
804 return FALSE;
805 }
806
807 /***********************************************************************
808 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
809 */
810 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
811 HDEVINFO DeviceInfoSet,
812 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
813 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
814 DWORD DeviceInterfaceDetailDataSize,
815 PDWORD RequiredSize,
816 PSP_DEVINFO_DATA DeviceInfoData)
817 {
818 FIXME("\n");
819 return FALSE;
820 }
821
822 /***********************************************************************
823 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
824 */
825 BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
826 HDEVINFO devinfo,
827 PSP_DEVINFO_DATA DeviceInfoData,
828 DWORD Property,
829 PDWORD PropertyRegDataType,
830 PBYTE PropertyBuffer,
831 DWORD PropertyBufferSize,
832 PDWORD RequiredSize)
833 {
834 FIXME("%04lx %p %ld %p %p %ld %p\n", (DWORD)devinfo, DeviceInfoData,
835 Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
836 RequiredSize);
837 return FALSE;
838 }
839
840 /***********************************************************************
841 * SetupDiInstallClassA (SETUPAPI.@)
842 */
843 BOOL WINAPI SetupDiInstallClassA(
844 HWND hwndParent,
845 PCSTR InfFileName,
846 DWORD Flags,
847 HSPFILEQ FileQueue)
848 {
849 UNICODE_STRING FileNameW;
850 BOOL Result;
851
852 if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName))
853 {
854 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
855 return FALSE;
856 }
857
858 Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue);
859
860 RtlFreeUnicodeString(&FileNameW);
861
862 return Result;
863 }
864
865 static HKEY CreateClassKey(HINF hInf)
866 {
867 WCHAR FullBuffer[MAX_PATH];
868 WCHAR Buffer[MAX_PATH];
869 DWORD RequiredSize;
870 HKEY hClassKey;
871
872 if (!SetupGetLineTextW(NULL,
873 hInf,
874 Version,
875 ClassGUID,
876 Buffer,
877 MAX_PATH,
878 &RequiredSize))
879 {
880 return INVALID_HANDLE_VALUE;
881 }
882
883 lstrcpyW(FullBuffer, ControlClass);
884 lstrcatW(FullBuffer, Buffer);
885
886 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
887 FullBuffer,
888 0,
889 KEY_ALL_ACCESS,
890 &hClassKey))
891 {
892 if (!SetupGetLineTextW(NULL,
893 hInf,
894 Version,
895 Class,
896 Buffer,
897 MAX_PATH,
898 &RequiredSize))
899 {
900 return INVALID_HANDLE_VALUE;
901 }
902
903 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
904 FullBuffer,
905 0,
906 NULL,
907 REG_OPTION_NON_VOLATILE,
908 KEY_ALL_ACCESS,
909 NULL,
910 &hClassKey,
911 NULL))
912 {
913 return INVALID_HANDLE_VALUE;
914 }
915
916 }
917
918 if (RegSetValueExW(hClassKey,
919 Class,
920 0,
921 REG_SZ,
922 (LPBYTE)Buffer,
923 RequiredSize * sizeof(WCHAR)))
924 {
925 RegCloseKey(hClassKey);
926 RegDeleteKeyW(HKEY_LOCAL_MACHINE,
927 FullBuffer);
928 return INVALID_HANDLE_VALUE;
929 }
930
931 return hClassKey;
932 }
933
934 /***********************************************************************
935 * SetupDiInstallClassW (SETUPAPI.@)
936 */
937 BOOL WINAPI SetupDiInstallClassW(
938 HWND hwndParent,
939 PCWSTR InfFileName,
940 DWORD Flags,
941 HSPFILEQ FileQueue)
942 {
943 WCHAR SectionName[MAX_PATH];
944 DWORD SectionNameLength = 0;
945 HINF hInf;
946 BOOL bFileQueueCreated = FALSE;
947 HKEY hClassKey;
948
949
950 FIXME("\n");
951
952 if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
953 {
954 SetLastError(ERROR_INVALID_PARAMETER);
955 return FALSE;
956 }
957
958 /* Open the .inf file */
959 hInf = SetupOpenInfFileW(InfFileName,
960 NULL,
961 INF_STYLE_WIN4,
962 NULL);
963 if (hInf == INVALID_HANDLE_VALUE)
964 {
965
966 return FALSE;
967 }
968
969 /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */
970 hClassKey = CreateClassKey(hInf);
971 if (hClassKey == INVALID_HANDLE_VALUE)
972 {
973 SetupCloseInfFile(hInf);
974 return FALSE;
975 }
976
977
978 /* Try to append a layout file */
979 #if 0
980 SetupOpenAppendInfFileW(NULL, hInf, NULL);
981 #endif
982
983 /* Retrieve the actual section name */
984 SetupDiGetActualSectionToInstallW(hInf,
985 ClassInstall32,
986 SectionName,
987 MAX_PATH,
988 &SectionNameLength,
989 NULL);
990
991 #if 0
992 if (!(Flags & DI_NOVCP))
993 {
994 FileQueue = SetupOpenFileQueue();
995 if (FileQueue == INVALID_HANDLE_VALUE)
996 {
997 SetupCloseInfFile(hInf);
998 return FALSE;
999 }
1000
1001 bFileQueueCreated = TRUE;
1002
1003 }
1004 #endif
1005
1006 SetupInstallFromInfSectionW(NULL,
1007 hInf,
1008 SectionName,
1009 SPINST_REGISTRY,
1010 hClassKey,
1011 NULL,
1012 0,
1013 NULL,
1014 NULL,
1015 INVALID_HANDLE_VALUE,
1016 NULL);
1017
1018 /* FIXME: More code! */
1019
1020 if (bFileQueueCreated)
1021 SetupCloseFileQueue(FileQueue);
1022
1023 SetupCloseInfFile(hInf);
1024
1025 return TRUE;
1026 }
1027
1028
1029 /***********************************************************************
1030 * SetupDiOpenClassRegKey (SETUPAPI.@)
1031 */
1032 HKEY WINAPI SetupDiOpenClassRegKey(
1033 const GUID* ClassGuid,
1034 REGSAM samDesired)
1035 {
1036 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
1037 DIOCR_INSTALLER, NULL, NULL);
1038 }
1039
1040
1041 /***********************************************************************
1042 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
1043 */
1044 HKEY WINAPI SetupDiOpenClassRegKeyExA(
1045 const GUID* ClassGuid,
1046 REGSAM samDesired,
1047 DWORD Flags,
1048 PCSTR MachineName,
1049 PVOID Reserved)
1050 {
1051 FIXME("\n");
1052 return INVALID_HANDLE_VALUE;
1053 }
1054
1055
1056 /***********************************************************************
1057 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
1058 */
1059 HKEY WINAPI SetupDiOpenClassRegKeyExW(
1060 const GUID* ClassGuid,
1061 REGSAM samDesired,
1062 DWORD Flags,
1063 PCWSTR MachineName,
1064 PVOID Reserved)
1065 {
1066 LPWSTR lpGuidString;
1067 HKEY hClassesKey;
1068 HKEY hClassKey;
1069 LPCWSTR lpKeyName;
1070
1071 if (MachineName != NULL)
1072 {
1073 FIXME("Remote access not supported yet!\n");
1074 return INVALID_HANDLE_VALUE;
1075 }
1076
1077 if (Flags == DIOCR_INSTALLER)
1078 {
1079 lpKeyName = ControlClass;
1080 }
1081 else if (Flags == DIOCR_INTERFACE)
1082 {
1083 lpKeyName = DeviceClasses;
1084 }
1085 else
1086 {
1087 ERR("Invalid Flags parameter!\n");
1088 SetLastError(ERROR_INVALID_PARAMETER);
1089 return INVALID_HANDLE_VALUE;
1090 }
1091
1092 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1093 lpKeyName,
1094 0,
1095 KEY_ALL_ACCESS,
1096 &hClassesKey))
1097 {
1098 return INVALID_HANDLE_VALUE;
1099 }
1100
1101 if (ClassGuid == NULL)
1102 return hClassesKey;
1103
1104 if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK)
1105 {
1106 RegCloseKey(hClassesKey);
1107 return FALSE;
1108 }
1109
1110 if (RegOpenKeyExW(hClassesKey,
1111 lpGuidString,
1112 0,
1113 KEY_ALL_ACCESS,
1114 &hClassKey))
1115 {
1116 RpcStringFreeW(&lpGuidString);
1117 RegCloseKey(hClassesKey);
1118 return FALSE;
1119 }
1120
1121 RpcStringFreeW(&lpGuidString);
1122 RegCloseKey(hClassesKey);
1123
1124 return hClassKey;
1125 }
1126
1127 /***********************************************************************
1128 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1129 */
1130 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
1131 HDEVINFO DeviceInfoSet,
1132 PCWSTR DevicePath,
1133 DWORD OpenFlags,
1134 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1135 {
1136 FIXME("%p %s %08lx %p\n",
1137 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
1138 return FALSE;
1139 }
1140
1141 /***********************************************************************
1142 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
1143 */
1144 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
1145 HDEVINFO DeviceInfoSet,
1146 PCSTR DevicePath,
1147 DWORD OpenFlags,
1148 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
1149 {
1150 FIXME("%p %s %08lx %p\n", DeviceInfoSet,
1151 debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
1152 return FALSE;
1153 }
1154
1155 /***********************************************************************
1156 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
1157 */
1158 BOOL WINAPI SetupDiSetClassInstallParamsA(
1159 HDEVINFO DeviceInfoSet,
1160 PSP_DEVINFO_DATA DeviceInfoData,
1161 PSP_CLASSINSTALL_HEADER ClassInstallParams,
1162 DWORD ClassInstallParamsSize)
1163 {
1164 FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
1165 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
1166 return FALSE;
1167 }
1168
1169 /***********************************************************************
1170 * SetupDiCallClassInstaller (SETUPAPI.@)
1171 */
1172 BOOL WINAPI SetupDiCallClassInstaller(
1173 DWORD InstallFunction,
1174 HDEVINFO DeviceInfoSet,
1175 PSP_DEVINFO_DATA DeviceInfoData)
1176 {
1177 FIXME("%ld %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
1178 return FALSE;
1179 }
1180
1181 /***********************************************************************
1182 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
1183 */
1184 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
1185 HDEVINFO DeviceInfoSet,
1186 PSP_DEVINFO_DATA DeviceInfoData,
1187 PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
1188 {
1189 FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
1190 return FALSE;
1191 }
1192
1193 /***********************************************************************
1194 * SetupDiOpenDevRegKey (SETUPAPI.@)
1195 */
1196 HKEY WINAPI SetupDiOpenDevRegKey(
1197 HDEVINFO DeviceInfoSet,
1198 PSP_DEVINFO_DATA DeviceInfoData,
1199 DWORD Scope,
1200 DWORD HwProfile,
1201 DWORD KeyType,
1202 REGSAM samDesired)
1203 {
1204 FIXME("%p %p %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData,
1205 Scope, HwProfile, KeyType, samDesired);
1206 return INVALID_HANDLE_VALUE;
1207 }