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