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