ReactOS 0.4.15-dev-7958-gcd0bb1a
devinst.c
Go to the documentation of this file.
1/*
2 * SetupAPI device installer
3 *
4 * Copyright 2000 Andreas Mohr for CodeWeavers
5 * 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
6 *
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.
11 *
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.
16 *
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
20 */
21
22#include "setupapi_private.h"
23
24#include <pseh/pseh2.h>
25
26/* Unicode constants */
27static const WCHAR BackSlash[] = {'\\',0};
28static const WCHAR DateFormat[] = {'%','u','-','%','u','-','%','u',0};
29static const WCHAR DotCoInstallers[] = {'.','C','o','I','n','s','t','a','l','l','e','r','s',0};
30static const WCHAR DotHW[] = {'.','H','W',0};
31static const WCHAR DotServices[] = {'.','S','e','r','v','i','c','e','s',0};
32static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
33static const WCHAR InstanceKeyFormat[] = {'%','0','4','l','u',0};
34static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
35static const WCHAR VersionFormat[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
36
37static const WCHAR REGSTR_DRIVER_DATE[] = {'D','r','i','v','e','r','D','a','t','e',0};
38static const WCHAR REGSTR_DRIVER_DATE_DATA[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0};
39static const WCHAR REGSTR_DRIVER_VERSION[] = {'D','r','i','v','e','r','V','e','r','s','i','o','n',0};
40static const WCHAR REGSTR_SECURITY[] = {'S','e','c','u','r','i','t','y',0};
41static const WCHAR REGSTR_UI_NUMBER_DESC_FORMAT[] = {'U','I','N','u','m','b','e','r','D','e','s','c','F','o','r','m','a','t',0};
42
43typedef DWORD
45 IN DI_FUNCTION InstallFunction,
48typedef BOOL
52typedef DWORD
54 IN DI_FUNCTION InstallFunction,
58
60{
62
67};
68
70{
77};
78
79
80
82{
83 static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-',
84 '%','0','4','X','-','%','0','2','X','%','0','2','X','-','%','0','2',
85 'X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%',
86 '0','2','X','}',0};
87
88 sprintfW(guidStr, fmt, guid->Data1, guid->Data2, guid->Data3,
89 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
90 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
91}
92
95{
96 switch (cr)
97 {
101 case CR_FAILURE: return ERROR_GEN_FAILURE;
115 case CR_SUCCESS: return ERROR_SUCCESS;
116 default: return ERROR_GEN_FAILURE;
117 }
118
119 /* Does not happen */
120}
121
122/* Lower scores are best ones */
123static BOOL
125 IN LPCWSTR SectionName,
126 IN PSP_ALTPLATFORM_INFO PlatformInfo,
127 IN BYTE ProductType,
128 IN WORD SuiteMask,
129 OUT PDWORD ScorePlatform,
130 OUT PDWORD ScoreMajorVersion,
131 OUT PDWORD ScoreMinorVersion,
132 OUT PDWORD ScoreProductType,
133 OUT PDWORD ScoreSuiteMask)
134{
135 LPWSTR Section = NULL;
136 //LPCWSTR pExtensionPlatform;
137 LPCWSTR pExtensionArchitecture;
138 LPWSTR Fields[6];
139 DWORD i;
140 BOOL ret = FALSE;
141
142 //static const WCHAR ExtensionPlatformNone[] = {'.',0};
143 static const WCHAR ExtensionPlatformNT[] = {'.','N','T',0};
144 static const WCHAR ExtensionPlatformWindows[] = {'.','W','i','n',0};
145
146 static const WCHAR ExtensionArchitectureNone[] = {0};
147 static const WCHAR ExtensionArchitecturealpha[] = {'a','l','p','h','a',0};
148 static const WCHAR ExtensionArchitectureamd64[] = {'A','M','D','6','4',0};
149 static const WCHAR ExtensionArchitectureia64[] = {'I','A','6','4',0};
150 static const WCHAR ExtensionArchitecturemips[] = {'m','i','p','s',0};
151 static const WCHAR ExtensionArchitectureppc[] = {'p','p','c',0};
152 static const WCHAR ExtensionArchitecturex86[] = {'x','8','6',0};
153
154 TRACE("%s(%s %p 0x%x 0x%x)\n",
155 __FUNCTION__, debugstr_w(SectionName), PlatformInfo, ProductType, SuiteMask);
156
157 *ScorePlatform = *ScoreMajorVersion = *ScoreMinorVersion = *ScoreProductType = *ScoreSuiteMask = 0;
158
159 Section = pSetupDuplicateString(SectionName);
160 if (!Section)
161 {
162 TRACE("pSetupDuplicateString() failed\n");
163 goto cleanup;
164 }
165
166 /* Set various extensions values */
167 switch (PlatformInfo->Platform)
168 {
170 //pExtensionPlatform = ExtensionPlatformWindows;
171 break;
173 //pExtensionPlatform = ExtensionPlatformNT;
174 break;
175 default:
176 ERR("Unknown platform 0x%lx\n", PlatformInfo->Platform);
177 //pExtensionPlatform = ExtensionPlatformNone;
178 break;
179 }
180 switch (PlatformInfo->ProcessorArchitecture)
181 {
183 pExtensionArchitecture = ExtensionArchitecturealpha;
184 break;
186 pExtensionArchitecture = ExtensionArchitectureamd64;
187 break;
189 pExtensionArchitecture = ExtensionArchitectureia64;
190 break;
192 pExtensionArchitecture = ExtensionArchitecturex86;
193 break;
195 pExtensionArchitecture = ExtensionArchitecturemips;
196 break;
198 pExtensionArchitecture = ExtensionArchitectureppc;
199 break;
200 default:
201 ERR("Unknown processor architecture 0x%x\n", PlatformInfo->ProcessorArchitecture);
203 pExtensionArchitecture = ExtensionArchitectureNone;
204 break;
205 }
206
207 /*
208 * Field[0] Platform
209 * Field[1] Architecture
210 * Field[2] Major version
211 * Field[3] Minor version
212 * Field[4] Product type
213 * Field[5] Suite mask
214 * Remark: these fields may be NULL if the information is not provided
215 */
216 Fields[0] = Section;
217 if (Fields[0] == NULL)
218 {
219 TRACE("No extension found\n");
220 *ScorePlatform = *ScoreMajorVersion = *ScoreMinorVersion = *ScoreProductType = *ScoreSuiteMask = ULONG_MAX;
221 ret = TRUE;
222 goto cleanup;
223 }
224 Fields[1] = Fields[0] + 1;
225 Fields[2] = Fields[3] = Fields[4] = Fields[5] = NULL;
226 for (i = 2; Fields[i - 1] != NULL && i < 6; i++)
227 {
228 Fields[i] = wcschr(Fields[i - 1], '.');
229 if (Fields[i])
230 {
231 Fields[i]++;
232 *(Fields[i] - 1) = UNICODE_NULL;
233 }
234 }
235 /* Take care of first 2 fields */
236 if (strncmpiW(Fields[0], ExtensionPlatformWindows, strlenW(ExtensionPlatformWindows)) == 0)
237 {
238 if (PlatformInfo->Platform != VER_PLATFORM_WIN32_WINDOWS)
239 {
240 TRACE("Mismatch on platform field\n");
241 goto cleanup;
242 }
243 Fields[1] += wcslen(ExtensionPlatformWindows) - 1;
244 }
245 else if (strncmpiW(Fields[0], ExtensionPlatformNT, strlenW(ExtensionPlatformNT)) == 0)
246 {
247 if (PlatformInfo->Platform != VER_PLATFORM_WIN32_NT)
248 {
249 TRACE("Mismatch on platform field\n");
250 goto cleanup;
251 }
252 Fields[1] += wcslen(ExtensionPlatformNT) - 1;
253 }
254 else
255 {
256 /* No platform specified */
257 *ScorePlatform |= 0x02;
258 }
259 if (strcmpiW(Fields[1], ExtensionArchitectureNone) == 0)
260 {
261 /* No architecture specified */
262 *ScorePlatform |= 0x01;
263 }
264 else if (strcmpiW(Fields[1], pExtensionArchitecture) != 0)
265 {
266 TRACE("Mismatch on architecture field ('%s' and '%s')\n",
267 debugstr_w(Fields[1]), debugstr_w(pExtensionArchitecture));
268 goto cleanup;
269 }
270
271 /* Check if informations are matching */
272 if (Fields[2] && *Fields[2])
273 {
275 MajorVersion = strtoulW(Fields[2], NULL, 0);
276 if ((MajorVersion == 0 || MajorVersion == ULONG_MAX) &&
277 (errno == ERANGE || errno == EINVAL))
278 {
279 TRACE("Wrong MajorVersion ('%s')\n", debugstr_w(Fields[2]));
280 goto cleanup;
281 }
282 if (Fields[3] && *Fields[3])
283 {
284 MinorVersion = strtoulW(Fields[3], NULL, 0);
285 if ((MinorVersion == 0 || MinorVersion == ULONG_MAX) &&
286 (errno == ERANGE || errno == EINVAL))
287 {
288 TRACE("Wrong MinorVersion ('%s')\n", debugstr_w(Fields[3]));
289 goto cleanup;
290 }
291 }
292 if (PlatformInfo->MajorVersion < MajorVersion ||
293 (PlatformInfo->MajorVersion == MajorVersion && PlatformInfo->MinorVersion < MinorVersion))
294 {
295 TRACE("Mismatch on version field (%lu.%lu and %lu.%lu)\n",
296 MajorVersion, MinorVersion, PlatformInfo->MajorVersion, PlatformInfo->MinorVersion);
297 goto cleanup;
298 }
299 *ScoreMajorVersion = MajorVersion - PlatformInfo->MajorVersion;
300 if (MajorVersion == PlatformInfo->MajorVersion)
301 *ScoreMinorVersion = MinorVersion - PlatformInfo->MinorVersion;
302 else
303 *ScoreMinorVersion = MinorVersion;
304 }
305 else if (Fields[3] && *Fields[3])
306 {
307 TRACE("Minor version found without major version\n");
308 goto cleanup;
309 }
310 else
311 {
312 *ScoreMajorVersion = PlatformInfo->MajorVersion;
313 *ScoreMinorVersion = PlatformInfo->MinorVersion;
314 }
315
316 if (Fields[4] && *Fields[4])
317 {
318 DWORD CurrentProductType;
319 CurrentProductType = strtoulW(Fields[4], NULL, 0);
320 if ((CurrentProductType == 0 || CurrentProductType == ULONG_MAX) &&
321 (errno == ERANGE || errno == EINVAL))
322 {
323 TRACE("Wrong Product type ('%s')\n", debugstr_w(Fields[4]));
324 goto cleanup;
325 }
326 if (CurrentProductType != ProductType)
327 {
328 TRACE("Mismatch on product type (0x%08lx and 0x%08x)\n",
329 CurrentProductType, ProductType);
330 goto cleanup;
331 }
332 }
333 else
334 *ScoreProductType = 1;
335
336 if (Fields[5] && *Fields[5])
337 {
338 DWORD CurrentSuiteMask;
339 CurrentSuiteMask = strtoulW(Fields[5], NULL, 0);
340 if ((CurrentSuiteMask == 0 || CurrentSuiteMask == ULONG_MAX) &&
341 (errno == ERANGE || errno == EINVAL))
342 {
343 TRACE("Wrong Suite mask ('%s')\n", debugstr_w(Fields[5]));
344 goto cleanup;
345 }
346 if ((CurrentSuiteMask & ~SuiteMask) != 0)
347 {
348 TRACE("Mismatch on suite mask (0x%08lx and 0x%08x)\n",
349 CurrentSuiteMask, SuiteMask);
350 goto cleanup;
351 }
352 *ScoreSuiteMask = SuiteMask & ~CurrentSuiteMask;
353 }
354 else
355 *ScoreSuiteMask = SuiteMask;
356
357 ret = TRUE;
358
359cleanup:
360 MyFree(Section);
361 return ret;
362}
363
364static BOOL
366 IN LPCWSTR SectionName,
368{
370 DWORD Score1, Score2, Score3, Score4, Score5;
371 BOOL ret;
372
373 if (SectionName[info->PrefixLength] != '.')
374 return TRUE;
375
377 &SectionName[info->PrefixLength],
378 info->PlatformInfo,
379 info->ProductType,
380 info->SuiteMask,
381 &Score1, &Score2, &Score3, &Score4, &Score5);
382 if (!ret)
383 {
384 TRACE("Section %s not compatible\n", debugstr_w(SectionName));
385 return TRUE;
386 }
387 if (Score1 > info->BestScore1) goto done;
388 if (Score1 < info->BestScore1) goto bettersection;
389 if (Score2 > info->BestScore2) goto done;
390 if (Score2 < info->BestScore2) goto bettersection;
391 if (Score3 > info->BestScore3) goto done;
392 if (Score3 < info->BestScore3) goto bettersection;
393 if (Score4 > info->BestScore4) goto done;
394 if (Score4 < info->BestScore4) goto bettersection;
395 if (Score5 > info->BestScore5) goto done;
396 if (Score5 < info->BestScore5) goto bettersection;
397 goto done;
398
399bettersection:
400 strcpyW(info->BestSection, SectionName);
401 info->BestScore1 = Score1;
402 info->BestScore2 = Score2;
403 info->BestScore3 = Score3;
404 info->BestScore4 = Score4;
405 info->BestScore5 = Score5;
406
407done:
408 return TRUE;
409}
410
411/***********************************************************************
412 * SetupDiGetActualSectionToInstallExW (SETUPAPI.@)
413 */
416 IN HINF InfHandle,
417 IN PCWSTR InfSectionName,
418 IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
419 OUT PWSTR InfSectionWithExt OPTIONAL,
420 IN DWORD InfSectionWithExtSize,
424{
425 BOOL ret = FALSE;
426
427 TRACE("%s(%p %s %p %p %lu %p %p %p)\n", __FUNCTION__, InfHandle, debugstr_w(InfSectionName),
428 AlternatePlatformInfo, InfSectionWithExt, InfSectionWithExtSize,
430
431 if (!InfHandle || InfHandle == (HINF)INVALID_HANDLE_VALUE)
433 else if (!InfSectionName)
435 else if (AlternatePlatformInfo && AlternatePlatformInfo->cbSize != sizeof(SP_ALTPLATFORM_INFO))
437 else if (Reserved != NULL)
439 else
440 {
441 static SP_ALTPLATFORM_INFO CurrentPlatform = { 0, };
442 static BYTE CurrentProductType = 0;
443 static WORD CurrentSuiteMask = 0;
444 PSP_ALTPLATFORM_INFO pPlatformInfo = &CurrentPlatform;
445 struct GetSectionCallbackInfo CallbackInfo;
446 DWORD dwFullLength;
449
450 /* Fill platform info if needed */
451 if (AlternatePlatformInfo)
452 {
453 pPlatformInfo = AlternatePlatformInfo;
454 ProductType = 0;
455 SuiteMask = 0;
456 }
457 else
458 {
459 if (CurrentPlatform.cbSize != sizeof(SP_ALTPLATFORM_INFO))
460 {
461 /* That's the first time we go here. We need to fill in the structure */
462 SYSTEM_INFO SystemInfo;
463 GetSystemInfo(&SystemInfo);
464 CurrentPlatform.cbSize = sizeof(SP_ALTPLATFORM_INFO);
465 CurrentPlatform.Platform = OsVersionInfo.dwPlatformId;
466 CurrentPlatform.MajorVersion = OsVersionInfo.dwMajorVersion;
467 CurrentPlatform.MinorVersion = OsVersionInfo.dwMinorVersion;
468 CurrentPlatform.ProcessorArchitecture = SystemInfo.wProcessorArchitecture;
469 CurrentPlatform.Reserved = 0;
470 CurrentProductType = OsVersionInfo.wProductType;
471 CurrentSuiteMask = OsVersionInfo.wSuiteMask;
472 }
473 ProductType = CurrentProductType;
474 SuiteMask = CurrentSuiteMask;
475 }
476
477 CallbackInfo.PlatformInfo = pPlatformInfo;
478 CallbackInfo.ProductType = ProductType;
479 CallbackInfo.SuiteMask = SuiteMask;
480 CallbackInfo.PrefixLength = strlenW(InfSectionName);
481 CallbackInfo.BestScore1 = ULONG_MAX;
482 CallbackInfo.BestScore2 = ULONG_MAX;
483 CallbackInfo.BestScore3 = ULONG_MAX;
484 CallbackInfo.BestScore4 = ULONG_MAX;
485 CallbackInfo.BestScore5 = ULONG_MAX;
486 strcpyW(CallbackInfo.BestSection, InfSectionName);
487 TRACE("EnumerateSectionsStartingWith(InfSectionName = %S)\n", InfSectionName);
489 InfHandle,
490 InfSectionName,
492 &CallbackInfo))
493 {
495 goto done;
496 }
497 TRACE("CallbackInfo.BestSection = %S\n", CallbackInfo.BestSection);
498
499 dwFullLength = lstrlenW(CallbackInfo.BestSection);
500 if (RequiredSize != NULL)
501 *RequiredSize = dwFullLength + 1;
502
503 if (InfSectionWithExtSize > 0)
504 {
505 if (InfSectionWithExtSize < dwFullLength + 1)
506 {
508 goto done;
509 }
510 strcpyW(InfSectionWithExt, CallbackInfo.BestSection);
511 if (Extension)
512 {
513 DWORD dwLength = lstrlenW(InfSectionName);
514 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
515 }
516 }
517
518 ret = TRUE;
519 }
520
521done:
522 TRACE("Returning %d\n", ret);
523 return ret;
524}
525
526
527BOOL
529 IN struct DeviceInfoSet *list,
530 IN LPCWSTR InstancePath,
531 IN LPCGUID pClassGuid,
532 OUT struct DeviceInfo **pDeviceInfo)
533{
534 DWORD size;
535 CONFIGRET cr;
536 struct DeviceInfo *deviceInfo;
537
538 *pDeviceInfo = NULL;
539
540 size = FIELD_OFFSET(struct DeviceInfo, Data) + (strlenW(InstancePath) + 1) * sizeof(WCHAR);
541 deviceInfo = HeapAlloc(GetProcessHeap(), 0, size);
542 if (!deviceInfo)
543 {
545 return FALSE;
546 }
547 ZeroMemory(deviceInfo, size);
548
549 cr = CM_Locate_DevNode_ExW(&deviceInfo->dnDevInst, (DEVINSTID_W)InstancePath, CM_LOCATE_DEVNODE_PHANTOM, list->hMachine);
550 if (cr != CR_SUCCESS)
551 {
553 return FALSE;
554 }
555
556 deviceInfo->set = list;
557 deviceInfo->InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
558 strcpyW(deviceInfo->Data, InstancePath);
559 deviceInfo->instanceId = deviceInfo->Data;
560 deviceInfo->UniqueId = strrchrW(deviceInfo->Data, '\\');
561 deviceInfo->DeviceDescription = NULL;
562 memcpy(&deviceInfo->ClassGuid, pClassGuid, sizeof(GUID));
563 deviceInfo->CreationFlags = 0;
566
567 *pDeviceInfo = deviceInfo;
568 return TRUE;
569}
570
571
572static BOOL
574{
575 HeapFree(GetProcessHeap(), 0, installParams->PropChangeParams);
576 HeapFree(GetProcessHeap(), 0, installParams->AddPropertyPageData);
577 return TRUE;
578}
579
580static BOOL
581DestroyDeviceInfo(struct DeviceInfo *deviceInfo)
582{
584 struct DriverInfoElement *driverInfo;
585 struct DeviceInterface *deviceInterface;
586
587 while (!IsListEmpty(&deviceInfo->DriverListHead))
588 {
591 if (!DestroyDriverInfoElement(driverInfo))
592 return FALSE;
593 }
594 while (!IsListEmpty(&deviceInfo->InterfaceListHead))
595 {
597 deviceInterface = CONTAINING_RECORD(ListEntry, struct DeviceInterface, ListEntry);
598 if (!DestroyDeviceInterface(deviceInterface))
599 return FALSE;
600 }
602 if (deviceInfo->hmodDevicePropPageProvider)
604 return HeapFree(GetProcessHeap(), 0, deviceInfo);
605}
606
607static BOOL
609{
611 struct DeviceInfo *deviceInfo;
612
613 while (!IsListEmpty(&list->ListHead))
614 {
615 ListEntry = RemoveHeadList(&list->ListHead);
616 deviceInfo = CONTAINING_RECORD(ListEntry, struct DeviceInfo, ListEntry);
617 if (!DestroyDeviceInfo(deviceInfo))
618 return FALSE;
619 }
620 if (list->HKLM != HKEY_LOCAL_MACHINE)
621 RegCloseKey(list->HKLM);
622 CM_Disconnect_Machine(list->hMachine);
623 DestroyClassInstallParams(&list->ClassInstallParams);
624 if (list->hmodClassPropPageProvider)
625 FreeLibrary(list->hmodClassPropPageProvider);
626 return HeapFree(GetProcessHeap(), 0, list);
627}
628
629/***********************************************************************
630 * SetupDiBuildClassInfoList (SETUPAPI.@)
631 *
632 * Returns a list of setup class GUIDs that identify the classes
633 * that are installed on a local machine.
634 *
635 * PARAMS
636 * Flags [I] control exclusion of classes from the list.
637 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
638 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
639 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
640 *
641 * RETURNS
642 * Success: TRUE.
643 * Failure: FALSE.
644 */
646 DWORD Flags,
647 LPGUID ClassGuidList,
650{
651 TRACE("\n");
652 return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
654 NULL, NULL);
655}
656
657/***********************************************************************
658 * SetupDiBuildClassInfoListExA (SETUPAPI.@)
659 *
660 * Returns a list of setup class GUIDs that identify the classes
661 * that are installed on a local or remote machine.
662 *
663 * PARAMS
664 * Flags [I] control exclusion of classes from the list.
665 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
666 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
667 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
668 * MachineName [I] name of a remote machine.
669 * Reserved [I] must be NULL.
670 *
671 * RETURNS
672 * Success: TRUE.
673 * Failure: FALSE.
674 */
676 DWORD Flags,
677 LPGUID ClassGuidList,
682{
683 LPWSTR MachineNameW = NULL;
684 BOOL bResult;
685
686 TRACE("%s(0x%lx %p %lu %p %s %p)\n", __FUNCTION__, Flags, ClassGuidList,
688
689 if (MachineName)
690 {
692 if (MachineNameW == NULL) return FALSE;
693 }
694
695 bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
697 MachineNameW, Reserved);
698
699 MyFree(MachineNameW);
700
701 return bResult;
702}
703
704/***********************************************************************
705 * SetupDiBuildClassInfoListExW (SETUPAPI.@)
706 *
707 * Returns a list of setup class GUIDs that identify the classes
708 * that are installed on a local or remote machine.
709 *
710 * PARAMS
711 * Flags [I] control exclusion of classes from the list.
712 * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
713 * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
714 * RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
715 * MachineName [I] name of a remote machine.
716 * Reserved [I] must be NULL.
717 *
718 * RETURNS
719 * Success: TRUE.
720 * Failure: FALSE.
721 */
723 DWORD Flags,
724 LPGUID ClassGuidList,
729{
730 GUID CurrentClassGuid;
732 DWORD dwIndex;
733 DWORD dwGuidListIndex = 0;
734 HMACHINE hMachine = NULL;
735 CONFIGRET cr;
736
737 TRACE("%s(0x%lx %p %lu %p %s %p)\n", __FUNCTION__, Flags, ClassGuidList,
739
740 if (!RequiredSize)
741 {
743 return FALSE;
744 }
745 else if (!ClassGuidList && ClassGuidListSize > 0)
746 {
748 return FALSE;
749 }
750
751 if (MachineName)
752 {
753 cr = CM_Connect_MachineW(MachineName, &hMachine);
754 if (cr != CR_SUCCESS)
755 {
757 return FALSE;
758 }
759 }
760
761 for (dwIndex = 0; ; dwIndex++)
762 {
763 cr = CM_Enumerate_Classes_Ex(dwIndex,
764 &CurrentClassGuid,
765 0,
766 hMachine);
767 if (cr == CR_SUCCESS)
768 {
769 TRACE("Guid: %s\n", debugstr_guid(&CurrentClassGuid));
770 if (CM_Open_Class_Key_ExW(&CurrentClassGuid,
771 NULL,
774 &hClassKey,
776 hMachine) != CR_SUCCESS)
777 {
779 if (hMachine)
780 CM_Disconnect_Machine(hMachine);
781 return FALSE;
782 }
783
786 NULL,
787 NULL,
788 NULL,
789 NULL))
790 {
791 TRACE("'NoUseClass' value found!\n");
793 continue;
794 }
795
796 if ((Flags & DIBCI_NOINSTALLCLASS) &&
799 NULL,
800 NULL,
801 NULL,
802 NULL)))
803 {
804 TRACE("'NoInstallClass' value found!\n");
806 continue;
807 }
808
809 if ((Flags & DIBCI_NODISPLAYCLASS) &&
812 NULL,
813 NULL,
814 NULL,
815 NULL)))
816 {
817 TRACE("'NoDisplayClass' value found!\n");
819 continue;
820 }
821
823
824 if (dwGuidListIndex < ClassGuidListSize)
825 {
826 ClassGuidList[dwGuidListIndex] = CurrentClassGuid;
827 }
828
829 dwGuidListIndex++;
830 }
831
832 if (cr != ERROR_SUCCESS)
833 break;
834 }
835
836 if (hMachine)
837 CM_Disconnect_Machine(hMachine);
838
839 if (RequiredSize != NULL)
840 *RequiredSize = dwGuidListIndex;
841
842 if (ClassGuidListSize < dwGuidListIndex)
843 {
845 return FALSE;
846 }
847
848 return TRUE;
849}
850
851/***********************************************************************
852 * SetupDiClassGuidsFromNameA (SETUPAPI.@)
853 */
855 LPCSTR ClassName,
856 LPGUID ClassGuidList,
859{
860 return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
862 NULL, NULL);
863}
864
865/***********************************************************************
866 * SetupDiClassGuidsFromNameW (SETUPAPI.@)
867 */
869 LPCWSTR ClassName,
870 LPGUID ClassGuidList,
873{
874 return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
876 NULL, NULL);
877}
878
879/***********************************************************************
880 * SetupDiClassGuidsFromNameExA (SETUPAPI.@)
881 */
883 LPCSTR ClassName,
884 LPGUID ClassGuidList,
889{
890 LPWSTR ClassNameW = NULL;
891 LPWSTR MachineNameW = NULL;
892 BOOL bResult;
893
894 TRACE("%s(%s %p %lu %p %s %p)\n", __FUNCTION__, debugstr_a(ClassName), ClassGuidList,
896
897 if (!ClassName)
898 {
900 return FALSE;
901 }
902
903 ClassNameW = pSetupMultiByteToUnicode(ClassName, CP_ACP);
904 if (ClassNameW == NULL)
905 return FALSE;
906
907 if (MachineName)
908 {
910 if (MachineNameW == NULL)
911 {
912 MyFree(ClassNameW);
913 return FALSE;
914 }
915 }
916
917 bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
919 MachineNameW, Reserved);
920
921 MyFree(MachineNameW);
922 MyFree(ClassNameW);
923
924 return bResult;
925}
926
927/***********************************************************************
928 * SetupDiClassGuidsFromNameExW (SETUPAPI.@)
929 */
931 LPCWSTR ClassName,
932 LPGUID ClassGuidList,
937{
938 WCHAR szKeyName[40];
940 HKEY hClassesKey;
943 DWORD dwIndex;
944 LONG lError;
945 DWORD dwGuidListIndex = 0;
946
947 TRACE("%s(%s %p %lu %p %s %p)\n", __FUNCTION__, debugstr_w(ClassName), ClassGuidList,
949
950 if (!ClassName || !RequiredSize)
951 {
953 return FALSE;
954 }
955 if (!ClassGuidList && ClassGuidListSize > 0)
956 {
958 return FALSE;
959 }
960 *RequiredSize = 0;
961
962 hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
966 Reserved);
967 if (hClassesKey == INVALID_HANDLE_VALUE)
968 {
969 return FALSE;
970 }
971
972 for (dwIndex = 0; ; dwIndex++)
973 {
974 dwLength = 40;
975 lError = RegEnumKeyExW(hClassesKey,
976 dwIndex,
977 szKeyName,
978 &dwLength,
979 NULL,
980 NULL,
981 NULL,
982 NULL);
983 TRACE("RegEnumKeyExW() returns %d\n", lError);
984 if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
985 {
986 TRACE("Key name: %p\n", szKeyName);
987
988 if (RegOpenKeyExW(hClassesKey,
989 szKeyName,
990 0,
992 &hClassKey))
993 {
994 RegCloseKey(hClassesKey);
995 return FALSE;
996 }
997
1001 NULL,
1002 NULL,
1004 &dwLength))
1005 {
1006 TRACE("Class name: %p\n", szClassName);
1007
1008 if (strcmpiW(szClassName, ClassName) == 0)
1009 {
1010 TRACE("Found matching class name\n");
1011
1012 TRACE("Guid: %p\n", szKeyName);
1013 if (dwGuidListIndex < ClassGuidListSize)
1014 {
1015 if (szKeyName[0] == '{' && szKeyName[37] == '}')
1016 {
1017 szKeyName[37] = 0;
1018 }
1019 TRACE("Guid: %p\n", &szKeyName[1]);
1020
1021 UuidFromStringW(&szKeyName[1],
1022 &ClassGuidList[dwGuidListIndex]);
1023 }
1024
1025 dwGuidListIndex++;
1026 }
1027 }
1028
1030 }
1031
1032 if (lError != ERROR_SUCCESS)
1033 break;
1034 }
1035
1036 RegCloseKey(hClassesKey);
1037
1038 if (RequiredSize != NULL)
1039 *RequiredSize = dwGuidListIndex;
1040
1041 if (ClassGuidListSize < dwGuidListIndex)
1042 {
1044 return FALSE;
1045 }
1046
1047 return TRUE;
1048}
1049
1050/***********************************************************************
1051 * SetupDiClassNameFromGuidA (SETUPAPI.@)
1052 */
1054 const GUID* ClassGuid,
1055 PSTR ClassName,
1056 DWORD ClassNameSize,
1058{
1059 return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
1060 ClassNameSize, RequiredSize,
1061 NULL, NULL);
1062}
1063
1064/***********************************************************************
1065 * SetupDiClassNameFromGuidW (SETUPAPI.@)
1066 */
1068 const GUID* ClassGuid,
1069 PWSTR ClassName,
1070 DWORD ClassNameSize,
1072{
1073 return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
1074 ClassNameSize, RequiredSize,
1075 NULL, NULL);
1076}
1077
1078/***********************************************************************
1079 * SetupDiClassNameFromGuidExA (SETUPAPI.@)
1080 */
1082 const GUID* ClassGuid,
1083 PSTR ClassName,
1084 DWORD ClassNameSize,
1088{
1089 WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
1090 LPWSTR MachineNameW = NULL;
1091 BOOL ret;
1092
1093 if (MachineName)
1096 RequiredSize, MachineNameW, Reserved);
1097 if (ret)
1098 {
1099 int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
1100 ClassNameSize, NULL, NULL);
1101 if (len == 0 || len > ClassNameSize)
1102 {
1104 ret = FALSE;
1105 }
1106 }
1107 MyFree(MachineNameW);
1108 return ret;
1109}
1110
1111/***********************************************************************
1112 * SetupDiClassNameFromGuidExW (SETUPAPI.@)
1113 */
1115 const GUID* ClassGuid,
1116 PWSTR ClassName,
1117 DWORD ClassNameSize,
1121{
1122 HKEY hKey;
1124 DWORD dwRegType;
1125 LONG rc;
1126 PWSTR Buffer;
1127
1128 TRACE("%s(%s %p %lu %p %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), ClassName,
1129 ClassNameSize, RequiredSize, debugstr_w(MachineName), Reserved);
1130
1131 /* Make sure there's a GUID */
1132 if (ClassGuid == NULL)
1133 {
1134 SetLastError(ERROR_INVALID_CLASS); /* On Vista: ERROR_INVALID_USER_BUFFER */
1135 return FALSE;
1136 }
1137
1138 /* Make sure there's a real buffer when there's a size */
1139 if ((ClassNameSize > 0) && (ClassName == NULL))
1140 {
1141 SetLastError(ERROR_INVALID_PARAMETER); /* On Vista: ERROR_INVALID_USER_BUFFER */
1142 return FALSE;
1143 }
1144
1145 /* Open the key for the GUID */
1147
1149 return FALSE;
1150
1151 /* Retrieve the class name data and close the key */
1152 rc = QueryRegistryValue(hKey, REGSTR_VAL_CLASS, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
1154
1155 /* Make sure we got the data */
1156 if (rc != ERROR_SUCCESS)
1157 {
1158 SetLastError(rc);
1159 return FALSE;
1160 }
1161
1162 /* Make sure the data is a string */
1163 if (dwRegType != REG_SZ)
1164 {
1165 MyFree(Buffer);
1167 return FALSE;
1168 }
1169
1170 /* Determine the length of the class name */
1171 dwLength /= sizeof(WCHAR);
1172
1173 if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
1174 /* Count the null-terminator */
1175 dwLength++;
1176
1177 /* Inform the caller about the class name */
1178 if ((ClassName != NULL) && (dwLength <= ClassNameSize))
1179 {
1180 memcpy(ClassName, Buffer, (dwLength - 1) * sizeof(WCHAR));
1181 ClassName[dwLength - 1] = UNICODE_NULL;
1182 }
1183
1184 /* Inform the caller about the required size */
1185 if (RequiredSize != NULL)
1187
1188 /* Clean up the buffer */
1189 MyFree(Buffer);
1190
1191 /* Make sure the buffer was large enough */
1192 if ((ClassName == NULL) || (dwLength > ClassNameSize))
1193 {
1195 return FALSE;
1196 }
1197
1198 return TRUE;
1199}
1200
1201/***********************************************************************
1202 * SetupDiCreateDeviceInfoList (SETUPAPI.@)
1203 */
1207{
1209}
1210
1211/***********************************************************************
1212 * SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
1213 */
1219{
1220 LPWSTR MachineNameW = NULL;
1221 HDEVINFO hDevInfo;
1222
1223 TRACE("%s(%s %p %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), hwndParent,
1225
1226 if (MachineName)
1227 {
1229 if (MachineNameW == NULL)
1230 return INVALID_HANDLE_VALUE;
1231 }
1232
1234 MachineNameW, Reserved);
1235
1236 MyFree(MachineNameW);
1237
1238 return hDevInfo;
1239}
1240
1241/***********************************************************************
1242 * SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
1243 *
1244 * Create an empty DeviceInfoSet list.
1245 *
1246 * PARAMS
1247 * ClassGuid [I] if not NULL only devices with GUID ClassGuid are associated
1248 * with this list.
1249 * hwndParent [I] hwnd needed for interface related actions.
1250 * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
1251 * local registry will be used.
1252 * Reserved [I] must be NULL
1253 *
1254 * RETURNS
1255 * Success: empty list.
1256 * Failure: INVALID_HANDLE_VALUE.
1257 */
1263{
1264 struct DeviceInfoSet *list = NULL;
1266 DWORD rc;
1267 CONFIGRET cr;
1269
1270 TRACE("%s(%s %p %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), hwndParent,
1272
1273 if (MachineName != NULL)
1274 {
1276 if (len >= SP_MAX_MACHINENAME_LENGTH - 4)
1277 {
1279 goto cleanup;
1280 }
1281 if(len > 0)
1282 size += (len + 3) * sizeof(WCHAR);
1283 else
1284 MachineName = NULL;
1285 }
1286
1287 if (Reserved != NULL)
1288 {
1290 return INVALID_HANDLE_VALUE;
1291 }
1292
1293 list = MyMalloc(size);
1294 if (!list)
1295 {
1297 return INVALID_HANDLE_VALUE;
1298 }
1300
1302 memcpy(&list->ClassGuid,
1304 sizeof(list->ClassGuid));
1305 list->InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
1306 list->InstallParams.Flags |= DI_CLASSINSTALLPARAMS;
1307 list->InstallParams.hwndParent = hwndParent;
1308 if (MachineName)
1309 {
1311 if (rc != ERROR_SUCCESS)
1312 {
1314 goto cleanup;
1315 }
1316
1317 list->szData[0] = list->szData[1] = '\\';
1318 strcpyW(list->szData + 2, MachineName);
1319 list->MachineName = list->szData;
1320 }
1321 else
1322 {
1323 list->HKLM = HKEY_LOCAL_MACHINE;
1324 list->MachineName = NULL;
1325 }
1326 cr = CM_Connect_MachineW(list->MachineName, &list->hMachine);
1327 if (cr != CR_SUCCESS)
1328 {
1330 goto cleanup;
1331 }
1332 InitializeListHead(&list->DriverListHead);
1333 InitializeListHead(&list->ListHead);
1334
1335 return (HDEVINFO)list;
1336
1337cleanup:
1339 {
1340 if (list)
1341 {
1342 if (list->HKLM != NULL && list->HKLM != HKEY_LOCAL_MACHINE)
1343 RegCloseKey(list->HKLM);
1344 MyFree(list);
1345 }
1346 }
1347 return ret;
1348}
1349
1350/***********************************************************************
1351 * SetupDiCreateDevRegKeyA (SETUPAPI.@)
1352 */
1356 DWORD Scope,
1357 DWORD HwProfile,
1358 DWORD KeyType,
1359 HINF InfHandle,
1360 PCSTR InfSectionName)
1361{
1362 PWSTR InfSectionNameW = NULL;
1363 HKEY key;
1364
1365 TRACE("%s(%p %p %d %d %d %p %s)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, Scope,
1366 HwProfile, KeyType, InfHandle, debugstr_a(InfSectionName));
1367
1368 if (InfHandle)
1369 {
1370 if (!InfSectionName)
1371 {
1373 return INVALID_HANDLE_VALUE;
1374 }
1375 else
1376 {
1377 InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
1378 if (InfSectionNameW == NULL) return INVALID_HANDLE_VALUE;
1379 }
1380 }
1382 HwProfile, KeyType, InfHandle, InfSectionNameW);
1383 MyFree(InfSectionNameW);
1384 return key;
1385}
1386
1387static HKEY
1389 IN HKEY HKLM,
1390 IN DWORD HwProfile,
1391 IN DWORD samDesired);
1392
1393/***********************************************************************
1394 * SetupDiCreateDevRegKeyW (SETUPAPI.@)
1395 */
1399 DWORD Scope,
1400 DWORD HwProfile,
1401 DWORD KeyType,
1402 HINF InfHandle,
1403 PCWSTR InfSectionName)
1404{
1405 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
1406 struct DeviceInfo *deviceInfo;
1408 DWORD rc;
1409 HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
1410 HKEY hKey = NULL;
1411 HKEY RootKey;
1412
1413 TRACE("%s(%p %p %lu %lu %lu %p %s)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, Scope,
1414 HwProfile, KeyType, InfHandle, debugstr_w(InfSectionName));
1415
1417 {
1419 return INVALID_HANDLE_VALUE;
1420 }
1421 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
1422 {
1424 return INVALID_HANDLE_VALUE;
1425 }
1428 {
1430 return INVALID_HANDLE_VALUE;
1431 }
1432 if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
1433 {
1435 return INVALID_HANDLE_VALUE;
1436 }
1437 if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
1438 {
1440 return INVALID_HANDLE_VALUE;
1441 }
1442 if (InfHandle && !InfSectionName)
1443 {
1445 return INVALID_HANDLE_VALUE;
1446 }
1447 if (!InfHandle && InfSectionName)
1448 {
1450 return INVALID_HANDLE_VALUE;
1451 }
1452
1453 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
1454
1455 if (Scope == DICS_FLAG_GLOBAL)
1456 RootKey = set->HKLM;
1457 else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
1458 {
1459 hHWProfileKey = OpenHardwareProfileKey(set->HKLM, HwProfile, KEY_CREATE_SUB_KEY);
1460 if (hHWProfileKey == INVALID_HANDLE_VALUE)
1461 goto cleanup;
1462 RootKey = hHWProfileKey;
1463 }
1464
1465 if (KeyType == DIREG_DEV)
1466 {
1467#if _WIN32_WINNT >= 0x502
1469#else
1471#endif
1473 goto cleanup;
1474
1475 if (Scope == DICS_FLAG_GLOBAL)
1476 {
1477 HKEY hTempKey = hKey;
1478
1479 rc = RegCreateKeyExW(hTempKey,
1480 L"Device Parameters",
1481 0,
1482 NULL,
1484#if _WIN32_WINNT >= 0x502
1486#else
1488#endif
1489 NULL,
1490 &hKey,
1491 NULL);
1492 if (rc == ERROR_SUCCESS)
1493 RegCloseKey(hTempKey);
1494 }
1495 }
1496 else /* KeyType == DIREG_DRV */
1497 {
1498#if _WIN32_WINNT >= 0x502
1500#else
1502#endif
1504 goto cleanup;
1505 }
1506
1507 /* Do installation of the specified section */
1508 if (InfHandle)
1509 {
1510 FIXME("Need to install section %s in file %p\n",
1511 debugstr_w(InfSectionName), InfHandle);
1512 }
1513 key = hKey;
1514
1515cleanup:
1516 if (hHWProfileKey != INVALID_HANDLE_VALUE)
1517 RegCloseKey(hHWProfileKey);
1518 if (hKey != NULL && hKey != key)
1520
1521 TRACE("Returning 0x%p\n", key);
1522 return key;
1523}
1524
1525/***********************************************************************
1526 * SetupDiCreateDeviceInfoA (SETUPAPI.@)
1527 */
1536{
1537 BOOL ret;
1538 LPWSTR DeviceNameW = NULL;
1539 LPWSTR DeviceDescriptionW = NULL;
1540
1541 TRACE("\n");
1542
1543 if (DeviceName)
1544 {
1546 if (DeviceNameW == NULL) return FALSE;
1547 }
1549 {
1550 DeviceDescriptionW = pSetupMultiByteToUnicode(DeviceDescription, CP_ACP);
1551 if (DeviceDescriptionW == NULL)
1552 {
1553 MyFree(DeviceNameW);
1554 return FALSE;
1555 }
1556 }
1557
1558 ret = SetupDiCreateDeviceInfoW(DeviceInfoSet, DeviceNameW, ClassGuid, DeviceDescriptionW,
1560
1561 MyFree(DeviceNameW);
1562 MyFree(DeviceDescriptionW);
1563
1564 return ret;
1565}
1566
1567/***********************************************************************
1568 * SetupDiCreateDeviceInfoW (SETUPAPI.@)
1569 */
1578{
1579 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
1580 struct DeviceInfo *deviceInfo = NULL;
1581 BOOL ret = FALSE;
1582 CONFIGRET cr;
1583 DEVINST RootDevInst;
1584 DEVINST DevInst;
1585 WCHAR GenInstanceId[MAX_DEVICE_ID_LEN];
1586 DWORD dwFlags;
1587
1588 TRACE("%s(%p %s %s %s %p %x %p)\n", __FUNCTION__, DeviceInfoSet, debugstr_w(DeviceName),
1591
1592 if (!DeviceName)
1593 {
1595 return FALSE;
1596 }
1598 {
1600 return FALSE;
1601 }
1602 if (!ClassGuid)
1603 {
1605 return FALSE;
1606 }
1607 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
1608 {
1610 return FALSE;
1611 }
1612 if (!IsEqualGUID(&set->ClassGuid, &GUID_NULL) &&
1613 !IsEqualGUID(ClassGuid, &set->ClassGuid))
1614 {
1616 return FALSE;
1617 }
1619 {
1620 TRACE("Unknown flags: 0x%08lx\n", CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS));
1622 return FALSE;
1623 }
1624
1625 /* Get the root device instance */
1626 cr = CM_Locate_DevInst_ExW(&RootDevInst,
1627 NULL,
1629 set->hMachine);
1630 if (cr != CR_SUCCESS)
1631 {
1633 return FALSE;
1634 }
1635
1639
1640 /* Create the new device instance */
1641 cr = CM_Create_DevInst_ExW(&DevInst,
1643 RootDevInst,
1644 dwFlags,
1645 set->hMachine);
1646 if (cr != CR_SUCCESS)
1647 {
1649 return FALSE;
1650 }
1651
1653 {
1654 /* Grab the actual instance ID that was created */
1655 cr = CM_Get_Device_ID_Ex(DevInst,
1656 GenInstanceId,
1658 0,
1659 set->hMachine);
1660 if (cr != CR_SUCCESS)
1661 {
1663 return FALSE;
1664 }
1665
1666 DeviceName = GenInstanceId;
1667 TRACE("Using generated instance ID: %s\n", debugstr_w(DeviceName));
1668 }
1669
1670 if (CreateDeviceInfo(set, DeviceName, ClassGuid, &deviceInfo))
1671 {
1672 InsertTailList(&set->ListHead, &deviceInfo->ListEntry);
1673
1674 if (!DeviceInfoData)
1675 ret = TRUE;
1676 else
1677 {
1678 if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
1679 {
1681 }
1682 else
1683 {
1685 DeviceInfoData->DevInst = deviceInfo->dnDevInst;
1686 DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
1687 ret = TRUE;
1688 }
1689 }
1690 }
1691
1692 if (ret == FALSE)
1693 {
1694 if (deviceInfo != NULL)
1695 {
1696 /* Remove deviceInfo from List */
1697 RemoveEntryList(&deviceInfo->ListEntry);
1698
1699 /* Destroy deviceInfo */
1700 DestroyDeviceInfo(deviceInfo);
1701 }
1702 }
1703
1704 TRACE("Returning %d\n", ret);
1705 return ret;
1706}
1707
1708/***********************************************************************
1709 * SetupDiRegisterDeviceInfo (SETUPAPI.@)
1710 */
1714 DWORD Flags,
1715 PSP_DETSIG_CMPPROC CompareProc,
1716 PVOID CompareContext,
1717 PSP_DEVINFO_DATA DupDeviceInfoData)
1718{
1719 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
1720 WCHAR DevInstId[MAX_DEVICE_ID_LEN];
1721 DEVINST ParentDevInst;
1722 CONFIGRET cr;
1723 DWORD dwError = ERROR_SUCCESS;
1724
1725 TRACE("%s(%p %p %08x %p %p %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, Flags,
1726 CompareProc, CompareContext, DupDeviceInfoData);
1727
1729 {
1731 return FALSE;
1732 }
1733 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
1734 {
1736 return FALSE;
1737 }
1740 {
1742 return FALSE;
1743 }
1744
1745 if (Flags & ~SPRDI_FIND_DUPS)
1746 {
1747 TRACE("Unknown flags: 0x%08lx\n", Flags & ~SPRDI_FIND_DUPS);
1749 return FALSE;
1750 }
1751
1752 if (Flags & SPRDI_FIND_DUPS)
1753 {
1754 FIXME("Unimplemented codepath!\n");
1755 }
1756
1758 DevInstId,
1760 0,
1761 set->hMachine);
1762
1763 CM_Get_Parent_Ex(&ParentDevInst,
1765 0,
1766 set->hMachine);
1767
1769 DevInstId,
1770 ParentDevInst,
1772 set->hMachine);
1773 if (cr != CR_SUCCESS &&
1775 {
1776 dwError = ERROR_NO_SUCH_DEVINST;
1777 }
1778
1779 SetLastError(dwError);
1780
1781 return (dwError == ERROR_SUCCESS);
1782}
1783
1784/***********************************************************************
1785 * SetupDiEnumDeviceInfo (SETUPAPI.@)
1786 */
1788 HDEVINFO devinfo,
1789 DWORD index,
1791{
1792 BOOL ret = FALSE;
1793
1794 TRACE("%s(%p %d %p)\n", __FUNCTION__, devinfo, index, info);
1795
1796 if(info==NULL)
1797 {
1799 return FALSE;
1800 }
1801 if (devinfo && devinfo != INVALID_HANDLE_VALUE)
1802 {
1803 struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
1804 if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
1805 {
1806 if (info->cbSize != sizeof(SP_DEVINFO_DATA))
1808 else
1809 {
1810 PLIST_ENTRY ItemList = list->ListHead.Flink;
1811 while (ItemList != &list->ListHead && index-- > 0)
1812 ItemList = ItemList->Flink;
1813 if (ItemList == &list->ListHead)
1815 else
1816 {
1817 struct DeviceInfo *DevInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
1818 memcpy(&info->ClassGuid,
1819 &DevInfo->ClassGuid,
1820 sizeof(GUID));
1821 info->DevInst = DevInfo->dnDevInst;
1822 info->Reserved = (ULONG_PTR)DevInfo;
1823 ret = TRUE;
1824 }
1825 }
1826 }
1827 else
1829 }
1830 else
1832 return ret;
1833}
1834
1835/***********************************************************************
1836 * SetupDiGetDeviceInstanceIdA (SETUPAPI.@)
1837 */
1841 PSTR DeviceInstanceId,
1842 DWORD DeviceInstanceIdSize,
1844{
1845 BOOL ret = FALSE;
1846 DWORD size;
1848
1849 TRACE("%s(%p %p %p %d %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, DeviceInstanceId,
1850 DeviceInstanceIdSize, RequiredSize);
1851
1852 if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
1853 {
1855 return FALSE;
1856 }
1857
1860 NULL,
1861 0,
1862 &size);
1864 return FALSE;
1865 instanceId = MyMalloc(size * sizeof(WCHAR));
1866 if (instanceId)
1867 {
1870 instanceId,
1871 size,
1872 &size);
1873 if (ret)
1874 {
1876 DeviceInstanceId,
1877 DeviceInstanceIdSize, NULL, NULL);
1878
1879 if (!len)
1880 ret = FALSE;
1881 else
1882 {
1883 if (len > DeviceInstanceIdSize)
1884 {
1886 ret = FALSE;
1887 }
1888 if (RequiredSize)
1889 *RequiredSize = len;
1890 }
1891 }
1893 }
1894 else
1895 {
1896 if (RequiredSize)
1897 *RequiredSize = size;
1899 ret = FALSE;
1900 }
1901 return ret;
1902}
1903
1904/***********************************************************************
1905 * SetupDiGetDeviceInstanceIdW (SETUPAPI.@)
1906 */
1910 PWSTR DeviceInstanceId,
1911 DWORD DeviceInstanceIdSize,
1913{
1914 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
1915 struct DeviceInfo *devInfo;
1916
1917 TRACE("%s(%p %p %p %d %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, DeviceInstanceId,
1918 DeviceInstanceIdSize, RequiredSize);
1919
1921 {
1923 return FALSE;
1924 }
1925 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
1926 {
1928 return FALSE;
1929 }
1932 {
1934 return FALSE;
1935 }
1936 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
1937 if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
1938 {
1940 return FALSE;
1941 }
1942 if (DeviceInstanceId && DeviceInstanceIdSize == 0)
1943 {
1945 return FALSE;
1946 }
1947 TRACE("instance ID: %s\n", debugstr_w(devInfo->instanceId));
1948 if (DeviceInstanceIdSize < lstrlenW(devInfo->instanceId) + 1)
1949 {
1951 if (RequiredSize)
1952 *RequiredSize = lstrlenW(devInfo->instanceId) + 1;
1953 return FALSE;
1954 }
1955 lstrcpyW(DeviceInstanceId, devInfo->instanceId);
1956 if (RequiredSize)
1957 *RequiredSize = lstrlenW(devInfo->instanceId) + 1;
1958 return TRUE;
1959}
1960
1961/***********************************************************************
1962 * SetupDiGetActualSectionToInstallA (SETUPAPI.@)
1963 */
1965 HINF InfHandle,
1966 PCSTR InfSectionName,
1967 PSTR InfSectionWithExt,
1968 DWORD InfSectionWithExtSize,
1970 PSTR *Extension)
1971{
1972 return SetupDiGetActualSectionToInstallExA(InfHandle, InfSectionName,
1973 NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
1974 Extension, NULL);
1975}
1976
1977/***********************************************************************
1978 * SetupDiGetActualSectionToInstallW (SETUPAPI.@)
1979 */
1981 HINF InfHandle,
1982 PCWSTR InfSectionName,
1983 PWSTR InfSectionWithExt,
1984 DWORD InfSectionWithExtSize,
1987{
1988 return SetupDiGetActualSectionToInstallExW(InfHandle, InfSectionName,
1989 NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
1990 Extension, NULL);
1991}
1992
1993/***********************************************************************
1994 * SetupDiGetActualSectionToInstallExA (SETUPAPI.@)
1995 */
1998 IN HINF InfHandle,
1999 IN PCSTR InfSectionName,
2000 IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
2001 OUT PSTR InfSectionWithExt OPTIONAL,
2002 IN DWORD InfSectionWithExtSize,
2006{
2007 LPWSTR InfSectionNameW = NULL;
2008 LPWSTR InfSectionWithExtW = NULL;
2009 PWSTR ExtensionW;
2010 BOOL bResult = FALSE;
2011
2012 TRACE("%s()\n", __FUNCTION__);
2013
2014 if (InfSectionName)
2015 {
2016 InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
2017 if (InfSectionNameW == NULL)
2018 goto cleanup;
2019 }
2020 if (InfSectionWithExt)
2021 {
2022 InfSectionWithExtW = MyMalloc(InfSectionWithExtSize * sizeof(WCHAR));
2023 if (InfSectionWithExtW == NULL)
2024 goto cleanup;
2025 }
2026
2028 InfHandle, InfSectionNameW, AlternatePlatformInfo,
2029 InfSectionWithExt ? InfSectionWithExtW : NULL,
2030 InfSectionWithExtSize,
2032 Extension ? &ExtensionW : NULL,
2033 Reserved);
2034
2035 if (bResult && InfSectionWithExt)
2036 {
2037 bResult = WideCharToMultiByte(CP_ACP, 0, InfSectionWithExtW, -1, InfSectionWithExt,
2038 InfSectionWithExtSize, NULL, NULL) != 0;
2039 }
2040 if (bResult && Extension)
2041 {
2042 if (ExtensionW == NULL)
2043 *Extension = NULL;
2044 else
2045 *Extension = &InfSectionWithExt[ExtensionW - InfSectionWithExtW];
2046 }
2047
2048cleanup:
2049 MyFree(InfSectionNameW);
2050 MyFree(InfSectionWithExtW);
2051
2052 return bResult;
2053}
2054
2055/***********************************************************************
2056 * SetupDiGetClassDescriptionA (SETUPAPI.@)
2057 */
2059 const GUID* ClassGuid,
2060 PSTR ClassDescription,
2061 DWORD ClassDescriptionSize,
2063{
2064 return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
2065 ClassDescriptionSize,
2067}
2068
2069/***********************************************************************
2070 * SetupDiGetClassDescriptionW (SETUPAPI.@)
2071 */
2073 const GUID* ClassGuid,
2074 PWSTR ClassDescription,
2075 DWORD ClassDescriptionSize,
2077{
2078 return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
2079 ClassDescriptionSize,
2081}
2082
2083/***********************************************************************
2084 * SetupDiGetClassDescriptionExA (SETUPAPI.@)
2085 */
2087 const GUID* ClassGuid,
2088 PSTR ClassDescription,
2089 DWORD ClassDescriptionSize,
2093{
2094 PWCHAR ClassDescriptionW = NULL;
2095 LPWSTR MachineNameW = NULL;
2096 BOOL ret = FALSE;
2097
2098 TRACE("%s(%s %p %lu %p %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), ClassDescription,
2099 ClassDescriptionSize, RequiredSize, debugstr_a(MachineName), Reserved);
2100
2101 if (ClassDescriptionSize > 0)
2102 {
2103 ClassDescriptionW = MyMalloc(ClassDescriptionSize * sizeof(WCHAR));
2104 if (!ClassDescriptionW)
2105 {
2107 goto cleanup;
2108 }
2109 }
2110
2111 if (MachineName)
2112 {
2114 if (!MachineNameW)
2115 {
2117 goto cleanup;
2118 }
2119 }
2120
2121 ret = SetupDiGetClassDescriptionExW(ClassGuid, ClassDescriptionW,
2122 ClassDescriptionSize * sizeof(WCHAR), RequiredSize, MachineNameW, Reserved);
2123 if (ret)
2124 {
2125 DWORD len = (DWORD)WideCharToMultiByte(CP_ACP, 0, ClassDescriptionW, -1, ClassDescription,
2126 ClassDescriptionSize, NULL, NULL);
2127 if (len == 0 || len > ClassDescriptionSize)
2128 {
2130 ret = FALSE;
2131 }
2132 }
2133
2134cleanup:
2135 MyFree(ClassDescriptionW);
2136 MyFree(MachineNameW);
2137 return ret;
2138}
2139
2140/***********************************************************************
2141 * SetupDiGetClassDescriptionExW (SETUPAPI.@)
2142 */
2144 const GUID* ClassGuid,
2145 PWSTR ClassDescription,
2146 DWORD ClassDescriptionSize,
2150{
2151 HKEY hKey;
2153 DWORD dwRegType;
2154 LONG rc;
2155 PWSTR Buffer;
2156
2157 TRACE("%s(%s %p %lu %p %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), ClassDescription,
2158 ClassDescriptionSize, RequiredSize, debugstr_w(MachineName), Reserved);
2159
2160 /* Make sure there's a GUID */
2161 if (!ClassGuid)
2162 {
2164 return FALSE;
2165 }
2166
2167 /* Make sure there's a real buffer when there's a size */
2168 if (!ClassDescription && ClassDescriptionSize > 0)
2169 {
2171 return FALSE;
2172 }
2173
2174 /* Open the key for the GUID */
2179 Reserved);
2181 return FALSE;
2182
2183 /* Retrieve the class description data and close the key */
2184 rc = QueryRegistryValue(hKey, NULL, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
2186
2187 /* Make sure we got the data */
2188 if (rc != ERROR_SUCCESS)
2189 {
2190 SetLastError(rc);
2191 return FALSE;
2192 }
2193
2194 /* Make sure the data is a string */
2195 if (dwRegType != REG_SZ)
2196 {
2197 MyFree(Buffer);
2199 return FALSE;
2200 }
2201
2202 /* Determine the length of the class description */
2203 dwLength /= sizeof(WCHAR);
2204
2205 /* Count the null-terminator if none is present */
2206 if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
2207 dwLength++;
2208
2209 /* Inform the caller about the class description */
2210 if ((ClassDescription != NULL) && (dwLength <= ClassDescriptionSize))
2211 {
2212 memcpy(ClassDescription, Buffer, (dwLength - 1) * sizeof(WCHAR));
2213 ClassDescription[dwLength - 1] = UNICODE_NULL;
2214 }
2215
2216 /* Inform the caller about the required size */
2217 if (RequiredSize != NULL)
2219
2220 /* Clean up the buffer */
2221 MyFree(Buffer);
2222
2223 /* Make sure the buffer was large enough */
2224 if ((ClassDescription == NULL) || (dwLength > ClassDescriptionSize))
2225 {
2227 return FALSE;
2228 }
2229
2230 return TRUE;
2231}
2232
2233/***********************************************************************
2234 * SetupDiGetClassDevsA (SETUPAPI.@)
2235 */
2237 CONST GUID *class,
2238 LPCSTR enumstr,
2239 HWND parent,
2240 DWORD flags)
2241{
2242 return SetupDiGetClassDevsExA(class, enumstr, parent,
2243 flags, NULL, NULL, NULL);
2244}
2245
2246/***********************************************************************
2247 * SetupDiGetClassDevsExA (SETUPAPI.@)
2248 */
2250 const GUID *class,
2251 PCSTR enumstr,
2252 HWND parent,
2253 DWORD flags,
2254 HDEVINFO deviceset,
2255 PCSTR machine,
2257{
2258 HDEVINFO ret;
2259 LPWSTR enumstrW = NULL, machineW = NULL;
2260
2261 if (enumstr)
2262 {
2263 enumstrW = pSetupMultiByteToUnicode(enumstr, CP_ACP);
2264 if (!enumstrW)
2265 {
2267 goto end;
2268 }
2269 }
2270 if (machine)
2271 {
2273 if (!machineW)
2274 {
2275 MyFree(enumstrW);
2277 goto end;
2278 }
2279 }
2280 ret = SetupDiGetClassDevsExW(class, enumstrW, parent, flags, deviceset,
2282 MyFree(enumstrW);
2284
2285end:
2286 return ret;
2287}
2288
2289/***********************************************************************
2290 * SetupDiGetClassDevsW (SETUPAPI.@)
2291 */
2293 CONST GUID *class,
2294 LPCWSTR enumstr,
2295 HWND parent,
2296 DWORD flags)
2297{
2298 return SetupDiGetClassDevsExW(class, enumstr, parent, flags, NULL, NULL,
2299 NULL);
2300}
2301
2302/***********************************************************************
2303 * SetupDiGetClassDevsExW (SETUPAPI.@)
2304 */
2306 CONST GUID *class,
2307 PCWSTR enumstr,
2308 HWND parent,
2309 DWORD flags,
2310 HDEVINFO deviceset,
2313{
2314 HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
2315 struct DeviceInfoSet *list;
2316 CONST GUID *pClassGuid;
2317 LONG rc;
2319
2320 TRACE("%s(%s %s %p 0x%08x %p %s %p)\n", __FUNCTION__, debugstr_guid(class),
2321 debugstr_w(enumstr), parent, flags, deviceset, debugstr_w(machine),
2322 reserved);
2323
2324 if (!(flags & DIGCF_ALLCLASSES) && !class)
2325 {
2327 return INVALID_HANDLE_VALUE;
2328 }
2329
2330 /* Create the deviceset if not set */
2331 if (deviceset)
2332 {
2333 list = (struct DeviceInfoSet *)deviceset;
2334 if (list->magic != SETUP_DEVICE_INFO_SET_MAGIC)
2335 {
2337 goto cleanup;
2338 }
2339 hDeviceInfo = deviceset;
2340 }
2341 else
2342 {
2343 hDeviceInfo = SetupDiCreateDeviceInfoListExW(
2345 NULL, machine, NULL);
2346 if (hDeviceInfo == INVALID_HANDLE_VALUE)
2347 goto cleanup;
2348 list = (struct DeviceInfoSet *)hDeviceInfo;
2349 }
2350
2351 if (flags & DIGCF_PROFILE)
2352 FIXME(": flag DIGCF_PROFILE ignored\n");
2353
2355 {
2356 if (!class)
2357 {
2359 goto cleanup;
2360 }
2361 rc = SETUP_CreateInterfaceList(list, machine, class, enumstr, flags & DIGCF_PRESENT);
2362 }
2363 else
2364 {
2365 /* Determine which class(es) should be included in the deviceset */
2366 if (flags & DIGCF_ALLCLASSES)
2367 {
2368 /* The caller wants all classes. Check if
2369 * the deviceset limits us to one class */
2370 if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
2371 pClassGuid = NULL;
2372 else
2373 pClassGuid = &list->ClassGuid;
2374 }
2375 else if (class)
2376 {
2377 /* The caller wants one class. Check if it matches deviceset class */
2378 if (IsEqualIID(&list->ClassGuid, class)
2379 || IsEqualIID(&list->ClassGuid, &GUID_NULL))
2380 {
2381 pClassGuid = class;
2382 }
2383 else
2384 {
2386 goto cleanup;
2387 }
2388 }
2389 else if (!IsEqualIID(&list->ClassGuid, &GUID_NULL))
2390 {
2391 /* No class specified. Try to use the one of the deviceset */
2392 if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
2393 pClassGuid = &list->ClassGuid;
2394 else
2395 {
2397 goto cleanup;
2398 }
2399 }
2400 else
2401 {
2403 goto cleanup;
2404 }
2405 rc = SETUP_CreateDevicesList(list, machine, pClassGuid, enumstr);
2406 }
2407 if (rc != ERROR_SUCCESS)
2408 {
2409 SetLastError(rc);
2410 goto cleanup;
2411 }
2412 set = hDeviceInfo;
2413
2414cleanup:
2415 if (!deviceset && hDeviceInfo != INVALID_HANDLE_VALUE && hDeviceInfo != set)
2416 SetupDiDestroyDeviceInfoList(hDeviceInfo);
2417 return set;
2418}
2419
2420/***********************************************************************
2421 * SetupDiGetDeviceInfoListDetailA (SETUPAPI.@)
2422 */
2425 PSP_DEVINFO_LIST_DETAIL_DATA_A DevInfoData )
2426{
2427 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2428
2429 TRACE("%s(%p %p)\n", __FUNCTION__, DeviceInfoSet, DevInfoData);
2430
2432 {
2434 return FALSE;
2435 }
2436 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
2437 {
2439 return FALSE;
2440 }
2441 if (!DevInfoData ||
2442 DevInfoData->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_A))
2443 {
2445 return FALSE;
2446 }
2447 memcpy(&DevInfoData->ClassGuid, &set->ClassGuid, sizeof(GUID));
2448 DevInfoData->RemoteMachineHandle = set->hMachine;
2449 if (set->MachineName)
2450 {
2451 FIXME("Stub\n");
2453 return FALSE;
2454 }
2455 else
2456 DevInfoData->RemoteMachineName[0] = 0;
2457
2458 return TRUE;
2459}
2460
2461/***********************************************************************
2462 * SetupDiGetDeviceInfoListDetailW (SETUPAPI.@)
2463 */
2466 PSP_DEVINFO_LIST_DETAIL_DATA_W DevInfoData )
2467{
2468 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2469
2470 TRACE("%s(%p %p)\n", __FUNCTION__, DeviceInfoSet, DevInfoData);
2471
2473 {
2475 return FALSE;
2476 }
2477 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
2478 {
2480 return FALSE;
2481 }
2482 if (!DevInfoData ||
2483 DevInfoData->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_W))
2484 {
2486 return FALSE;
2487 }
2488 memcpy(&DevInfoData->ClassGuid, &set->ClassGuid, sizeof(GUID));
2489 DevInfoData->RemoteMachineHandle = set->hMachine;
2490 if (set->MachineName)
2491 strcpyW(DevInfoData->RemoteMachineName, set->MachineName + 2);
2492 else
2493 DevInfoData->RemoteMachineName[0] = 0;
2494
2495 return TRUE;
2496}
2497
2498/***********************************************************************
2499 * SetupDiCreateDeviceInterfaceA (SETUPAPI.@)
2500 */
2504 const GUID *InterfaceClassGuid,
2506 DWORD CreationFlags,
2507 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
2508{
2509 BOOL ret;
2510 LPWSTR ReferenceStringW = NULL;
2511
2512 TRACE("%s(%p %p %s %s %08x %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
2514 CreationFlags, DeviceInterfaceData);
2515
2516 if (ReferenceString)
2517 {
2518 ReferenceStringW = pSetupMultiByteToUnicode(ReferenceString, CP_ACP);
2519 if (ReferenceStringW == NULL) return FALSE;
2520 }
2521
2523 InterfaceClassGuid, ReferenceStringW, CreationFlags,
2524 DeviceInterfaceData);
2525
2526 MyFree(ReferenceStringW);
2527
2528 return ret;
2529}
2530
2531/***********************************************************************
2532 * SetupDiCreateDeviceInterfaceW (SETUPAPI.@)
2533 */
2537 const GUID *InterfaceClassGuid,
2539 DWORD CreationFlags,
2540 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
2541{
2542 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2543 TRACE("%s(%p %p %s %s %08x %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
2545 CreationFlags, DeviceInterfaceData);
2546
2548 {
2550 return FALSE;
2551 }
2552 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
2553 {
2555 return FALSE;
2556 }
2559 {
2561 return FALSE;
2562 }
2563 if (!InterfaceClassGuid)
2564 {
2566 return FALSE;
2567 }
2568
2569 FIXME("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData,
2571 CreationFlags, DeviceInterfaceData);
2573 return FALSE;
2574}
2575
2576/***********************************************************************
2577 * SetupDiCreateDeviceInterfaceRegKeyA (SETUPAPI.@)
2578 */
2581 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
2583 REGSAM samDesired,
2584 HINF InfHandle,
2585 PCSTR InfSectionName)
2586{
2587 HKEY key;
2588 PWSTR InfSectionNameW = NULL;
2589
2590 TRACE("%s(%p %p %d %08x %p %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInterfaceData, Reserved,
2591 samDesired, InfHandle, InfSectionName);
2592 if (InfHandle)
2593 {
2594 if (!InfSectionName)
2595 {
2597 return INVALID_HANDLE_VALUE;
2598 }
2599 InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
2600 if (!InfSectionNameW)
2601 return INVALID_HANDLE_VALUE;
2602 }
2604 DeviceInterfaceData, Reserved, samDesired, InfHandle,
2605 InfSectionNameW);
2606 MyFree(InfSectionNameW);
2607 return key;
2608}
2609
2610/***********************************************************************
2611 * SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@)
2612 */
2615 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
2617 REGSAM samDesired,
2618 HINF InfHandle,
2619 PCWSTR InfSectionName)
2620{
2621 HKEY hKey, hDevKey;
2624 LONG rc;
2625 WCHAR bracedGuidString[39];
2626 struct DeviceInterface *DevItf;
2627 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2628
2629 TRACE("%s(%p %p %d %08x %p %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInterfaceData, Reserved,
2630 samDesired, InfHandle, InfSectionName);
2631
2634 {
2636 return INVALID_HANDLE_VALUE;
2637 }
2638 if (!DeviceInterfaceData ||
2639 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
2640 !DeviceInterfaceData->Reserved)
2641 {
2643 return INVALID_HANDLE_VALUE;
2644 }
2645 if (InfHandle && !InfSectionName)
2646 {
2648 return INVALID_HANDLE_VALUE;
2649 }
2650
2651 hKey = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid, samDesired, DIOCR_INTERFACE, NULL, NULL);
2653 {
2656 {
2658 return INVALID_HANDLE_VALUE;
2659 }
2660 SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid, bracedGuidString);
2661
2662 if (RegCreateKeyExW(hKey, bracedGuidString, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL) != ERROR_SUCCESS)
2663 {
2665 return INVALID_HANDLE_VALUE;
2666 }
2668 hKey = hDevKey;
2669 }
2670
2671 DevItf = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
2672
2673 Length = (wcslen(DevItf->SymbolicLink)+1) * sizeof(WCHAR);
2675 if (!SymbolicLink)
2676 {
2679 return INVALID_HANDLE_VALUE;
2680 }
2681
2683
2684 Index = 0;
2685 while(SymbolicLink[Index])
2686 {
2687 if (SymbolicLink[Index] == L'\\')
2688 {
2689 SymbolicLink[Index] = L'#';
2690 }
2691 Index++;
2692 }
2693
2694 rc = RegCreateKeyExW(hKey, SymbolicLink, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL);
2695
2698
2699 if (rc == ERROR_SUCCESS)
2700 {
2701 if (InfHandle && InfSectionName)
2702 {
2703 if (!SetupInstallFromInfSection(NULL /*FIXME */,
2704 InfHandle,
2705 InfSectionName,
2707 hDevKey,
2708 NULL,
2709 0,
2710 set->SelectedDevice->InstallParams.InstallMsgHandler,
2711 set->SelectedDevice->InstallParams.InstallMsgHandlerContext,
2713 NULL))
2714 {
2715 RegCloseKey(hDevKey);
2716 return INVALID_HANDLE_VALUE;
2717 }
2718 }
2719 }
2720
2721 SetLastError(rc);
2722 return hDevKey;
2723}
2724
2725/***********************************************************************
2726 * SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@)
2727 */
2730 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
2732{
2733 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2734 BOOL ret = FALSE;
2735
2736 TRACE("%s(%p %p %d)\n", __FUNCTION__, DeviceInfoSet, DeviceInterfaceData, Reserved);
2737
2740 {
2742 return FALSE;
2743 }
2744 if (!DeviceInterfaceData ||
2745 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
2746 !DeviceInterfaceData->Reserved)
2747 {
2749 return FALSE;
2750 }
2751
2752 FIXME("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved);
2754 return ret;
2755}
2756
2757/***********************************************************************
2758 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
2759 *
2760 * PARAMS
2761 * DeviceInfoSet [I] Set of devices from which to enumerate
2762 * interfaces
2763 * DeviceInfoData [I] (Optional) If specified, a specific device
2764 * instance from which to enumerate interfaces.
2765 * If it isn't specified, all interfaces for all
2766 * devices in the set are enumerated.
2767 * InterfaceClassGuid [I] The interface class to enumerate.
2768 * MemberIndex [I] An index of the interface instance to enumerate.
2769 * A caller should start with MemberIndex set to 0,
2770 * and continue until the function fails with
2771 * ERROR_NO_MORE_ITEMS.
2772 * DeviceInterfaceData [I/O] Returns an enumerated interface. Its cbSize
2773 * member must be set to
2774 * sizeof(SP_DEVICE_INTERFACE_DATA).
2775 *
2776 * RETURNS
2777 * Success: non-zero value.
2778 * Failure: FALSE. Call GetLastError() for more info.
2779 */
2784 DWORD MemberIndex,
2785 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
2786{
2787 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2788 BOOL ret = FALSE;
2789
2790 TRACE("%s(%p, %p, %s, %d, %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
2791 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
2792
2795 {
2797 return FALSE;
2798 }
2801 {
2803 return FALSE;
2804 }
2805 if (!DeviceInterfaceData ||
2806 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
2807 {
2809 return FALSE;
2810 }
2811 if (DeviceInfoData)
2812 {
2813 struct DeviceInfo *devInfo =
2815 BOOL found = FALSE;
2816 PLIST_ENTRY InterfaceListEntry = devInfo->InterfaceListHead.Flink;
2817 while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
2818 {
2819 struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
2821 {
2822 InterfaceListEntry = InterfaceListEntry->Flink;
2823 continue;
2824 }
2825 if (MemberIndex-- == 0)
2826 {
2827 /* return this item */
2828 memcpy(&DeviceInterfaceData->InterfaceClassGuid,
2829 &DevItf->InterfaceClassGuid,
2830 sizeof(GUID));
2831 DeviceInterfaceData->Flags = DevItf->Flags;
2832 DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
2833 found = TRUE;
2834 ret = TRUE;
2835 }
2836 InterfaceListEntry = InterfaceListEntry->Flink;
2837 }
2838 if (!found)
2840 }
2841 else
2842 {
2843 BOOL found = FALSE;
2844 PLIST_ENTRY ItemList = set->ListHead.Flink;
2845 while (ItemList != &set->ListHead && !found)
2846 {
2847 PLIST_ENTRY InterfaceListEntry;
2848 struct DeviceInfo *devInfo =
2849 CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
2850 InterfaceListEntry = devInfo->InterfaceListHead.Flink;
2851 while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
2852 {
2853 struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
2855 {
2856 InterfaceListEntry = InterfaceListEntry->Flink;
2857 continue;
2858 }
2859 if (MemberIndex-- == 0)
2860 {
2861 /* return this item */
2862 memcpy(&DeviceInterfaceData->InterfaceClassGuid,
2863 &DevItf->InterfaceClassGuid,
2864 sizeof(GUID));
2865 DeviceInterfaceData->Flags = DevItf->Flags;
2866 DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
2867 found = TRUE;
2868 ret = TRUE;
2869 }
2870 InterfaceListEntry = InterfaceListEntry->Flink;
2871 }
2872 ItemList = ItemList->Flink;
2873
2874 }
2875 if (!found)
2877 }
2878 return ret;
2879}
2880
2881/***********************************************************************
2882 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
2883 *
2884 * Destroy a DeviceInfoList and free all used memory of the list.
2885 *
2886 * PARAMS
2887 * devinfo [I] DeviceInfoList pointer to list to destroy
2888 *
2889 * RETURNS
2890 * Success: non zero value.
2891 * Failure: zero value.
2892 */
2894{
2895 BOOL ret = FALSE;
2896
2897 TRACE("%s(%p)\n", __FUNCTION__, devinfo);
2898 if (devinfo && devinfo != INVALID_HANDLE_VALUE)
2899 {
2900 struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
2901
2902 if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
2903 {
2905 }
2906 }
2907
2908 if (ret == FALSE)
2910
2911 return ret;
2912}
2913
2914/***********************************************************************
2915 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
2916 */
2919 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
2920 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
2921 DWORD DeviceInterfaceDetailDataSize,
2924{
2925 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2926 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailDataW = NULL;
2927 DWORD sizeW = 0, bytesNeeded;
2928 BOOL ret = FALSE;
2929
2930 TRACE("%s(%p, %p, %p, %d, %p, %p)\n", __FUNCTION__, DeviceInfoSet,
2931 DeviceInterfaceData, DeviceInterfaceDetailData,
2932 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
2933
2936 {
2938 return FALSE;
2939 }
2940 if (!DeviceInterfaceData ||
2941 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
2942 !DeviceInterfaceData->Reserved)
2943 {
2945 return FALSE;
2946 }
2947 if (DeviceInterfaceDetailData && (DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A)))
2948 {
2950 return FALSE;
2951 }
2952
2953 if((DeviceInterfaceDetailDataSize != 0) &&
2954 (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(CHAR))))
2955 {
2957 return FALSE;
2958 }
2959
2960 if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
2961 {
2963 return FALSE;
2964 }
2965
2966
2967 if (DeviceInterfaceDetailData != NULL)
2968 {
2970 + (DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath)) * sizeof(WCHAR);
2971 DeviceInterfaceDetailDataW = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)MyMalloc(sizeW);
2972 if (!DeviceInterfaceDetailDataW)
2973 {
2975 }
2976 DeviceInterfaceDetailDataW->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
2977 }
2978 if (!DeviceInterfaceDetailData || (DeviceInterfaceDetailData && DeviceInterfaceDetailDataW))
2979 {
2982 DeviceInterfaceData,
2983 DeviceInterfaceDetailDataW,
2984 sizeW,
2985 &sizeW,
2987 bytesNeeded = (sizeW - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) / sizeof(WCHAR)
2989 if (RequiredSize)
2990 *RequiredSize = bytesNeeded;
2991 if (ret && DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize >= bytesNeeded)
2992 {
2994 CP_ACP, 0,
2995 DeviceInterfaceDetailDataW->DevicePath, -1,
2996 DeviceInterfaceDetailData->DevicePath, DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath),
2997 NULL, NULL))
2998 {
2999 ret = FALSE;
3000 }
3001 }
3002 }
3003 MyFree(DeviceInterfaceDetailDataW);
3004
3005 return ret;
3006}
3007
3008/***********************************************************************
3009 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
3010 */
3013 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
3014 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
3015 DWORD DeviceInterfaceDetailDataSize,
3018{
3019 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
3020 BOOL ret = FALSE;
3021
3022 TRACE("%s(%p, %p, %p, %d, %p, %p)\n", __FUNCTION__, DeviceInfoSet,
3023 DeviceInterfaceData, DeviceInterfaceDetailData,
3024 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
3025
3028 {
3030 return FALSE;
3031 }
3032 if (!DeviceInterfaceData ||
3033 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
3034 !DeviceInterfaceData->Reserved)
3035 {
3037 return FALSE;
3038 }
3039 if (DeviceInterfaceDetailData && DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W))
3040 {
3042 return FALSE;
3043 }
3044 if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
3045 {
3047 return FALSE;
3048 }
3050 {
3052 return FALSE;
3053 }
3054 if ((DeviceInterfaceDetailData != NULL)
3055 && (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) + sizeof(WCHAR)))
3056 {
3058 return FALSE;
3059 }
3060 else
3061 {
3062 struct DeviceInterface *deviceInterface = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
3063 LPCWSTR devName = deviceInterface->SymbolicLink;
3064 DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) +
3065 (lstrlenW(devName) + 1) * sizeof(WCHAR);
3066
3067 if (sizeRequired > DeviceInterfaceDetailDataSize)
3068 {
3070 if (RequiredSize)
3071 *RequiredSize = sizeRequired;
3072 }
3073 else
3074 {
3075 strcpyW(DeviceInterfaceDetailData->DevicePath, devName);
3076 TRACE("DevicePath is %s\n", debugstr_w(DeviceInterfaceDetailData->DevicePath));
3077 if (DeviceInfoData)
3078 {
3080 &deviceInterface->DeviceInfo->ClassGuid,
3081 sizeof(GUID));
3082 DeviceInfoData->DevInst = deviceInterface->DeviceInfo->dnDevInst;
3083 DeviceInfoData->Reserved = (ULONG_PTR)deviceInterface->DeviceInfo;
3084 }
3085 ret = TRUE;
3086 }
3087 }
3088 return ret;
3089}
3090
3092{
3096};
3097
3099 { REG_SZ, "DeviceDesc", REGSTR_VAL_DEVDESC },
3100 { REG_MULTI_SZ, "HardwareId", REGSTR_VAL_HARDWAREID },
3101 { REG_MULTI_SZ, "CompatibleIDs", REGSTR_VAL_COMPATIBLEIDS },
3102 { 0, NULL, NULL }, /* SPDRP_UNUSED0 */
3103 { REG_SZ, "Service", REGSTR_VAL_SERVICE },
3104 { 0, NULL, NULL }, /* SPDRP_UNUSED1 */
3105 { 0, NULL, NULL }, /* SPDRP_UNUSED2 */
3106 { REG_SZ, "Class", REGSTR_VAL_CLASS },
3107 { REG_SZ, "ClassGUID", REGSTR_VAL_CLASSGUID },
3108 { REG_SZ, "Driver", REGSTR_VAL_DRIVER },
3109 { REG_DWORD, "ConfigFlags", REGSTR_VAL_CONFIGFLAGS },
3110 { REG_SZ, "Mfg", REGSTR_VAL_MFG },
3111 { REG_SZ, "FriendlyName", REGSTR_VAL_FRIENDLYNAME },
3112 { REG_SZ, "LocationInformation", REGSTR_VAL_LOCATION_INFORMATION },
3113 { 0, NULL, NULL }, /* SPDRP_PHYSICAL_DEVICE_OBJECT_NAME */
3114 { REG_DWORD, "Capabilities", REGSTR_VAL_CAPABILITIES },
3115 { REG_DWORD, "UINumber", REGSTR_VAL_UI_NUMBER },
3116 { REG_MULTI_SZ, "UpperFilters", REGSTR_VAL_UPPERFILTERS },
3117 { REG_MULTI_SZ, "LowerFilters", REGSTR_VAL_LOWERFILTERS },
3118 { 0, NULL, NULL }, /* SPDRP_BUSTYPEGUID */
3119 { 0, NULL, NULL }, /* SPDRP_LEGACYBUSTYPE */
3120 { 0, NULL, NULL }, /* SPDRP_BUSNUMBER */
3121 { 0, NULL, NULL }, /* SPDRP_ENUMERATOR_NAME */
3122 { REG_BINARY, "Security", REGSTR_SECURITY },
3123 { 0, NULL, NULL }, /* SPDRP_SECURITY_SDS */
3124 { 0, NULL, NULL }, /* SPDRP_DEVTYPE */
3125 { 0, NULL, NULL }, /* SPDRP_EXCLUSIVE */
3126 { 0, NULL, NULL }, /* SPDRP_CHARACTERISTICS */
3127 { 0, NULL, NULL }, /* SPDRP_ADDRESS */
3128 { REG_SZ, "UINumberDescFormat", REGSTR_UI_NUMBER_DESC_FORMAT },
3129 { 0, NULL, NULL }, /* SPDRP_DEVICE_POWER_DATA */
3130 { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY */
3131 { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_HW_DEFAULT */
3132 { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_OVERRIDE */
3133 { 0, NULL, NULL }, /* SPDRP_INSTALL_STATE */
3134};
3135
3136/***********************************************************************
3137 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
3138 */
3147{
3148 BOOL ret;
3149 BOOL bIsStringProperty;
3150 DWORD RegType;
3151 DWORD RequiredSizeA, RequiredSizeW;
3152 DWORD PropertyBufferSizeW = 0;
3153 PBYTE PropertyBufferW = NULL;
3154
3155 TRACE("%s(%p %p %d %p %p %d %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
3157 RequiredSize);
3158
3159 if (PropertyBufferSize != 0)
3160 {
3161 PropertyBufferSizeW = PropertyBufferSize * 2;
3162 PropertyBufferW = HeapAlloc(GetProcessHeap(), 0, PropertyBufferSizeW);
3163 if (!PropertyBufferW)
3164 {
3166 return FALSE;
3167 }
3168 }
3169
3172 Property,
3173 &RegType,
3174 PropertyBufferW,
3175 PropertyBufferSizeW,
3176 &RequiredSizeW);
3177
3179 {
3180 bIsStringProperty = (RegType == REG_SZ || RegType == REG_MULTI_SZ || RegType == REG_EXPAND_SZ);
3181
3182 if (bIsStringProperty)
3183 RequiredSizeA = RequiredSizeW / sizeof(WCHAR);
3184 else
3185 RequiredSizeA = RequiredSizeW;
3186 if (RequiredSize)
3187 *RequiredSize = RequiredSizeA;
3189 *PropertyRegDataType = RegType;
3190 }
3191
3192 if (!ret)
3193 {
3194 HeapFree(GetProcessHeap(), 0, PropertyBufferW);
3195 return ret;
3196 }
3197
3198 if (RequiredSizeA <= PropertyBufferSize)
3199 {
3200 if (bIsStringProperty && PropertyBufferSize > 0)
3201 {
3202 if (WideCharToMultiByte(CP_ACP, 0, (LPWSTR)PropertyBufferW, RequiredSizeW / sizeof(WCHAR), (LPSTR)PropertyBuffer, PropertyBufferSize, NULL, NULL) == 0)
3203 {
3204 /* Last error is already set by WideCharToMultiByte */
3205 ret = FALSE;
3206 }
3207 }
3208 else
3209 memcpy(PropertyBuffer, PropertyBufferW, RequiredSizeA);
3210 }
3211 else
3212 {
3214 ret = FALSE;
3215 }
3216
3217 HeapFree(GetProcessHeap(), 0, PropertyBufferW);
3218 return ret;
3219}
3220
3221/***********************************************************************
3222 * SetupDiGetDeviceRegistryPropertyW (SETUPAPI.@)
3223 */
3232{
3233 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
3234 struct DeviceInfo *devInfo;
3235 CONFIGRET cr;
3236 LONG lError = ERROR_SUCCESS;
3237 DWORD size;
3238
3239 TRACE("%s(%p %p %d %p %p %d %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
3241 RequiredSize);
3242
3244 {
3246 return FALSE;
3247 }
3248 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
3249 {
3251 return FALSE;
3252 }
3255 {
3257 return FALSE;
3258 }
3259
3261 {
3263 return FALSE;
3264 }
3265
3266 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
3267
3268 if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
3270 {
3271 HKEY hKey;
3273 hKey = SETUPDI_OpenDevKey(set->HKLM, devInfo, KEY_QUERY_VALUE);
3275 return FALSE;
3279
3280 if (RequiredSize)
3281 *RequiredSize = size;
3282
3283 switch (lError)
3284 {
3285 case ERROR_SUCCESS:
3286 if (PropertyBuffer == NULL && size != 0)
3288 break;
3289 case ERROR_MORE_DATA:
3291 break;
3292 default:
3293 break;
3294 }
3295 }
3297 {
3298 size = (strlenW(devInfo->Data) + 1) * sizeof(WCHAR);
3299
3302 if (RequiredSize)
3303 *RequiredSize = size;
3304 if (PropertyBufferSize >= size)
3305 {
3306 strcpyW((LPWSTR)PropertyBuffer, devInfo->Data);
3307 }
3308 else
3310 }
3311 else
3312 {
3314
3319 &size,
3320 0,
3321 set->hMachine);
3322 if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL))
3323 {
3324 if (RequiredSize)
3325 *RequiredSize = size;
3326 }
3327
3328 if (cr != CR_SUCCESS)
3329 {
3330 switch (cr)
3331 {
3332 case CR_INVALID_DEVINST:
3333 lError = ERROR_NO_SUCH_DEVINST;
3334 break;
3335
3338 break;
3339
3340 case CR_BUFFER_SMALL:
3342 break;
3343
3344 default :
3345 lError = ERROR_INVALID_DATA;
3346 break;
3347 }
3348 }
3349 }
3350
3351 SetLastError(lError);
3352 return (lError == ERROR_SUCCESS);
3353}
3354
3355/***********************************************************************
3356 * Internal for SetupDiSetDeviceRegistryPropertyA/W
3357 */
3362 const BYTE *PropertyBuffer,
3364 BOOL isAnsi)
3365{
3366 BOOL ret = FALSE;
3367 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
3368 struct DeviceInfo *deviceInfo;
3369
3370 TRACE("%s(%p %p %d %p %d)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, Property,
3372
3374 {
3376 return FALSE;
3377 }
3378 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
3379 {
3381 return FALSE;
3382 }
3385 {
3387 return FALSE;
3388 }
3389
3390 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
3391
3392 if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
3394 && PropertyMap[Property].nameA)
3395 {
3396 HKEY hKey;
3397 LONG l;
3398 hKey = SETUPDI_OpenDevKey(set->HKLM, deviceInfo, KEY_SET_VALUE);
3400 return FALSE;
3401 /* Write new data */
3402 if (isAnsi)
3403 {
3404 l = RegSetValueExA(
3405 hKey, PropertyMap[Property].nameA, 0,
3408 }
3409 else
3410 {
3411 l = RegSetValueExW(
3415 }
3416 if (!l)
3417 ret = TRUE;
3418 else
3419 SetLastError(l);
3421 }
3422 else
3423 {
3424 ERR("Property 0x%lx not implemented\n", Property);
3426 }
3427
3428 TRACE("Returning %d\n", ret);
3429 return ret;
3430}
3431/***********************************************************************
3432 * SetupDiSetDeviceRegistryPropertyA (SETUPAPI.@)
3433 */
3438 const BYTE *PropertyBuffer,
3440{
3443 Property,
3446 TRUE);
3447}
3448
3449/***********************************************************************
3450 * SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
3451 */
3456 const BYTE *PropertyBuffer,
3458{
3461 Property,
3464 FALSE);
3465}
3466
3467/***********************************************************************
3468 * SetupDiInstallClassA (SETUPAPI.@)
3469 */
3472 PCSTR InfFileName,
3473 DWORD Flags,
3474 HSPFILEQ FileQueue)
3475{
3476 return SetupDiInstallClassExA(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
3477}
3478
3479/***********************************************************************
3480 * SetupDiInstallClassExA (SETUPAPI.@)
3481 */
3485 IN PCSTR InfFileName OPTIONAL,
3486 IN DWORD Flags,
3487 IN HSPFILEQ FileQueue OPTIONAL,
3491{
3492 PWSTR InfFileNameW = NULL;
3493 BOOL Result;
3494
3495 if (!InfFileName)
3496 {
3498 return FALSE;
3499 }
3500 else
3501 {
3502 InfFileNameW = pSetupMultiByteToUnicode(InfFileName, CP_ACP);
3503 if (InfFileNameW == NULL)
3504 {
3506 return FALSE;
3507 }
3508 }
3509
3512
3513 MyFree(InfFileNameW);
3514
3515 return Result;
3516}
3517
3519{
3520 WCHAR FullBuffer[MAX_PATH];
3525
3526 /* Obtain the Class GUID for this class */
3528 hInf,
3529 Version,
3531 Buffer,
3532 sizeof(Buffer) / sizeof(WCHAR),
3533 &RequiredSize))
3534 {
3535 return INVALID_HANDLE_VALUE;
3536 }
3537
3538 /* Build the corresponding registry key name */
3539 lstrcpyW(FullBuffer, REGSTR_PATH_CLASS_NT);
3540 lstrcatW(FullBuffer, BackSlash);
3541 lstrcatW(FullBuffer, Buffer);
3542
3543 /* Obtain the Class name for this class */
3545 hInf,
3546 Version,
3548 Buffer,
3549 sizeof(Buffer) / sizeof(WCHAR),
3550 &RequiredSize))
3551 {
3552 return INVALID_HANDLE_VALUE;
3553 }
3554
3555 /* Try to open or create the registry key */
3556 TRACE("Opening class key %s\n", debugstr_w(FullBuffer));
3557#if 0 // I keep this for reference...
3559 FullBuffer,
3560 0,
3562 &hClassKey))
3563 {
3564 /* Use RegCreateKeyExW */
3565 }
3566#endif
3568 FullBuffer,
3569 0,
3570 NULL,
3573 NULL,
3574 &hClassKey,
3575 &Disposition))
3576 {
3577 ERR("RegCreateKeyExW(%s) failed\n", debugstr_w(FullBuffer));
3578 return INVALID_HANDLE_VALUE;
3579 }
3581 TRACE("The class key %s was successfully created\n", debugstr_w(FullBuffer));
3582 else
3583 TRACE("The class key %s was successfully opened\n", debugstr_w(FullBuffer));
3584
3585 TRACE( "setting value %s to %s\n", debugstr_w(REGSTR_VAL_CLASS), debugstr_w(Buffer) );
3588 0,
3589 REG_SZ,
3590 (LPBYTE)Buffer,
3591 RequiredSize * sizeof(WCHAR)))
3592 {
3595 FullBuffer);
3596 return INVALID_HANDLE_VALUE;
3597 }
3598
3599 return hClassKey;
3600}
3601
3602/***********************************************************************
3603 * SetupDiInstallClassW (SETUPAPI.@)
3604 */
3607 PCWSTR InfFileName,
3608 DWORD Flags,
3609 HSPFILEQ FileQueue)
3610{
3611 return SetupDiInstallClassExW(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
3612}
3613
3614
3615/***********************************************************************
3616 * SetupDiOpenClassRegKey (SETUPAPI.@)
3617 */
3619 const GUID* ClassGuid,
3620 REGSAM samDesired)
3621{
3622 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
3624}
3625
3626
3627/***********************************************************************
3628 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
3629 */
3631 const GUID* ClassGuid,
3632 REGSAM samDesired,
3633 DWORD Flags,
3636{
3637 PWSTR MachineNameW = NULL;
3638 HKEY hKey;
3639
3640 TRACE("%s(%s 0x%lx 0x%lx %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), samDesired,
3642
3643 if (MachineName)
3644 {
3646 if (MachineNameW == NULL)
3647 return INVALID_HANDLE_VALUE;
3648 }
3649
3651 Flags, MachineNameW, Reserved);
3652
3653 MyFree(MachineNameW);
3654
3655 return hKey;
3656}
3657
3658
3659/***********************************************************************
3660 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
3661 */
3663 const GUID* ClassGuid,
3664 REGSAM samDesired,
3665 DWORD Flags,
3668{
3669 HKEY HKLM;
3670 HKEY hClassesKey;
3671 HKEY key;
3672 LPCWSTR lpKeyName;
3673 LONG l;
3674
3675 TRACE("%s(%s 0x%lx 0x%lx %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), samDesired,
3677
3678 if (MachineName != NULL)
3679 {
3681 if (l != ERROR_SUCCESS)
3682 {
3683 SetLastError(l);
3684 return INVALID_HANDLE_VALUE;
3685 }
3686 }
3687 else
3689
3690 if (Flags == DIOCR_INSTALLER)
3691 {
3692 lpKeyName = REGSTR_PATH_CLASS_NT;
3693 }
3694 else if (Flags == DIOCR_INTERFACE)
3695 {
3696 lpKeyName = REGSTR_PATH_DEVICE_CLASSES;
3697 }
3698 else
3699 {
3700 ERR("Invalid Flags parameter!\n");
3703 return INVALID_HANDLE_VALUE;
3704 }
3705
3706 if (!ClassGuid)
3707 {
3708 if ((l = RegOpenKeyExW(HKLM,
3709 lpKeyName,
3710 0,
3711 samDesired,
3712 &hClassesKey)))
3713 {
3715 hClassesKey = INVALID_HANDLE_VALUE;
3716 }
3717 if (MachineName != NULL)
3719 key = hClassesKey;
3720 }
3721 else
3722 {
3723 WCHAR bracedGuidString[39];
3724
3725 SETUPDI_GuidToString(ClassGuid, bracedGuidString);
3726
3727 if (!(l = RegOpenKeyExW(HKLM,
3728 lpKeyName,
3729 0,
3730 samDesired,
3731 &hClassesKey)))
3732 {
3733 if (MachineName != NULL)
3735
3736 if ((l = RegOpenKeyExW(hClassesKey,
3737 bracedGuidString,
3738 0,
3739 samDesired,
3740 &key)))
3741 {
3742 SetLastError(l);
3744 }
3745 RegCloseKey(hClassesKey);
3746 }
3747 else
3748 {
3750 SetLastError(l);
3752 }
3753 }
3754
3755 return key;
3756}
3757
3758/***********************************************************************
3759 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
3760 */
3763 PCWSTR DevicePath,
3764 DWORD OpenFlags,
3765 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
3766{
3767 struct DeviceInfoSet * list;
3768 PCWSTR pEnd;
3769 DWORD dwLength, dwError, dwIndex, dwKeyName, dwSubIndex;
3770 CLSID ClassId;
3771 WCHAR Buffer[MAX_PATH + 1];
3772 WCHAR SymBuffer[MAX_PATH + 1];
3773 WCHAR InstancePath[MAX_PATH + 1];
3774 HKEY hKey, hDevKey, hSymKey;
3775 struct DeviceInfo * deviceInfo;
3776 struct DeviceInterface *deviceInterface;
3777 BOOL Ret;
3778 PLIST_ENTRY ItemList;
3779 PLIST_ENTRY InterfaceListEntry;
3780
3781 TRACE("%s(%p %s %08x %p)\n", __FUNCTION__,
3782 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
3783
3784
3785 if (DeviceInterfaceData && DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
3786 {
3788 return FALSE;
3789 }
3790
3792 {
3794 return FALSE;
3795 }
3796
3797 list = (struct DeviceInfoSet * )DeviceInfoSet;
3798
3799 dwLength = wcslen(DevicePath);
3800 if (dwLength < 39)
3801 {
3802 /* path must be at least a guid length + L'\0' */
3804 return FALSE;
3805 }
3806
3807 if (DevicePath[0] != L'\\' ||
3808 DevicePath[1] != L'\\' ||
3809 (DevicePath[2] != L'?' && DevicePath[2] != L'.') ||
3810 DevicePath[3] != L'\\')
3811 {
3812 /* invalid formatted path */
3814 return FALSE;
3815 }
3816
3817 /* check for reference strings */
3818 pEnd = wcschr(&DevicePath[4], L'\\');
3819 if (!pEnd)
3820 {
3821 /* no reference string */
3822 pEnd = DevicePath + dwLength;
3823 }
3824
3825 /* copy guid */
3826 wcscpy(Buffer, pEnd - 37);
3827 Buffer[36] = L'\0';
3828
3829 dwError = UuidFromStringW(Buffer, &ClassId);
3830 if (dwError != NOERROR)
3831 {
3832 /* invalid formatted path */
3834 return FALSE;
3835 }
3836
3837 hKey = SetupDiOpenClassRegKeyExW(&ClassId, KEY_READ, DIOCR_INTERFACE, list->MachineName, NULL);
3838
3840 {
3841 /* invalid device class */
3842 return FALSE;
3843 }
3844
3845 ItemList = list->ListHead.Flink;
3846 while (ItemList != &list->ListHead)
3847 {
3848 deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
3849 InterfaceListEntry = deviceInfo->InterfaceListHead.Flink;
3850 while (InterfaceListEntry != &deviceInfo->InterfaceListHead)
3851 {
3852 deviceInterface = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
3853 if (!IsEqualIID(&deviceInterface->InterfaceClassGuid, &ClassId))
3854 {
3855 InterfaceListEntry = InterfaceListEntry->Flink;
3856 continue;
3857 }
3858
3859 if (!wcsicmp(deviceInterface->SymbolicLink, DevicePath))
3860 {
3861 if (DeviceInterfaceData)
3862 {
3863 DeviceInterfaceData->Reserved = (ULONG_PTR)deviceInterface;
3864 DeviceInterfaceData->Flags = deviceInterface->Flags;
3865 CopyMemory(&DeviceInterfaceData->InterfaceClassGuid, &ClassId, sizeof(GUID));
3866 }
3867
3868 return TRUE;
3869 }
3870
3871 }
3872 }
3873
3874
3875 dwIndex = 0;
3876 do
3877 {
3878 Buffer[0] = 0;
3879 dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
3880 dwError = RegEnumKeyExW(hKey, dwIndex, Buffer, &dwKeyName, NULL, NULL, NULL, NULL);
3881
3882 if (dwError != ERROR_SUCCESS)
3883 break;
3884
3885 if (RegOpenKeyExW(hKey, Buffer, 0, KEY_READ, &hDevKey) != ERROR_SUCCESS)
3886 break;
3887
3888 dwSubIndex = 0;
3889 InstancePath[0] = 0;
3890 dwKeyName = sizeof(InstancePath);
3891
3892 dwError = RegQueryValueExW(hDevKey, L"DeviceInstance", NULL, NULL, (LPBYTE)InstancePath, &dwKeyName);
3893
3894 while(TRUE)
3895 {
3896 Buffer[0] = 0;
3897 dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
3898 dwError = RegEnumKeyExW(hDevKey, dwSubIndex, Buffer, &dwKeyName, NULL, NULL, NULL, NULL);
3899
3900 if (dwError != ERROR_SUCCESS)
3901 break;
3902
3903 dwError = RegOpenKeyExW(hDevKey, Buffer, 0, KEY_READ, &hSymKey);
3904 if (dwError != ERROR_SUCCESS)
3905 break;
3906
3907 /* query for symbolic link */
3908 dwKeyName = sizeof(SymBuffer);
3909 SymBuffer[0] = L'\0';
3910 dwError = RegQueryValueExW(hSymKey, L"SymbolicLink", NULL, NULL, (LPBYTE)SymBuffer, &dwKeyName);
3911
3912 if (dwError != ERROR_SUCCESS)
3913 {
3914 RegCloseKey(hSymKey);
3915 break;
3916 }
3917
3918 if (!wcsicmp(SymBuffer, DevicePath))
3919 {
3920 Ret = CreateDeviceInfo(list, InstancePath, &ClassId, &deviceInfo);
3921 RegCloseKey(hSymKey);
3922 RegCloseKey(hDevKey);
3924
3925 if (Ret)
3926 {
3927 deviceInterface = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInterface) + (wcslen(SymBuffer) + 1) * sizeof(WCHAR));
3928 if (deviceInterface)
3929 {
3930
3931 CopyMemory(&deviceInterface->InterfaceClassGuid, &ClassId, sizeof(GUID));
3932 deviceInterface->DeviceInfo = deviceInfo;
3933 deviceInterface->Flags = SPINT_ACTIVE; //FIXME
3934
3935 wcscpy(deviceInterface->SymbolicLink, SymBuffer);
3936
3937 InsertTailList(&deviceInfo->InterfaceListHead, &deviceInterface->ListEntry);
3938 InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
3939
3940
3941 if (DeviceInterfaceData)
3942 {
3943 DeviceInterfaceData->Reserved = (ULONG_PTR)deviceInterface;
3944 DeviceInterfaceData->Flags = deviceInterface->Flags;
3945 CopyMemory(&DeviceInterfaceData->InterfaceClassGuid, &ClassId, sizeof(GUID));
3946 }
3947 else
3948 {
3949 Ret = FALSE;
3951 }
3952 }
3953 }
3954 else
3955 {
3956 HeapFree(GetProcessHeap(), 0, deviceInfo);
3957 Ret = FALSE;
3958 }
3959 return Ret;
3960 }
3961 RegCloseKey(hSymKey);
3962 dwSubIndex++;
3963 }
3964
3965 RegCloseKey(hDevKey);
3966 dwIndex++;
3967 } while(TRUE);
3968
3970 return FALSE;
3971}
3972
3973/***********************************************************************
3974 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
3975 */
3978 PCSTR DevicePath,
3979 DWORD OpenFlags,
3980 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
3981{
3982 LPWSTR DevicePathW = NULL;
3983 BOOL bResult;
3984
3985 TRACE("%s(%p %s %08lx %p)\n", __FUNCTION__, DeviceInfoSet, debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
3986
3987 DevicePathW = pSetupMultiByteToUnicode(DevicePath, CP_ACP);
3988 if (DevicePathW == NULL)
3989 return FALSE;
3990
3992 DevicePathW, OpenFlags, DeviceInterfaceData);
3993
3994 MyFree(DevicePathW);
3995
3996 return bResult;
3997}
3998
3999/***********************************************************************
4000 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
4001 */
4007{
4008 FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData,
4009 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
4010 return FALSE;
4011}
4012
4013static BOOL WINAPI
4017{
4019}
4020
4021/***********************************************************************
4022 * SetupDiCallClassInstaller (SETUPAPI.@)
4023 */
4025 DI_FUNCTION InstallFunction,
4028{
4029 BOOL ret = FALSE;
4030
4031 TRACE("%s(%u %p %p)\n", __FUNCTION__, InstallFunction, DeviceInfoSet, DeviceInfoData);
4032
4033 if (!DeviceInfoSet)
4039 else if (((struct DeviceInfoSet *)DeviceInfoSet)->HKLM != HKEY_LOCAL_MACHINE)
4041 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4043 else
4044 {
4046#define CLASS_COINSTALLER 0x1
4047#define DEVICE_COINSTALLER 0x2
4048#define CLASS_INSTALLER 0x4
4049 UCHAR CanHandle = 0;
4051
4052 switch (InstallFunction)
4053 {
4056 break;
4059 break;
4060 case DIF_ALLOW_INSTALL:
4061 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4062 break;
4063 case DIF_DETECT:
4064 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4065 break;
4067 CanHandle = CLASS_INSTALLER;
4068 break;
4069 case DIF_INSTALLDEVICE:
4072 break;
4074 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4076 break;
4080 break;
4083 break;
4085 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4086 break;
4088 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4089 break;
4091 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4092 break;
4094 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4095 break;
4098 break;
4099 case DIF_PROPERTYCHANGE:
4102 break;
4104 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4106 break;
4107 case DIF_REGISTERDEVICE:
4108 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4110 break;
4111 case DIF_REMOVE:
4114 break;
4116 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4118 break;
4119 case DIF_SELECTDEVICE:
4120 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4122 break;
4123 case DIF_TROUBLESHOOTER:
4125 break;
4126 case DIF_UNREMOVE:
4129 break;
4130 default:
4131 ERR("Install function %u not supported\n", InstallFunction);
4133 }
4134
4137 /* Don't process this call, as a parameter is invalid */
4138 CanHandle = 0;
4139
4140 if (CanHandle != 0)
4141 {
4142 LIST_ENTRY ClassCoInstallersListHead;
4143 LIST_ENTRY DeviceCoInstallersListHead;
4144 HMODULE ClassInstallerLibrary = NULL;
4145 CLASS_INSTALL_PROC ClassInstaller = NULL;
4147 PLIST_ENTRY ListEntry;
4148 HKEY hKey;
4149 DWORD dwRegType, dwLength;
4150 DWORD rc = NO_ERROR;
4151
4152 InitializeListHead(&ClassCoInstallersListHead);
4153 InitializeListHead(&DeviceCoInstallersListHead);
4154
4155 if (CanHandle & DEVICE_COINSTALLER)
4156 {
4159 {
4161 if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
4162 {
4163 LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
4164 if (KeyBuffer != NULL)
4165 {
4167 if (rc == ERROR_SUCCESS)
4168 {
4169 LPWSTR ptr;
4170 for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
4171 {
4172 /* Add coinstaller to DeviceCoInstallersListHead list */
4173 struct CoInstallerElement *coinstaller;
4174 TRACE("Got device coinstaller '%s'\n", debugstr_w(ptr));
4175 coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement));
4176 if (!coinstaller)
4177 continue;
4178 ZeroMemory(coinstaller, sizeof(struct CoInstallerElement));
4179 if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS)
4180 InsertTailList(&DeviceCoInstallersListHead, &coinstaller->ListEntry);
4181 else
4182 HeapFree(GetProcessHeap(), 0, coinstaller);
4183 }
4184 }
4185 HeapFree(GetProcessHeap(), 0, KeyBuffer);
4186 }
4187 }
4189 }
4190 }
4191 if (CanHandle & CLASS_COINSTALLER)
4192 {
4193 rc = RegOpenKeyExW(
4196 0, /* Options */
4198 &hKey);
4199 if (rc == ERROR_SUCCESS)
4200 {
4201 WCHAR szGuidString[40];
4202 if (pSetupStringFromGuid(&DeviceInfoData->ClassGuid, szGuidString, ARRAYSIZE(szGuidString)) == ERROR_SUCCESS)
4203 {
4204 rc = RegQueryValueExW(hKey, szGuidString, NULL, &dwRegType, NULL, &dwLength);
4205 if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
4206 {
4207 LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
4208 if (KeyBuffer != NULL)
4209 {
4210 rc = RegQueryValueExW(hKey, szGuidString, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
4211 if (rc == ERROR_SUCCESS)
4212 {
4213 LPWSTR ptr;
4214 for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
4215 {
4216 /* Add coinstaller to ClassCoInstallersListHead list */
4217 struct CoInstallerElement *coinstaller;
4218 TRACE("Got class coinstaller '%s'\n", debugstr_w(ptr));
4219 coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement));
4220 if (!coinstaller)
4221 continue;
4222 ZeroMemory(coinstaller, sizeof(struct CoInstallerElement));
4223 if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS)
4224 InsertTailList(&ClassCoInstallersListHead, &coinstaller->ListEntry);
4225 else
4226 HeapFree(GetProcessHeap(), 0, coinstaller);
4227 }
4228 }
4229 HeapFree(GetProcessHeap(), 0, KeyBuffer);
4230 }
4231 }
4232 }
4234 }
4235 }
4236 if ((CanHandle & CLASS_INSTALLER) && !(InstallParams.FlagsEx & DI_FLAGSEX_CI_FAILED))
4237 {
4240 {
4242 if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
4243 {
4244 LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
4245 if (KeyBuffer != NULL)
4246 {
4248 if (rc == ERROR_SUCCESS)
4249 {
4250 /* Get ClassInstaller function pointer */
4251 TRACE("Got class installer '%s'\n", debugstr_w(KeyBuffer));
4252 if (GetFunctionPointer(KeyBuffer, &ClassInstallerLibrary, (PVOID*)&ClassInstaller) != ERROR_SUCCESS)
4253 {
4254 InstallParams.FlagsEx |= DI_FLAGSEX_CI_FAILED;
4256 }
4257 }
4258 HeapFree(GetProcessHeap(), 0, KeyBuffer);
4259 }
4260 }
4262 }
4263 }
4264
4265 /* Call Class co-installers */
4266 Context.PostProcessing = FALSE;
4267 rc = NO_ERROR;
4268 ListEntry = ClassCoInstallersListHead.Flink;
4269 while (rc == NO_ERROR && ListEntry != &ClassCoInstallersListHead)
4270 {
4271 struct CoInstallerElement *coinstaller;
4273 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4274 coinstaller->PrivateData = Context.PrivateData;
4276 {
4277 coinstaller->DoPostProcessing = TRUE;
4278 rc = NO_ERROR;
4279 }
4281 }
4282
4283 /* Call Device co-installers */
4284 ListEntry = DeviceCoInstallersListHead.Flink;
4285 while (rc == NO_ERROR && ListEntry != &DeviceCoInstallersListHead)
4286 {
4287 struct CoInstallerElement *coinstaller;
4289 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4290 coinstaller->PrivateData = Context.PrivateData;
4292 {
4293 coinstaller->DoPostProcessing = TRUE;
4294 rc = NO_ERROR;
4295 }
4297 }
4298
4299 /* Call Class installer */
4300 if (ClassInstaller)
4301 {
4302 rc = (*ClassInstaller)(InstallFunction, DeviceInfoSet, DeviceInfoData);
4303 FreeFunctionPointer(ClassInstallerLibrary, ClassInstaller);
4304 }
4305 else
4307
4308 /* Call default handler */
4309 if (rc == ERROR_DI_DO_DEFAULT)
4310 {
4311 if (DefaultHandler && !(InstallParams.Flags & DI_NODI_DEFAULTACTION))
4312 {
4314 rc = NO_ERROR;
4315 else
4316 rc = GetLastError();
4317 }
4318 else
4319 rc = NO_ERROR;
4320 }
4321
4322 /* Call Class co-installers that required postprocessing */
4323 Context.PostProcessing = TRUE;
4324 ListEntry = ClassCoInstallersListHead.Flink;
4325 while (ListEntry != &ClassCoInstallersListHead)
4326 {
4327 struct CoInstallerElement *coinstaller;
4329 if (coinstaller->DoPostProcessing)
4330 {
4331 Context.InstallResult = rc;
4332 Context.PrivateData = coinstaller->PrivateData;
4333 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4334 }
4335 FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
4337 }
4338
4339 /* Call Device co-installers that required postprocessing */
4340 ListEntry = DeviceCoInstallersListHead.Flink;
4341 while (ListEntry != &DeviceCoInstallersListHead)
4342 {
4343 struct CoInstallerElement *coinstaller;
4345 if (coinstaller->DoPostProcessing)
4346 {
4347 Context.InstallResult = rc;
4348 Context.PrivateData = coinstaller->PrivateData;
4349 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4350 }
4351 FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
4353 }
4354
4355 /* Free allocated memory */
4356 while (!IsListEmpty(&ClassCoInstallersListHead))
4357 {
4358 ListEntry = RemoveHeadList(&ClassCoInstallersListHead);
4360 }
4361 while (!IsListEmpty(&DeviceCoInstallersListHead))
4362 {
4363 ListEntry = RemoveHeadList(&DeviceCoInstallersListHead);
4365 }
4366
4367 ret = (rc == NO_ERROR);
4368 }
4369 }
4370
4371 TRACE("Returning %d\n", ret);
4372 return ret;
4373}
4374
4375/***********************************************************************
4376 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
4377 */
4382{
4383 SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
4384 BOOL ret = FALSE;
4385
4387
4390 else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_A))
4392 else
4393 {
4394 deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
4396
4397 if (ret)
4398 {
4399 /* Do W->A conversion */
4400 memcpy(
4402 &deviceInstallParamsW,
4404 if (WideCharToMultiByte(CP_ACP, 0, deviceInstallParamsW.DriverPath, -1,
4405 DeviceInstallParams->DriverPath, MAX_PATH, NULL, NULL) == 0)
4406 {
4407 DeviceInstallParams->DriverPath[0] = '\0';
4408 ret = FALSE;
4409 }
4410 }
4411 }
4412
4413 TRACE("Returning %d\n", ret);
4414 return ret;
4415}
4416
4417/***********************************************************************
4418 * SetupDiGetDeviceInfoListClass (SETUPAPI.@)
4419 */
4423 OUT LPGUID ClassGuid)
4424{
4425 struct DeviceInfoSet *list;
4426 BOOL ret = FALSE;
4427
4428 TRACE("%s(%p %p)\n", __FUNCTION__, DeviceInfoSet, ClassGuid);
4429
4430 if (!DeviceInfoSet)
4434 else if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
4436 else
4437 {
4438 *ClassGuid = list->ClassGuid;
4439
4440 ret = TRUE;
4441 }
4442
4443 TRACE("Returning %d\n", ret);
4444 return ret;
4445}
4446
4447/***********************************************************************
4448 * SetupDiGetDeviceInstallParamsW (SETUPAPI.@)
4449 */
4455{
4456 struct DeviceInfoSet *list;
4457 BOOL ret = FALSE;
4458
4460
4461 if (!DeviceInfoSet)
4465 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4467 else if (!DeviceInstallParams)
4469 else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
4471 else
4472 {
4474
4475 if (DeviceInfoData)
4476 Source = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
4477 else
4478 Source = &list->InstallParams;
4479
4480 ret = TRUE;
4481
4482 _SEH2_TRY
4483 {
4485 }
4487 {
4489 ret = FALSE;
4490 }
4491 _SEH2_END;
4492 }
4493
4494 TRACE("Returning %d\n", ret);
4495 return ret;
4496}
4497
4498static BOOL
4501{
4502 DWORD SupportedFlags =
4503 DI_NOVCP | /* 0x00000008 */
4504 DI_DIDCOMPAT | /* 0x00000010 */
4505 DI_DIDCLASS | /* 0x00000020 */
4506 DI_NEEDRESTART | /* 0x00000080 */
4507 DI_NEEDREBOOT | /* 0x00000100 */
4508 DI_RESOURCEPAGE_ADDED | /* 0x00002000 */
4509 DI_PROPERTIES_CHANGE | /* 0x00004000 */
4510 DI_ENUMSINGLEINF | /* 0x00010000 */
4511 DI_DONOTCALLCONFIGMG | /* 0x00020000 */
4512 DI_CLASSINSTALLPARAMS | /* 0x00100000 */
4513 DI_NODI_DEFAULTACTION | /* 0x00200000 */
4514 DI_QUIETINSTALL | /* 0x00800000 */
4515 DI_NOFILECOPY | /* 0x01000000 */
4516 DI_DRIVERPAGE_ADDED; /* 0x04000000 */
4517 DWORD SupportedFlagsEx =
4518 DI_FLAGSEX_CI_FAILED | /* 0x00000004 */
4519 DI_FLAGSEX_DIDINFOLIST | /* 0x00000010 */
4520 DI_FLAGSEX_DIDCOMPATINFO | /* 0x00000020 */
4521 DI_FLAGSEX_ALLOWEXCLUDEDDRVS | /* 0x00000800 */
4522 DI_FLAGSEX_NO_DRVREG_MODIFY | /* 0x00008000 */
4523 DI_FLAGSEX_INSTALLEDDRIVER; /* 0x04000000 */
4524 BOOL ret = FALSE;
4525
4526 /* FIXME: add support for more flags */
4527
4528 /* FIXME: DI_CLASSINSTALLPARAMS flag is not correctly used.
4529 * It should be checked before accessing to other values
4530 * of the SP_DEVINSTALL_PARAMS structure */
4531
4532 if (DeviceInstallParams->Flags & ~SupportedFlags)
4533 {
4534 FIXME("Unknown Flags: 0x%08lx\n", DeviceInstallParams->Flags & ~SupportedFlags);
4536 }
4537 else if (DeviceInstallParams->FlagsEx & ~SupportedFlagsEx)
4538 {
4539 FIXME("Unknown FlagsEx: 0x%08lx\n", DeviceInstallParams->FlagsEx & ~SupportedFlagsEx);
4541 }
4542 else if ((DeviceInstallParams->Flags & DI_NOVCP)
4543 && (DeviceInstallParams->FileQueue == NULL || DeviceInstallParams->FileQueue == (HSPFILEQ)INVALID_HANDLE_VALUE))
4545 else
4546 {
4547 /* FIXME: check Reserved field */
4548 ret = TRUE;
4549 }
4550
4551 return ret;
4552}
4553
4554/***********************************************************************
4555 * SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
4556 */
4562{
4563 struct DeviceInfoSet *list;
4564 BOOL ret = FALSE;
4565
4567
4568 if (!DeviceInfoSet)
4572 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4574 else if (!DeviceInstallParams)
4576 else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
4579 {
4581
4582 if (DeviceInfoData)
4583 Destination = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
4584 else
4585 Destination = &list->InstallParams;
4587 ret = TRUE;
4588 }
4589
4590 TRACE("Returning %d\n", ret);
4591 return ret;
4592}
4593
4594/***********************************************************************
4595 * SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
4596 */
4602{
4603 SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
4604 int len = 0;
4605 BOOL ret = FALSE;
4606
4608
4611 else if (DeviceInstallParams->cbSize < sizeof(SP_DEVINSTALL_PARAMS_A))
4613 else
4614 {
4615 memcpy(&deviceInstallParamsW, DeviceInstallParams, FIELD_OFFSET(SP_DEVINSTALL_PARAMS_A, DriverPath));
4616 deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
4617 len = MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, NULL, 0);
4618 if (!len)
4619 {
4620 ERR("DrivePath is NULL\n");
4621 ret = FALSE;
4622 }
4623 else
4624 {
4625 MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, deviceInstallParamsW.DriverPath, len);
4627 }
4628 }
4629
4630 TRACE("Returning %d\n", ret);
4631 return ret;
4632}
4633
4634static HKEY
4636 IN HKEY HKLM,
4637 IN DWORD HwProfile,
4638 IN DWORD samDesired)
4639{
4640 HKEY hHWProfilesKey = NULL;
4641 HKEY hHWProfileKey = NULL;
4643 LONG rc;
4644
4645 rc = RegOpenKeyExW(HKLM,
4647 0,
4649 &hHWProfilesKey);
4650 if (rc != ERROR_SUCCESS)
4651 {
4652 SetLastError(rc);
4653 goto cleanup;
4654 }
4655 if (HwProfile == 0)
4656 {
4657 rc = RegOpenKeyExW(hHWProfilesKey,
4659 0,
4661 &hHWProfileKey);
4662 }
4663 else
4664 {
4665 WCHAR subKey[5];
4666 snprintfW(subKey, 4, InstanceKeyFormat, HwProfile);
4667 subKey[4] = '\0';
4668 rc = RegOpenKeyExW(hHWProfilesKey,
4669 subKey,
4670 0,
4672 &hHWProfileKey);
4673 }
4674 if (rc != ERROR_SUCCESS)
4675 {
4676 SetLastError(rc);
4677 goto cleanup;
4678 }
4679 ret = hHWProfileKey;
4680
4681cleanup:
4682 if (hHWProfilesKey != NULL)
4683 RegCloseKey(hHWProfilesKey);
4684 if (hHWProfileKey != NULL && hHWProfileKey != ret)
4685 RegCloseKey(hHWProfileKey);
4686 return ret;
4687}
4688
4689static BOOL
4691 struct DeviceInfoSet *deviceInfoSet,
4692 struct DeviceInfo *deviceInfo)
4693{
4695
4696 ListEntry = deviceInfoSet->ListHead.Flink;
4697 while (ListEntry != &deviceInfoSet->ListHead)
4698 {
4699 if (deviceInfo == CONTAINING_RECORD(ListEntry, struct DeviceInfo, ListEntry))
4700 return TRUE;
4701
4703 }
4704
4705 return FALSE;
4706}
4707
4708/***********************************************************************
4709 * SetupDiDeleteDeviceInfo (SETUPAPI.@)
4710 */
4715{
4716 struct DeviceInfoSet *deviceInfoSet;
4717 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData;
4718 BOOL ret = FALSE;
4719
4721
4722 if (!DeviceInfoSet)
4724 else if ((deviceInfoSet = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
4726 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4728 else if (!IsDeviceInfoInDeviceInfoSet(deviceInfoSet, deviceInfo))
4730 else
4731 {
4732 RemoveEntryList(&deviceInfo->ListEntry);
4733 DestroyDeviceInfo(deviceInfo);
4734 ret = TRUE;
4735 }
4736
4737 return ret;
4738}
4739
4740
4741/***********************************************************************
4742 * SetupDiOpenDeviceInfoA (SETUPAPI.@)
4743 */
4747 IN PCSTR DeviceInstanceId,
4749 IN DWORD OpenFlags,
4751{
4752 LPWSTR DeviceInstanceIdW = NULL;
4753 BOOL bResult;
4754
4755 TRACE("%s(%p %s %p %lx %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInstanceId, hwndParent, OpenFlags, DeviceInfoData);
4756
4757 DeviceInstanceIdW = pSetupMultiByteToUnicode(DeviceInstanceId, CP_ACP);
4758 if (DeviceInstanceIdW == NULL)
4759 return FALSE;
4760
4762 DeviceInstanceIdW, hwndParent, OpenFlags, DeviceInfoData);
4763
4764 MyFree(DeviceInstanceIdW);
4765
4766 return bResult;
4767}
4768
4769
4770/***********************************************************************
4771 * SetupDiOpenDeviceInfoW (SETUPAPI.@)
4772 */
4776 IN PCWSTR DeviceInstanceId,
4778 IN DWORD OpenFlags,
4780{
4781 struct DeviceInfoSet *list;
4783 DWORD rc, dwSize;
4784 BOOL ret = FALSE;
4785
4786 TRACE("%s(%p %s %p %lx %p)\n", __FUNCTION__,
4787 DeviceInfoSet, debugstr_w(DeviceInstanceId),
4788 hwndParent, OpenFlags, DeviceInfoData);
4789
4790 if (OpenFlags & DIOD_CANCEL_REMOVE)
4791 FIXME("DIOD_CANCEL_REMOVE flag not implemented\n");
4792
4793 if (!DeviceInfoSet)
4797 else if (!DeviceInstanceId)
4799 else if (OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS))
4800 {
4801 TRACE("Unknown flags: 0x%08lx\n", OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS));
4803 }
4804 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4806 else
4807 {
4808 struct DeviceInfo *deviceInfo = NULL;
4809 /* Search if device already exists in DeviceInfoSet.
4810 * If yes, return the existing element
4811 * If no, create a new element using information in registry
4812 */
4813 PLIST_ENTRY ItemList = list->ListHead.Flink;
4814 while (ItemList != &list->ListHead)
4815 {
4816 deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
4817 if (!wcscmp(deviceInfo->instanceId, DeviceInstanceId))
4818 break;
4819 deviceInfo = NULL;
4820 ItemList = ItemList->Flink;
4821 }
4822
4823 if (deviceInfo)
4824 {
4825 /* good one found */
4826 ret = TRUE;
4827 }
4828 else
4829 {
4831 WCHAR szClassGuid[MAX_GUID_STRING_LEN];
4832
4833 /* Open supposed registry key */
4834 rc = RegOpenKeyExW(
4835 list->HKLM,
4837 0, /* Options */
4839 &hEnumKey);
4840 if (rc != ERROR_SUCCESS)
4841 {
4842 SetLastError(rc);
4843 goto cleanup;
4844 }
4845 rc = RegOpenKeyExW(
4846 hEnumKey,
4847 DeviceInstanceId,
4848 0, /* Options */
4850 &hKey);
4852 if (rc != ERROR_SUCCESS)
4853 {
4854 if (rc == ERROR_FILE_NOT_FOUND)
4856 SetLastError(rc);
4857 goto cleanup;
4858 }
4859
4861 dwSize = MAX_GUID_STRING_LEN * sizeof(WCHAR);
4862
4865 NULL,
4866 NULL,
4867 (LPBYTE)szClassGuid,
4868 &dwSize) == ERROR_SUCCESS)
4869 {
4870 szClassGuid[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
4871
4872 /* Convert a string to a ClassGuid */
4873 UuidFromStringW(&szClassGuid[1], &ClassGUID);
4874 }
4875
4876 if (!CreateDeviceInfo(list, DeviceInstanceId, &ClassGUID, &deviceInfo))
4877 goto cleanup;
4878
4879 InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
4880
4881 ret = TRUE;
4882 }
4883
4884 if (ret && deviceInfo && DeviceInfoData)
4885 {
4886 memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID));
4887 DeviceInfoData->DevInst = deviceInfo->dnDevInst;
4888 DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
4889 }
4890 }
4891
4892cleanup:
4893 if (hKey != NULL)
4895 return ret;
4896}
4897
4898
4899/***********************************************************************
4900 * SetupDiGetSelectedDevice (SETUPAPI.@)
4901 */
4906{
4907 struct DeviceInfoSet *list;
4908 BOOL ret = FALSE;
4909
4911
4912 if (!DeviceInfoSet)
4916 else if (list->SelectedDevice == NULL)
4918 else if (!DeviceInfoData)
4920 else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4922 else
4923 {
4925 &list->SelectedDevice->ClassGuid,
4926 sizeof(GUID));
4927 DeviceInfoData->DevInst = list->SelectedDevice->dnDevInst;
4928 DeviceInfoData->Reserved = (ULONG_PTR)list->SelectedDevice;
4929 ret = TRUE;
4930 }
4931
4932 TRACE("Returning %d\n", ret);
4933 return ret;
4934}
4935
4936
4937/***********************************************************************
4938 * SetupDiSetSelectedDevice (SETUPAPI.@)
4939 */
4944{
4945 struct DeviceInfoSet *list;
4946 BOOL ret = FALSE;
4947
4949
4950 if (!DeviceInfoSet)
4954 else if (!DeviceInfoData)
4956 else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4958 else if (DeviceInfoData->Reserved == 0)
4960 else
4961 {
4962 list->SelectedDevice = (struct DeviceInfo *)DeviceInfoData->Reserved;
4963 ret = TRUE;
4964 }
4965
4966 TRACE("Returning %d\n", ret);
4967 return ret;
4968}
4969
4970
4971/* Return the current hardware profile id, or -1 if error */
4972static DWORD
4975{
4976 HKEY hKey = NULL;
4977 DWORD dwRegType, dwLength;
4978 DWORD hwProfile;
4979 LONG rc;
4980 DWORD ret = (DWORD)-1;
4981
4984 0, /* Options */
4986 &hKey);
4987 if (rc != ERROR_SUCCESS)
4988 {
4989 SetLastError(rc);
4990 goto cleanup;
4991 }
4992
4993 dwLength = sizeof(DWORD);
4996 NULL,
4997 &dwRegType,
4998 (LPBYTE)&hwProfile, &dwLength);
4999 if (rc != ERROR_SUCCESS)
5000 {
5001 SetLastError(rc);
5002 goto cleanup;
5003 }
5004 else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
5005 {
5007 goto cleanup;
5008 }
5009
5010 ret = hwProfile;
5011
5012cleanup:
5013 if (hKey != NULL)
5015
5016 return ret;
5017}
5018
5019static BOOL
5023{
5024#ifndef __WINESRC__
5025 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5026 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5027 CONFIGRET cr;
5028
5029 cr = CM_Enable_DevNode_Ex(deviceInfo->dnDevInst, 0, set->hMachine);
5030 if (cr != CR_SUCCESS)
5031 {
5033 return FALSE;
5034 }
5035
5036 return TRUE;
5037#else
5038 FIXME("Stub: ResetDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
5039 return TRUE;
5040#endif
5041}
5042
5043static BOOL
5047{
5048#ifndef __WINESRC__
5049 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5050 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5051 CONFIGRET cr;
5052
5053 cr = CM_Disable_DevNode_Ex(deviceInfo->dnDevInst, 0, set->hMachine);
5054 if (cr != CR_SUCCESS)
5055 {
5057 return FALSE;
5058 }
5059
5060 return TRUE;
5061#else
5062 FIXME("Stub: StopDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
5063 return TRUE;
5064#endif
5065}
5066
5067/***********************************************************************
5068 * SetupDiChangeState (SETUPAPI.@)
5069 */
5074{
5075 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5076 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5077 PSP_PROPCHANGE_PARAMS PropChange;
5079 LPCWSTR RegistryValueName;
5080 DWORD dwConfigFlags, dwLength, dwRegType;
5081 LONG rc;
5082 BOOL ret = FALSE;
5083
5085
5086 if (!DeviceInfoData)
5087 PropChange = ((struct DeviceInfoSet *)DeviceInfoSet)->ClassInstallParams.PropChangeParams;
5088 else
5089 PropChange = ((struct DeviceInfo *)DeviceInfoData->Reserved)->ClassInstallParams.PropChangeParams;
5090 if (!PropChange)
5091 {
5093 goto cleanup;
5094 }
5095
5096 if (PropChange->Scope == DICS_FLAG_GLOBAL)
5097 RegistryValueName = REGSTR_VAL_CONFIGFLAGS;
5098 else
5099 RegistryValueName = REGSTR_VAL_CSCONFIGFLAGS;
5100
5101 switch (PropChange->StateChange)
5102 {
5103 case DICS_ENABLE:
5104 case DICS_DISABLE:
5105 {
5106 if (PropChange->Scope == DICS_FLAG_GLOBAL)
5107 hRootKey = set->HKLM;
5108 else /* PropChange->Scope == DICS_FLAG_CONFIGSPECIFIC */
5109 {
5110 hRootKey = OpenHardwareProfileKey(set->HKLM, PropChange->HwProfile, KEY_CREATE_SUB_KEY);
5111 if (hRootKey == INVALID_HANDLE_VALUE)
5112 goto cleanup;
5113 }
5114
5115 /* Enable/disable device in registry */
5116 hKey = SETUPDI_OpenDrvKey(hRootKey, deviceInfo, KEY_QUERY_VALUE | KEY_SET_VALUE);
5118 hKey = SETUPDI_CreateDevKey(hRootKey, deviceInfo, KEY_QUERY_VALUE | KEY_SET_VALUE);
5120 break;
5121 dwLength = sizeof(DWORD);
5122 rc = RegQueryValueExW(
5123 hKey,
5124 RegistryValueName,
5125 NULL,
5126 &dwRegType,
5127 (LPBYTE)&dwConfigFlags, &dwLength);
5128 if (rc == ERROR_FILE_NOT_FOUND)
5129 dwConfigFlags = 0;
5130 else if (rc != ERROR_SUCCESS)
5131 {
5132 SetLastError(rc);
5133 goto cleanup;
5134 }
5135 else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
5136 {
5138 goto cleanup;
5139 }
5140 if (PropChange->StateChange == DICS_ENABLE)
5141 dwConfigFlags &= ~(PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
5142 else
5143 dwConfigFlags |= (PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
5144 rc = RegSetValueExW(
5145 hKey,
5146 RegistryValueName,
5147 0,
5148 REG_DWORD,
5149 (LPBYTE)&dwConfigFlags, sizeof(DWORD));
5150 if (rc != ERROR_SUCCESS)
5151 {
5152 SetLastError(rc);
5153 goto cleanup;
5154 }
5155
5156 /* Enable/disable device if needed */
5157 if (PropChange->Scope == DICS_FLAG_GLOBAL
5158 || PropChange->HwProfile == 0
5159 || PropChange->HwProfile == SETUPAPI_GetCurrentHwProfile(DeviceInfoSet))
5160 {
5161 if (PropChange->StateChange == DICS_ENABLE)
5163 else
5165 }
5166 else
5167 ret = TRUE;
5168 break;
5169 }
5170 case DICS_PROPCHANGE:
5171 {
5173 break;
5174 }
5175 default:
5176 {
5177 ERR("Unknown StateChange 0x%lx\n", PropChange->StateChange);
5179 }
5180 }
5181
5182cleanup:
5183 if (hRootKey != INVALID_HANDLE_VALUE && hRootKey != set->HKLM)
5184 RegCloseKey(hRootKey);
5185
5188
5189 TRACE("Returning %d\n", ret);
5190 return ret;
5191}
5192
5193/***********************************************************************
5194 * SetupDiSelectDevice (SETUPAPI.@)
5195 */
5200{
5201 FIXME("%p %p\n", DeviceInfoSet, DeviceInfoData);
5203 return FALSE;
5204}
5205
5206
5207/***********************************************************************
5208 * SetupDiRegisterCoDeviceInstallers (SETUPAPI.@)
5209 */
5214{
5215 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5216 struct DeviceInfo *deviceInfo;
5217 BOOL ret = FALSE; /* Return value */
5218
5220
5221 if (!DeviceInfoSet)
5227 else if (!DeviceInfoData)
5229 else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
5231 else
5232 {
5234 struct DriverInfoElement *SelectedDriver;
5235 BOOL Result;
5236 DWORD DoAction;
5237 WCHAR SectionName[MAX_PATH];
5238 DWORD SectionNameLength = 0;
5240 PVOID Context = NULL;
5241
5242 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
5244 if (!Result)
5245 goto cleanup;
5246
5247 SelectedDriver = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
5248 if (SelectedDriver == NULL)
5249 {
5251 goto cleanup;
5252 }
5253
5254 /* Get .CoInstallers section name */
5256 SelectedDriver->InfFileDetails->hInf,
5257 SelectedDriver->Details.SectionName,
5258 SectionName, MAX_PATH, &SectionNameLength, NULL);
5259 if (!Result || SectionNameLength > MAX_PATH - strlenW(DotCoInstallers) - 1)
5260 goto cleanup;
5261 lstrcatW(SectionName, DotCoInstallers);
5262
5263 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5264
5265 /* Open/Create driver key information */
5266#if _WIN32_WINNT >= 0x502
5267 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_READ | KEY_WRITE);
5268#else
5269 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_ALL_ACCESS);
5270#endif
5272#if _WIN32_WINNT >= 0x502
5274#else
5276#endif
5278 goto cleanup;
5279
5280 /* Install .CoInstallers section */
5281 DoAction = SPINST_REGISTRY;
5283 {
5284 DoAction |= SPINST_FILES;
5286 if (!Context)
5287 goto cleanup;
5288 }
5290 SelectedDriver->InfFileDetails->hInf, SectionName,
5291 DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
5294 if (!Result)
5295 goto cleanup;
5296
5297 ret = TRUE;
5298
5299cleanup:
5300 if (Context)
5304 }
5305
5306 TRACE("Returning %d\n", ret);
5307 return ret;
5308}
5309
5310static BOOL
5313 OUT LPBOOL IsOEMLocation)
5314{
5315 PWCHAR last;
5316
5317 last = strrchrW(FullName, '\\');
5318 if (!last)
5319 {
5320 /* No directory specified */
5321 *IsOEMLocation = FALSE;
5322 }
5323 else
5324 {
5325 LPWSTR Windir;
5326 UINT ret;
5327
5328 Windir = MyMalloc((MAX_PATH + 1 + strlenW(InfDirectory)) * sizeof(WCHAR));
5329 if (!Windir)
5330 {
5332 return FALSE;
5333 }
5334
5336 if (ret == 0 || ret > MAX_PATH)
5337 {
5338 MyFree(Windir);
5340 return FALSE;
5341 }
5342 if (*Windir && Windir[strlenW(Windir) - 1] != '\\')
5343 strcatW(Windir, BackSlash);
5344 strcatW(Windir, InfDirectory);
5345
5346 if (strncmpiW(FullName, Windir, last - FullName) == 0)
5347 {
5348 /* The path is %SYSTEMROOT%\Inf */
5349 *IsOEMLocation = FALSE;
5350 }
5351 else
5352 {
5353 /* The file is in another place */
5354 *IsOEMLocation = TRUE;
5355 }
5356 MyFree(Windir);
5357 }
5358 return TRUE;
5359}
5360
5361/***********************************************************************
5362 * SetupDiInstallDevice (SETUPAPI.@)
5363 */
5368{
5369 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5370 struct DeviceInfo *deviceInfo;
5372 struct DriverInfoElement *SelectedDriver;
5374 WCHAR SectionName[MAX_PATH];
5375 WCHAR Buffer[32];
5376 DWORD SectionNameLength = 0;
5377 BOOL Result = FALSE;
5378 ULONG DoAction;
5380 LPWSTR pSectionName = NULL;
5381 WCHAR ClassName[MAX_CLASS_NAME_LEN];
5383 LPWSTR lpGuidString = NULL, lpFullGuidString = NULL;
5384 BOOL RebootRequired = FALSE;
5386 BOOL NeedtoCopyFile;
5387 LARGE_INTEGER fullVersion;
5388 LONG rc;
5389 PVOID Context = NULL;
5390 BOOL ret = FALSE; /* Return value */
5391
5393
5394 if (!DeviceInfoSet)
5400 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
5402 else
5403 Result = TRUE;
5404
5405 if (!Result)
5406 {
5407 /* One parameter is bad */
5408 goto cleanup;
5409 }
5410
5411 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
5413 if (!Result)
5414 goto cleanup;
5415
5416 if (InstallParams.FlagsEx & DI_FLAGSEX_SETFAILEDINSTALL)
5417 {
5418 /* Set FAILEDINSTALL in ConfigFlags registry value */
5419 DWORD ConfigFlags, regType;
5424 &regType,
5425 (PBYTE)&ConfigFlags,
5426 sizeof(ConfigFlags),
5427 NULL);
5428 if (!Result || regType != REG_DWORD)
5429 {
5431 goto cleanup;
5432 }
5433 ConfigFlags |= CONFIGFLAG_FAILEDINSTALL;
5438 (PBYTE)&ConfigFlags,
5439 sizeof(ConfigFlags));
5440 if (!Result)
5441 {
5443 goto cleanup;
5444 }
5445
5446 ret = TRUE;
5447 goto cleanup;
5448 }
5449
5450 SelectedDriver = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
5451 if (SelectedDriver == NULL)
5452 {
5454 goto cleanup;
5455 }
5456
5457 FileTimeToSystemTime(&SelectedDriver->Info.DriverDate, &DriverDate);
5458
5460 SelectedDriver->InfFileDetails->hInf,
5461 SelectedDriver->Details.SectionName,
5462 SectionName, MAX_PATH, &SectionNameLength, NULL);
5463 if (!Result || SectionNameLength > MAX_PATH - strlenW(DotServices))
5464 goto cleanup;
5465 pSectionName = &SectionName[strlenW(SectionName)];
5466
5467 /* Get information from [Version] section */
5469 goto cleanup;
5470 /* Format ClassGuid to a string */
5471 if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
5472 goto cleanup;
5473 RequiredSize = lstrlenW(lpGuidString);
5474 lpFullGuidString = HeapAlloc(GetProcessHeap(), 0, (RequiredSize + 3) * sizeof(WCHAR));
5475 if (!lpFullGuidString)
5476 {
5478 goto cleanup;
5479 }
5480 lpFullGuidString[0] = '{';
5481 memcpy(&lpFullGuidString[1], lpGuidString, RequiredSize * sizeof(WCHAR));
5482 lpFullGuidString[RequiredSize + 1] = '}';
5483 lpFullGuidString[RequiredSize + 2] = '\0';
5484
5485 /* Copy .inf file to Inf\ directory (if needed) */
5486 Result = InfIsFromOEMLocation(SelectedDriver->Details.InfFileName, &NeedtoCopyFile);
5487 if (!Result)
5488 goto cleanup;
5489 if (NeedtoCopyFile)
5490 {
5491 WCHAR NewFileName[MAX_PATH];
5492 struct InfFileDetails *newInfFileDetails;
5494 SelectedDriver->Details.InfFileName,
5495 NULL,
5496 SPOST_NONE,
5498 NewFileName, MAX_PATH,
5499 NULL,
5500 NULL);
5502 goto cleanup;
5503 /* Create a new struct InfFileDetails, and set it to
5504 * SelectedDriver->InfFileDetails, to release use of
5505 * current InfFile */
5506 newInfFileDetails = CreateInfFileDetails(NewFileName);
5507 if (!newInfFileDetails)
5508 goto cleanup;
5509 DereferenceInfFile(SelectedDriver->InfFileDetails);
5510 SelectedDriver->InfFileDetails = newInfFileDetails;
5511 strcpyW(SelectedDriver->Details.InfFileName, NewFileName);
5512 }
5513
5514 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5515
5516 /* Open/Create driver key information */
5517#if _WIN32_WINNT >= 0x502
5518 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_READ | KEY_WRITE);
5519#else
5520 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_ALL_ACCESS);
5521#endif
5523#if _WIN32_WINNT >= 0x502
5525#else
5527#endif
5529 goto cleanup;
5530
5531 /* Install main section */
5532 DoAction = 0;
5534 DoAction |= SPINST_REGISTRY;
5536 {
5537 DoAction |= SPINST_FILES;
5539 if (!Context)
5540 goto cleanup;
5541 }
5542 *pSectionName = '\0';
5544 SelectedDriver->InfFileDetails->hInf, SectionName,
5545 DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
5548 if (!Result)
5549 goto cleanup;
5552
5553 /* Write information to driver key */
5554 *pSectionName = UNICODE_NULL;
5555 memcpy(&fullVersion, &SelectedDriver->Info.DriverVersion, sizeof(LARGE_INTEGER));
5556 TRACE("Write information to driver key\n");
5557 TRACE("DriverDate : '%u-%u-%u'\n", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
5558 TRACE("DriverDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
5559 TRACE("DriverVersion : '%ld.%ld.%lu.%ld'\n", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
5560 TRACE("InfPath : '%s'\n", debugstr_w(SelectedDriver->InfFileDetails->FileName));
5561 TRACE("InfSection : '%s'\n", debugstr_w(SelectedDriver->Details.SectionName));
5562 TRACE("InfSectionExt : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)]));
5563 TRACE("MatchingDeviceId: '%s'\n", debugstr_w(SelectedDriver->MatchingId));
5564 TRACE("ProviderName : '%s'\n", debugstr_w(SelectedDriver->Info.ProviderName));
5565 sprintfW(Buffer, DateFormat, DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
5566 rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
5567 if (rc == ERROR_SUCCESS)
5568 rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE_DATA, 0, REG_BINARY, (const BYTE *)&SelectedDriver->Info.DriverDate, sizeof(FILETIME));
5569 if (rc == ERROR_SUCCESS)
5570 rc = RegSetValueExW(hKey, REGSTR_VAL_DRVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
5571 if (rc == ERROR_SUCCESS)
5572 {
5573 sprintfW(Buffer, VersionFormat, fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
5574 rc = RegSetValueExW(hKey, REGSTR_DRIVER_VERSION, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
5575 }
5576 if (rc == ERROR_SUCCESS)
5577 rc = RegSetValueExW(hKey, REGSTR_VAL_INFPATH, 0, REG_SZ, (const BYTE *)SelectedDriver->InfFileDetails->FileName, (strlenW(SelectedDriver->InfFileDetails->FileName) + 1) * sizeof(WCHAR));
5578 if (rc == ERROR_SUCCESS)
5579 rc = RegSetValueExW(hKey, REGSTR_VAL_INFSECTION, 0, REG_SZ, (const BYTE *)SelectedDriver->Details.SectionName, (strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
5580 if (rc == ERROR_SUCCESS)
5581 rc = RegSetValueExW(hKey, REGSTR_VAL_INFSECTIONEXT, 0, REG_SZ, (const BYTE *)&SectionName[strlenW(SelectedDriver->Details.SectionName)], (strlenW(SectionName) - strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
5582 if (rc == ERROR_SUCCESS)
5583 rc = RegSetValueExW(hKey, REGSTR_VAL_MATCHINGDEVID, 0, REG_SZ, (const BYTE *)SelectedDriver->MatchingId, (strlenW(SelectedDriver->MatchingId) + 1) * sizeof(WCHAR));
5584 if (rc == ERROR_SUCCESS)
5585 rc = RegSetValueExW(hKey, REGSTR_VAL_PROVIDER_NAME, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.ProviderName, (strlenW(SelectedDriver->Info.ProviderName) + 1) * sizeof(WCHAR));
5586 if (rc != ERROR_SUCCESS)
5587 {
5588 SetLastError(rc);
5589 goto cleanup;
5590 }
5593
5594 /* FIXME: Process .LogConfigOverride section */
5595
5596 /* Install .Services section */
5597 strcpyW(pSectionName, DotServices);
5599 SelectedDriver->InfFileDetails->hInf,
5600 SectionName,
5601 0,
5604 NULL,
5605 NULL);
5606 if (!Result)
5607 {
5609 goto cleanup;
5611 }
5613 RebootRequired = TRUE;
5614
5615 /* Open device registry key */
5618 goto cleanup;
5619
5620 /* Install .HW section */
5621 DoAction = 0;
5623 DoAction |= SPINST_REGISTRY;
5624 strcpyW(pSectionName, DotHW);
5626 SelectedDriver->InfFileDetails->hInf, SectionName,
5627 DoAction, hKey, NULL, 0,
5628 NULL, NULL,
5630 if (!Result)
5631 goto cleanup;
5632
5633 /* Write information to enum key */
5634 TRACE("Write information to enum key\n");
5635 TRACE("Class : '%s'\n", debugstr_w(ClassName));
5636 TRACE("ClassGUID : '%s'\n", debugstr_w(lpFullGuidString));
5637 TRACE("DeviceDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
5638 TRACE("Mfg : '%s'\n", debugstr_w(SelectedDriver->Info.MfgName));
5639 rc = RegSetValueExW(hKey, REGSTR_VAL_CLASS, 0, REG_SZ, (const BYTE *)ClassName, (strlenW(ClassName) + 1) * sizeof(WCHAR));
5640 if (rc == ERROR_SUCCESS)
5641 rc = RegSetValueExW(hKey, REGSTR_VAL_CLASSGUID, 0, REG_SZ, (const BYTE *)lpFullGuidString, (strlenW(lpFullGuidString) + 1) * sizeof(WCHAR));
5642 if (rc == ERROR_SUCCESS)
5643 rc = RegSetValueExW(hKey, REGSTR_VAL_DEVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
5644 if (rc == ERROR_SUCCESS)
5645 rc = RegSetValueExW(hKey, REGSTR_VAL_MFG, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.MfgName, (strlenW(SelectedDriver->Info.MfgName) + 1) * sizeof(WCHAR));
5646 if (rc != ERROR_SUCCESS)
5647 {
5648 SetLastError(rc);
5649 goto cleanup;
5650 }
5651
5652 /* Start the device */
5653 if (!RebootRequired && !(InstallParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG)))
5655 else
5656 ret = TRUE;
5657
5658cleanup:
5659 /* End of installation */
5662 if (lpGuidString)
5663 RpcStringFreeW(&lpGuidString);
5664 HeapFree(GetProcessHeap(), 0, lpFullGuidString);
5665 if (Context)
5667 TRACE("Returning %d\n", ret);
5668 return ret;
5669}
5670
5672{
5673 HKEY enumKey, key = INVALID_HANDLE_VALUE;
5674 LONG l;
5675
5677 if (!l)
5678 {
5679 l = RegCreateKeyExW(enumKey, devInfo->instanceId, 0, NULL, REG_OPTION_NON_VOLATILE, samDesired, NULL, &key, NULL);
5680 RegCloseKey(enumKey);
5681 }
5682 if (l)
5683 SetLastError(l);
5684 return key;
5685}
5686
5688{
5690 LPWSTR lpGuidString = NULL;
5691 LPWSTR DriverKey = NULL; /* {GUID}\Index */
5692 LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
5693 DWORD Index; /* Index used in the DriverKey name */
5694 DWORD dwSize;
5696 DWORD rc;
5697 HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
5698 HKEY hEnumKey = NULL;
5700 HKEY hDeviceKey = INVALID_HANDLE_VALUE;
5701 HKEY hKey = NULL;
5702
5703 /* Open device key, to read Driver value */
5704 hDeviceKey = SETUPDI_OpenDevKey(RootKey, devInfo, KEY_QUERY_VALUE | KEY_SET_VALUE);
5705 if (hDeviceKey == INVALID_HANDLE_VALUE)
5706 goto cleanup;
5707
5709 if (rc != ERROR_SUCCESS)
5710 {
5711 SetLastError(rc);
5712 goto cleanup;
5713 }
5714
5715 rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, NULL, &dwSize);
5716 if (rc != ERROR_SUCCESS)
5717 {
5718 /* Create a new driver key */
5719
5720 if (UuidToStringW(ClassGuid, &lpGuidString) != RPC_S_OK)
5721 goto cleanup;
5722
5723 /* The driver key is in \System\CurrentControlSet\Control\Class\{GUID}\Index */
5724 DriverKey = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
5725 if (!DriverKey)
5726 {
5728 goto cleanup;
5729 }
5730
5731 DriverKey[0] = '{';
5732 strcpyW(&DriverKey[1], lpGuidString);
5733 pDeviceInstance = &DriverKey[strlenW(DriverKey)];
5734 *pDeviceInstance++ = '}';
5735 *pDeviceInstance++ = '\\';
5736
5737 /* Try all values for Index between 0 and 9999 */
5738 Index = 0;
5739 while (Index <= 9999)
5740 {
5741 sprintfW(pDeviceInstance, InstanceKeyFormat, Index);
5743 DriverKey,
5744 0,
5745 NULL,
5747#if _WIN32_WINNT >= 0x502
5749#else
5751#endif
5752 NULL,
5753 &hKey,
5754 &Disposition);
5755 if (rc != ERROR_SUCCESS)
5756 {
5757 SetLastError(rc);
5758 goto cleanup;
5759 }
5761 break;
5763 hKey = NULL;
5764 Index++;
5765 }
5766
5767 if (Index > 9999)
5768 {
5769 /* Unable to create more than 9999 devices within the same class */
5771 goto cleanup;
5772 }
5773
5774 /* Write the new Driver value */
5775 rc = RegSetValueExW(hDeviceKey, REGSTR_VAL_DRIVER, 0, REG_SZ, (const BYTE *)DriverKey, (strlenW(DriverKey) + 1) * sizeof(WCHAR));
5776 if (rc != ERROR_SUCCESS)
5777 {
5778 SetLastError(rc);
5779 goto cleanup;
5780 }
5781 }
5782 else
5783 {
5784 /* Open the existing driver key */
5785
5786 DriverKey = HeapAlloc(GetProcessHeap(), 0, dwSize);
5787 if (!DriverKey)
5788 {
5790 goto cleanup;
5791 }
5792
5793 rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, (LPBYTE)DriverKey, &dwSize);
5794 if (rc != ERROR_SUCCESS)
5795 {
5796 SetLastError(rc);
5797 goto cleanup;
5798 }
5799
5801 DriverKey,
5802 0,
5803 NULL,
5805#if _WIN32_WINNT >= 0x502
5807#else
5809#endif
5810 NULL,
5811 &hKey,
5812 &Disposition);
5813 if (rc != ERROR_SUCCESS)
5814 {
5815 SetLastError(rc);
5816 goto cleanup;
5817 }
5818 }
5819
5820 key = hKey;
5821
5822cleanup:
5823 if (lpGuidString)
5824 RpcStringFreeW(&lpGuidString);
5825 HeapFree(GetProcessHeap(), 0, DriverKey);
5826 if (hHWProfileKey != INVALID_HANDLE_VALUE)
5827 RegCloseKey(hHWProfileKey);
5828 if (hEnumKey != NULL)
5830 if (hClassKey != NULL)
5832 if (hDeviceKey != INVALID_HANDLE_VALUE)
5833 RegCloseKey(hDeviceKey);
5834 if (hKey != NULL && hKey != key)
5836
5837 TRACE("Returning 0x%p\n", hKey);
5838 return hKey;
5839}
5840
5842{
5843 HKEY enumKey, key = INVALID_HANDLE_VALUE;
5844 LONG l;
5845
5847 if (!l)
5848 {
5849 l = RegOpenKeyExW(enumKey, devInfo->instanceId, 0, samDesired, &key);
5850 RegCloseKey(enumKey);
5851 }
5852 if (l)
5853 SetLastError(l);
5854 return key;
5855}
5856
5858{
5859 LPWSTR DriverKey = NULL;
5860 DWORD dwLength = 0;
5861 DWORD dwRegType;
5862 DWORD rc;
5863 HKEY hEnumKey = NULL;
5864 HKEY hKey = NULL;
5866
5869 goto cleanup;
5870 /* Read the 'Driver' key */
5872 if (rc != ERROR_SUCCESS)
5873 {
5874 SetLastError(rc);
5875 goto cleanup;
5876 }
5877 else if (dwRegType != REG_SZ)
5878 {
5880 goto cleanup;
5881 }
5882 DriverKey = HeapAlloc(GetProcessHeap(), 0, dwLength);
5883 if (!DriverKey)
5884 {
5886 goto cleanup;
5887 }
5888 rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
5889 if (rc != ERROR_SUCCESS)
5890 {
5891 SetLastError(rc);
5892 goto cleanup;
5893 }
5895 hKey = NULL;
5896 /* Need to open the driver key */
5897 rc = RegOpenKeyExW(
5898 RootKey,
5900 0, /* Options */
5902 &hEnumKey);
5903 if (rc != ERROR_SUCCESS)
5904 {
5905 SetLastError(rc);
5906 goto cleanup;
5907 }
5908 rc = RegOpenKeyExW(
5909 hEnumKey,
5910 DriverKey,
5911 0, /* Options */
5912 samDesired,
5913 &hKey);
5914 if (rc != ERROR_SUCCESS)
5915 {
5916 SetLastError(rc);
5917 goto cleanup;
5918 }
5919 key = hKey;
5920
5921cleanup:
5922 if (hEnumKey != NULL)
5924 if (hKey != NULL && hKey != key)
5926 if (DriverKey)
5927 HeapFree(GetProcessHeap(), 0, DriverKey);
5928 return key;
5929}
5930
5931/***********************************************************************
5932 * SetupDiOpenDevRegKey (SETUPAPI.@)
5933 */
5937 DWORD Scope,
5938 DWORD HwProfile,
5939 DWORD KeyType,
5940 REGSAM samDesired)
5941{
5943 struct DeviceInfo *devInfo;
5945 HKEY RootKey;
5946
5947 TRACE("%s(%p %p %d %d %d %x)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
5948 Scope, HwProfile, KeyType, samDesired);
5949
5951 {
5953 return INVALID_HANDLE_VALUE;
5954 }
5955 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
5956 {
5958 return INVALID_HANDLE_VALUE;
5959 }
5962 {
5964 return INVALID_HANDLE_VALUE;
5965 }
5966 if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
5967 {
5969 return INVALID_HANDLE_VALUE;
5970 }
5971 if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
5972 {
5974 return INVALID_HANDLE_VALUE;
5975 }
5976 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5977 if (devInfo->set != set)
5978 {
5980 return INVALID_HANDLE_VALUE;
5981 }
5982 if (Scope != DICS_FLAG_GLOBAL)
5983 {
5984 RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
5986 return INVALID_HANDLE_VALUE;
5987 }
5988 else
5989 RootKey = set->HKLM;
5990 switch (KeyType)
5991 {
5992 case DIREG_DEV:
5993 key = SETUPDI_OpenDevKey(RootKey, devInfo, samDesired);
5994 if (Scope == DICS_FLAG_GLOBAL)
5995 {
5996 LONG rc;
5997 HKEY hTempKey = key;
5998 rc = RegOpenKeyExW(hTempKey,
5999 L"Device Parameters",
6000 0,
6001 samDesired,
6002 &key);
6003 if (rc == ERROR_SUCCESS)
6004 RegCloseKey(hTempKey);
6005 }
6006 break;
6007 case DIREG_DRV:
6008 key = SETUPDI_OpenDrvKey(RootKey, devInfo, samDesired);
6009 break;
6010 default:
6011 WARN("unknown KeyType %d\n", KeyType);
6012 }
6013 if (RootKey != set->HKLM)
6015 return key;
6016}
6017
6019{
6020 FIXME("\n");
6021 return FALSE;
6022}
6023
6025{
6026 FIXME("\n");
6027 return FALSE;
6028}
6029
6030/***********************************************************************
6031 * SetupDiDeleteDevRegKey (SETUPAPI.@)
6032 */
6036 DWORD Scope,
6037 DWORD HwProfile,
6038 DWORD KeyType)
6039{
6040 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
6041 struct DeviceInfo *devInfo;
6042 BOOL ret = FALSE;
6043 HKEY RootKey;
6044
6045 TRACE("%s(%p %p %d %d %d)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, Scope, HwProfile,
6046 KeyType);
6047
6049 {
6051 return FALSE;
6052 }
6053 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
6054 {
6056 return FALSE;
6057 }
6060 {
6062 return FALSE;
6063 }
6064 if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
6065 {
6067 return FALSE;
6068 }
6069 if (KeyType != DIREG_DEV && KeyType != DIREG_DRV && KeyType != DIREG_BOTH)
6070 {
6072 return FALSE;
6073 }
6074 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
6075 if (devInfo->set != set)
6076 {
6078 return FALSE;
6079 }
6080 if (Scope != DICS_FLAG_GLOBAL)
6081 {
6082 RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
6084 return FALSE;
6085 }
6086 else
6087 RootKey = set->HKLM;
6088 switch (KeyType)
6089 {
6090 case DIREG_DEV:
6091 ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
6092 break;
6093 case DIREG_DRV:
6094 ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
6095 break;
6096 case DIREG_BOTH:
6097 ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
6098 if (ret)
6099 ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
6100 break;
6101 default:
6102 WARN("unknown KeyType %d\n", KeyType);
6103 }
6104 if (RootKey != set->HKLM)
6106 return ret;
6107}
6108
6109/***********************************************************************
6110 * SetupDiRestartDevices (SETUPAPI.@)
6111 */
6112BOOL
6113WINAPI
6117{
6118 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
6119 struct DeviceInfo *devInfo;
6120 CONFIGRET cr;
6121
6123
6125 {
6127 return FALSE;
6128 }
6129 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
6130 {
6132 return FALSE;
6133 }
6134
6137 {
6139 return FALSE;
6140 }
6141
6142 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
6143
6144 cr = CM_Enable_DevNode_Ex(devInfo->dnDevInst, 0, set->hMachine);
6145 if (cr != CR_SUCCESS)
6146 {
6148 return FALSE;
6149 }
6150
6151 return TRUE;
6152}
#define EINVAL
Definition: acclib.h:90
#define ERANGE
Definition: acclib.h:92
#define _WIN32_WINNT
Definition: precomp.h:14
static const WCHAR nameW[]
Definition: main.c:46
HKEY hClassKey
Definition: umpnpmgr.c:45
static HANDLE hEnumKey
Definition: devinst.c:20
@ Reserved2
Definition: bcd.h:202
@ Reserved1
Definition: bcd.h:201
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
r l[0]
Definition: byte_order.h:168
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define CR_INVALID_PROPERTY
Definition: cfgmgr32.h:899
#define MAX_CLASS_NAME_LEN
Definition: cfgmgr32.h:52
#define CR_INVALID_DATA
Definition: cfgmgr32.h:877
#define CM_OPEN_CLASS_KEY_INSTALLER
Definition: cfgmgr32.h:772
#define CM_Create_DevInst_Ex
Definition: cfgmgr32.h:1128
#define CR_INVALID_DEVICE_ID
Definition: cfgmgr32.h:876
#define CR_OUT_OF_MEMORY
Definition: cfgmgr32.h:844
#define CM_CREATE_DEVINST_GENERATE_ID
Definition: cfgmgr32.h:629
#define CM_CREATE_DEVINST_PHANTOM
Definition: cfgmgr32.h:628
_Null_terminated_ WCHAR * DEVINSTID_W
Definition: cfgmgr32.h:80
#define CR_FAILURE
Definition: cfgmgr32.h:865
#define RegDisposition_OpenExisting
Definition: cfgmgr32.h:610
#define CR_INVALID_DEVINST
Definition: cfgmgr32.h:848
#define CM_DRP_DEVICEDESC
Definition: cfgmgr32.h:676
DWORD DEVINST
Definition: cfgmgr32.h:76
#define CR_ACCESS_DENIED
Definition: cfgmgr32.h:897
#define CR_INVALID_MACHINENAME
Definition: cfgmgr32.h:893
#define CM_Locate_DevInst_ExW
Definition: cfgmgr32.h:2395
#define CR_INVALID_FLAG
Definition: cfgmgr32.h:846
#define CR_ALREADY_SUCH_DEVINST
Definition: cfgmgr32.h:862
#define CM_LOCATE_DEVINST_NORMAL
Definition: cfgmgr32.h:766
#define CM_Create_DevInst_ExW
Definition: cfgmgr32.h:1117
#define CR_NO_SUCH_DEVNODE
Definition: cfgmgr32.h:857
DEVINSTID_A DEVINSTID
Definition: cfgmgr32.h:87
#define CR_BUFFER_SMALL
Definition: cfgmgr32.h:872
#define CR_CALL_NOT_IMPLEMENTED
Definition: cfgmgr32.h:898
RETURN_TYPE CONFIGRET
Definition: cfgmgr32.h:74
#define CR_INVALID_POINTER
Definition: cfgmgr32.h:845
#define CR_SUCCESS
Definition: cfgmgr32.h:842
#define CM_LOCATE_DEVNODE_PHANTOM
Definition: cfgmgr32.h:761
#define CR_NO_SUCH_VALUE
Definition: cfgmgr32.h:883
#define CM_CREATE_DEVINST_DO_NOT_INSTALL
Definition: cfgmgr32.h:630
#define CR_NO_SUCH_REGISTRY_KEY
Definition: cfgmgr32.h:892
#define CR_INVALID_DEVNODE
Definition: cfgmgr32.h:847
#define CR_REGISTRY_ERROR
Definition: cfgmgr32.h:875
#define CM_CREATE_DEVINST_NORMAL
Definition: cfgmgr32.h:626
#define CM_Get_Device_ID_Ex
Definition: cfgmgr32.h:1566
CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW(_In_ DEVINST dnDevInst, _In_ ULONG ulProperty, _Out_opt_ PULONG pulRegDataType, _Out_writes_bytes_opt_(*pulLength) PVOID Buffer, _Inout_ PULONG pulLength, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:3479
CONFIGRET WINAPI CM_Disconnect_Machine(_In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:1863
CONFIGRET WINAPI CM_Open_Class_Key_ExW(_In_opt_ LPGUID pClassGuid, _In_opt_ LPCWSTR pszClassName, _In_ REGSAM samDesired, _In_ REGDISPOSITION Disposition, _Out_ PHKEY phkClass, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:6288
CONFIGRET WINAPI CM_Get_Parent_Ex(_Out_ PDEVINST pdnDevInst, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:5314
CONFIGRET WINAPI CM_Connect_MachineW(_In_opt_ PCWSTR UNCServerName, _Out_ PHMACHINE phMachine)
Definition: cfgmgr.c:1241
CONFIGRET WINAPI CM_Disable_DevNode_Ex(_In_ DEVINST dnDevInst, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:1797
CONFIGRET WINAPI CM_Locate_DevNode_ExW(_Out_ PDEVINST pdnDevInst, _In_opt_ DEVINSTID_W pDeviceID, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:5911
CONFIGRET WINAPI CM_Enumerate_Classes_Ex(_In_ ULONG ulClassIndex, _Out_ LPGUID ClassGuid, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:2009
CONFIGRET WINAPI CM_Enable_DevNode_Ex(_In_ DEVINST dnDevInst, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:1927
Definition: bufpool.h:45
Definition: list.h:37
Definition: _set.h:50
static const WCHAR szClassName[]
Definition: clipbrd.c:11
static HWND hwndParent
Definition: cryptui.c:300
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_SUCCESS
Definition: deptool.c:10
#define MAX_DEVICE_ID_LEN
Definition: devaction.c:40
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAX_GUID_STRING_LEN
Definition: apphelp.c:29
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegConnectRegistryW(LPCWSTR lpMachineName, HKEY hKey, PHKEY phkResult)
Definition: reg.c:874
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define FreeLibrary(x)
Definition: compat.h:748
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define wcsicmp
Definition: compat.h:15
#define lstrlenW
Definition: compat.h:750
static DWORD DWORD * dwLength
Definition: fusion.c:86
static void cleanup(void)
Definition: main.c:1335
PVOID QueryRegistryValue(HANDLE RegHandle, PWCHAR ValueName, LPDWORD RegistryType, LPDWORD Length)
Definition: registry.c:67
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2397
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
static const WCHAR sizeW[]
Definition: editor.c:79
LONG SETUP_CreateDevicesList(IN OUT struct DeviceInfoSet *list, IN PCWSTR MachineName OPTIONAL, IN CONST GUID *Class OPTIONAL, IN PCWSTR Enumerator OPTIONAL)
Definition: devclass.c:121
static const WCHAR ClassGUID[]
Definition: devclass.c:30
BOOL WINAPI SetupDiInstallClassExW(IN HWND hwndParent OPTIONAL, IN PCWSTR InfFileName OPTIONAL, IN DWORD Flags, IN HSPFILEQ FileQueue OPTIONAL, IN CONST GUID *InterfaceClassGuid OPTIONAL, IN PVOID Reserved1, IN PVOID Reserved2)
Definition: devclass.c:708
static const WCHAR InstanceKeyFormat[]
Definition: devinst.c:33
static BOOL InfIsFromOEMLocation(IN PCWSTR FullName, OUT LPBOOL IsOEMLocation)
Definition: devinst.c:5311
BOOL WINAPI SetupDiSetClassInstallParamsA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_CLASSINSTALL_HEADER ClassInstallParams, DWORD ClassInstallParamsSize)
Definition: devinst.c:4002
static BOOL DestroyDeviceInfo(struct DeviceInfo *deviceInfo)
Definition: devinst.c:581
BOOL WINAPI SetupDiOpenDeviceInfoA(IN HDEVINFO DeviceInfoSet, IN PCSTR DeviceInstanceId, IN HWND hwndParent OPTIONAL, IN DWORD OpenFlags, OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: devinst.c:4745
#define CLASS_COINSTALLER
HDEVINFO WINAPI SetupDiGetClassDevsExA(const GUID *class, PCSTR enumstr, HWND parent, DWORD flags, HDEVINFO deviceset, PCSTR machine, PVOID reserved)
Definition: devinst.c:2249
static const WCHAR DateFormat[]
Definition: devinst.c:28
BOOL WINAPI SetupDiGetActualSectionToInstallExA(IN HINF InfHandle, IN PCSTR InfSectionName, IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL, OUT PSTR InfSectionWithExt OPTIONAL, IN DWORD InfSectionWithExtSize, OUT PDWORD RequiredSize OPTIONAL, OUT PSTR *Extension OPTIONAL, IN PVOID Reserved)
Definition: devinst.c:1997
BOOL WINAPI SetupDiRegisterCoDeviceInstallers(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5211
BOOL WINAPI SetupDiCreateDeviceInterfaceA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, PCSTR ReferenceString, DWORD CreationFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:2501
BOOL WINAPI SetupDiRestartDevices(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:6114
HDEVINFO WINAPI SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, HWND hwndParent, PCWSTR MachineName, PVOID Reserved)
Definition: devinst.c:1259
static BOOL CheckSectionValid(IN LPCWSTR SectionName, IN PSP_ALTPLATFORM_INFO PlatformInfo, IN BYTE ProductType, IN WORD SuiteMask, OUT PDWORD ScorePlatform, OUT PDWORD ScoreMajorVersion, OUT PDWORD ScoreMinorVersion, OUT PDWORD ScoreProductType, OUT PDWORD ScoreSuiteMask)
Definition: devinst.c:124
BOOL WINAPI SetupDiBuildClassInfoListExW(DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, LPCWSTR MachineName, PVOID Reserved)
Definition: devinst.c:722
BOOL WINAPI SetupDiOpenDeviceInterfaceA(HDEVINFO DeviceInfoSet, PCSTR DevicePath, DWORD OpenFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:3976
BOOL WINAPI SetupDiGetClassDescriptionExA(const GUID *ClassGuid, PSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved)
Definition: devinst.c:2086
BOOL WINAPI SetupDiBuildClassInfoList(DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize)
Definition: devinst.c:645
BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
Definition: devinst.c:3139
static HKEY OpenHardwareProfileKey(IN HKEY HKLM, IN DWORD HwProfile, IN DWORD samDesired)
Definition: devinst.c:4635
BOOL WINAPI SetupDiInstallClassExA(IN HWND hwndParent OPTIONAL, IN PCSTR InfFileName OPTIONAL, IN DWORD Flags, IN HSPFILEQ FileQueue OPTIONAL, IN CONST GUID *InterfaceClassGuid OPTIONAL, IN PVOID Reserved1, IN PVOID Reserved2)
Definition: devinst.c:3483
static BOOL SETUPDI_DeleteDrvKey(HKEY RootKey, struct DeviceInfo *devInfo)
Definition: devinst.c:6024
BOOL WINAPI SetupDiSetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4558
BOOL WINAPI SetupDiClassGuidsFromNameExA(LPCSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, LPCSTR MachineName, PVOID Reserved)
Definition: devinst.c:882
DWORD GetErrorCodeFromCrCode(const IN CONFIGRET cr)
Definition: devinst.c:94
BOOL WINAPI SetupDiGetClassDescriptionExW(const GUID *ClassGuid, PWSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved)
Definition: devinst.c:2143
BOOL WINAPI SetupDiEnumDeviceInfo(HDEVINFO devinfo, DWORD index, PSP_DEVINFO_DATA info)
Definition: devinst.c:1787
BOOL WINAPI SetupDiInstallClassA(HWND hwndParent, PCSTR InfFileName, DWORD Flags, HSPFILEQ FileQueue)
Definition: devinst.c:3470
HKEY WINAPI SetupDiCreateDevRegKeyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, HINF InfHandle, PCWSTR InfSectionName)
Definition: devinst.c:1396
BOOL WINAPI SetupDiGetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4451
BOOL WINAPI SetupDiCreateDeviceInfoA(HDEVINFO DeviceInfoSet, PCSTR DeviceName, CONST GUID *ClassGuid, PCSTR DeviceDescription, HWND hwndParent, DWORD CreationFlags, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:1528
static const WCHAR DotServices[]
Definition: devinst.c:31
BOOL WINAPI SetupDiCallClassInstaller(DI_FUNCTION InstallFunction, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4024
BOOL WINAPI SetupDiRegisterDeviceInfo(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Flags, PSP_DETSIG_CMPPROC CompareProc, PVOID CompareContext, PSP_DEVINFO_DATA DupDeviceInfoData)
Definition: devinst.c:1711
BOOL(WINAPI * DEFAULT_CLASS_INSTALL_PROC)(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:49
BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved)
Definition: devinst.c:2728
HKEY SETUPDI_CreateDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, UUID *ClassGuid, REGSAM samDesired)
Definition: devinst.c:5687
HKEY SETUPDI_OpenDevKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
Definition: devinst.c:5841
BOOL WINAPI SetupDiCreateDeviceInfoW(HDEVINFO DeviceInfoSet, PCWSTR DeviceName, CONST GUID *ClassGuid, PCWSTR DeviceDescription, HWND hwndParent, DWORD CreationFlags, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:1570
BOOL WINAPI SetupDiGetDeviceInfoListDetailW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_LIST_DETAIL_DATA_W DevInfoData)
Definition: devinst.c:2464
BOOL WINAPI SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, CONST GUID *InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:2780
BOOL WINAPI SetupDiSelectDevice(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: devinst.c:5197
BOOL WINAPI SetupDiClassNameFromGuidA(const GUID *ClassGuid, PSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize)
Definition: devinst.c:1053
BOOL WINAPI SetupDiGetClassDescriptionA(const GUID *ClassGuid, PSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize)
Definition: devinst.c:2058
static const WCHAR REGSTR_DRIVER_VERSION[]
Definition: devinst.c:39
BOOL WINAPI SetupDiSetDeviceRegistryPropertyA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, const BYTE *PropertyBuffer, DWORD PropertyBufferSize)
Definition: devinst.c:3434
BOOL WINAPI SetupDiGetActualSectionToInstallW(HINF InfHandle, PCWSTR InfSectionName, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PWSTR *Extension)
Definition: devinst.c:1980
BOOL WINAPI SetupDiInstallClassW(HWND hwndParent, PCWSTR InfFileName, DWORD Flags, HSPFILEQ FileQueue)
Definition: devinst.c:3605
BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
Definition: devinst.c:3224
BOOL WINAPI SetupDiClassGuidsFromNameExW(LPCWSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, LPCWSTR MachineName, PVOID Reserved)
Definition: devinst.c:930
static BOOL DestroyDeviceInfoSet(struct DeviceInfoSet *list)
Definition: devinst.c:608
static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
Definition: devinst.c:81
BOOL WINAPI SetupDiGetClassDescriptionW(const GUID *ClassGuid, PWSTR ClassDescription, DWORD ClassDescriptionSize, PDWORD RequiredSize)
Definition: devinst.c:2072
static const WCHAR REGSTR_UI_NUMBER_DESC_FORMAT[]
Definition: devinst.c:41
BOOL WINAPI SetupDiCreateDeviceInterfaceW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, PCWSTR ReferenceString, DWORD CreationFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:2534
HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyA(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved, REGSAM samDesired, HINF InfHandle, PCSTR InfSectionName)
Definition: devinst.c:2579
HDEVINFO WINAPI SetupDiGetClassDevsW(CONST GUID *class, LPCWSTR enumstr, HWND parent, DWORD flags)
Definition: devinst.c:2292
static const WCHAR REGSTR_DRIVER_DATE[]
Definition: devinst.c:37
static BOOL DestroyClassInstallParams(struct ClassInstallParams *installParams)
Definition: devinst.c:573
BOOL WINAPI SetupDiDeleteDevRegKey(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType)
Definition: devinst.c:6033
static BOOL GetSectionCallback(IN LPCWSTR SectionName, IN PVOID Context)
Definition: devinst.c:365
BOOL WINAPI IntSetupDiSetDeviceRegistryPropertyAW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, const BYTE *PropertyBuffer, DWORD PropertyBufferSize, BOOL isAnsi)
Definition: devinst.c:3358
BOOL WINAPI SetupDiClassGuidsFromNameA(LPCSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize)
Definition: devinst.c:854
static const WCHAR BackSlash[]
Definition: devinst.c:27
HDEVINFO WINAPI SetupDiGetClassDevsExW(CONST GUID *class, PCWSTR enumstr, HWND parent, DWORD flags, HDEVINFO deviceset, PCWSTR machine, PVOID reserved)
Definition: devinst.c:2305
static BOOL SETUPDI_DeleteDevKey(HKEY RootKey, struct DeviceInfo *devInfo)
Definition: devinst.c:6018
BOOL WINAPI SetupDiGetActualSectionToInstallA(HINF InfHandle, PCSTR InfSectionName, PSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PSTR *Extension)
Definition: devinst.c:1964
HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, DWORD Reserved, REGSAM samDesired, HINF InfHandle, PCWSTR InfSectionName)
Definition: devinst.c:2613
BOOL WINAPI SetupDiDeleteDeviceInfo(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4712
BOOL WINAPI SetupDiChangeState(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5071
BOOL WINAPI SetupDiInstallDevice(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5365
BOOL WINAPI SetupDiOpenDeviceInterfaceW(HDEVINFO DeviceInfoSet, PCWSTR DevicePath, DWORD OpenFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:3761
HDEVINFO WINAPI SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid, HWND hwndParent, PCSTR MachineName, PVOID Reserved)
Definition: devinst.c:1215
HKEY SETUPDI_OpenDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
Definition: devinst.c:5857
#define CLASS_INSTALLER
BOOL WINAPI SetupDiOpenDeviceInfoW(IN HDEVINFO DeviceInfoSet, IN PCWSTR DeviceInstanceId, IN HWND hwndParent OPTIONAL, IN DWORD OpenFlags, OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: devinst.c:4774
BOOL WINAPI SetupDiGetDeviceInstanceIdW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PWSTR DeviceInstanceId, DWORD DeviceInstanceIdSize, PDWORD RequiredSize)
Definition: devinst.c:1907
DWORD(CALLBACK * COINSTALLER_PROC)(IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN OUT PCOINSTALLER_CONTEXT_DATA Context)
Definition: devinst.c:53
static BOOL ResetDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5020
BOOL WINAPI SetupDiSetDeviceInstallParamsA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
Definition: devinst.c:4598
HKEY WINAPI SetupDiOpenDevRegKey(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, REGSAM samDesired)
Definition: devinst.c:5934
static BOOL IsDeviceInfoInDeviceInfoSet(struct DeviceInfoSet *deviceInfoSet, struct DeviceInfo *deviceInfo)
Definition: devinst.c:4690
static BOOL WINAPI IntSetupDiRegisterDeviceInfo(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4014
HKEY WINAPI SetupDiCreateDevRegKeyA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, HINF InfHandle, PCSTR InfSectionName)
Definition: devinst.c:1353
BOOL WINAPI SetupDiClassNameFromGuidW(const GUID *ClassGuid, PWSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize)
Definition: devinst.c:1067
static const WCHAR REGSTR_SECURITY[]
Definition: devinst.c:40
BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, const BYTE *PropertyBuffer, DWORD PropertyBufferSize)
Definition: devinst.c:3452
HKEY SETUP_CreateClassKey(HINF hInf)
Definition: devinst.c:3518
BOOL WINAPI SetupDiClassGuidsFromNameW(LPCWSTR ClassName, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize)
Definition: devinst.c:868
BOOL WINAPI SetupDiClassNameFromGuidExW(const GUID *ClassGuid, PWSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize, PCWSTR MachineName, PVOID Reserved)
Definition: devinst.c:1114
static const WCHAR VersionFormat[]
Definition: devinst.c:35
DWORD(CALLBACK * CLASS_INSTALL_PROC)(IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: devinst.c:44
BOOL WINAPI SetupDiBuildClassInfoListExA(DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, LPCSTR MachineName, PVOID Reserved)
Definition: devinst.c:675
static DWORD SETUPAPI_GetCurrentHwProfile(IN HDEVINFO DeviceInfoSet)
Definition: devinst.c:4973
BOOL WINAPI SetupDiSetSelectedDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4941
BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:2917
static const WCHAR REGSTR_DRIVER_DATE_DATA[]
Definition: devinst.c:38
BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:3011
static struct PropertyMapEntry PropertyMap[]
Definition: devinst.c:3098
BOOL WINAPI SetupDiClassNameFromGuidExA(const GUID *ClassGuid, PSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved)
Definition: devinst.c:1081
BOOL WINAPI SetupDiGetSelectedDevice(IN HDEVINFO DeviceInfoSet, OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4903
static const WCHAR InfDirectory[]
Definition: devinst.c:32
HDEVINFO WINAPI SetupDiGetClassDevsA(CONST GUID *class, LPCSTR enumstr, HWND parent, DWORD flags)
Definition: devinst.c:2236
HKEY SETUPDI_CreateDevKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
Definition: devinst.c:5671
BOOL WINAPI SetupDiGetDeviceInstallParamsA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
Definition: devinst.c:4378
static const WCHAR DotHW[]
Definition: devinst.c:30
HKEY WINAPI SetupDiOpenClassRegKey(const GUID *ClassGuid, REGSAM samDesired)
Definition: devinst.c:3618
static BOOL StopDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5044
BOOL WINAPI SetupDiGetDeviceInfoListDetailA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_LIST_DETAIL_DATA_A DevInfoData)
Definition: devinst.c:2423
BOOL WINAPI SetupDiGetActualSectionToInstallExW(IN HINF InfHandle, IN PCWSTR InfSectionName, IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL, OUT PWSTR InfSectionWithExt OPTIONAL, IN DWORD InfSectionWithExtSize, OUT PDWORD RequiredSize OPTIONAL, OUT PWSTR *Extension OPTIONAL, IN PVOID Reserved)
Definition: devinst.c:415
static BOOL CheckDeviceInstallParameters(IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4499
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2893
BOOL WINAPI SetupDiGetDeviceInstanceIdA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSTR DeviceInstanceId, DWORD DeviceInstanceIdSize, PDWORD RequiredSize)
Definition: devinst.c:1838
HKEY WINAPI SetupDiOpenClassRegKeyExW(const GUID *ClassGuid, REGSAM samDesired, DWORD Flags, PCWSTR MachineName, PVOID Reserved)
Definition: devinst.c:3662
HKEY WINAPI SetupDiOpenClassRegKeyExA(const GUID *ClassGuid, REGSAM samDesired, DWORD Flags, PCSTR MachineName, PVOID Reserved)
Definition: devinst.c:3630
HDEVINFO WINAPI SetupDiCreateDeviceInfoList(const GUID *ClassGuid, HWND hwndParent)
Definition: devinst.c:1205
BOOL WINAPI SetupDiGetDeviceInfoListClass(IN HDEVINFO DeviceInfoSet, OUT LPGUID ClassGuid)
Definition: devinst.c:4421
BOOL CreateDeviceInfo(IN struct DeviceInfoSet *list, IN LPCWSTR InstancePath, IN LPCGUID pClassGuid, OUT struct DeviceInfo **pDeviceInfo)
Definition: devinst.c:528
static const WCHAR DotCoInstallers[]
Definition: devinst.c:29
#define DEVICE_COINSTALLER
BOOL WINAPI SetupDiInstallDriverFiles(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: driver.c:2093
struct InfFileDetails * CreateInfFileDetails(IN LPCWSTR FullInfFileName)
Definition: driver.c:55
BOOL DestroyDriverInfoElement(struct DriverInfoElement *driverInfo)
Definition: driver.c:94
BOOL WINAPI SetupDiSelectBestCompatDrv(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: driver.c:2057
VOID DereferenceInfFile(struct InfFileDetails *infFile)
Definition: driver.c:45
BOOL WINAPI SetupInstallFromInfSectionW(HWND owner, HINF hinf, PCWSTR section, UINT flags, HKEY key_root, PCWSTR src_root, UINT copy_flags, PSP_FILE_CALLBACK_W callback, PVOID context, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data)
Definition: install.c:1327
BOOL WINAPI SetupCopyOEMInfW(IN PCWSTR SourceInfFileName, IN PCWSTR OEMSourceMediaLocation, IN DWORD OEMSourceMediaType, IN DWORD CopyStyle, OUT PWSTR DestinationInfFileName OPTIONAL, IN DWORD DestinationInfFileNameSize, OUT PDWORD RequiredSize OPTIONAL, OUT PWSTR *DestinationInfFileNameComponent OPTIONAL)
Definition: install.c:2305
BOOL WINAPI SetupInstallServicesFromInfSectionExW(HINF hinf, PCWSTR sectionname, DWORD flags, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PVOID reserved1, PVOID reserved2)
Definition: install.c:2078
BOOL DestroyDeviceInterface(struct DeviceInterface *deviceInterface)
Definition: interface.c:61
static const WCHAR SymbolicLink[]
Definition: interface.c:31
BOOL WINAPI SetupDiInstallDeviceInterfaces(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: interface.c:414
LONG SETUP_CreateInterfaceList(struct DeviceInfoSet *list, PCWSTR MachineName, CONST GUID *InterfaceGuid, PCWSTR DeviceInstanceW, BOOL OnlyPresentInterfaces)
Definition: interface.c:68
LPWSTR WINAPI pSetupMultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
Definition: misc.c:281
DWORD FreeFunctionPointer(IN HMODULE ModulePointer, IN PVOID FunctionPointer)
Definition: misc.c:105
LPVOID WINAPI MyMalloc(DWORD dwSize)
Definition: misc.c:147
VOID WINAPI MyFree(LPVOID lpMem)
Definition: misc.c:128
LPWSTR WINAPI pSetupDuplicateString(LPCWSTR lpSrc)
Definition: misc.c:198
DWORD WINAPI pSetupStringFromGuid(LPGUID lpGUID, PWSTR pString, DWORD dwStringLen)
Definition: misc.c:1775
DWORD GetFunctionPointer(IN PWSTR InstallerName, OUT HMODULE *ModulePointer, OUT PVOID *FunctionPointer)
Definition: misc.c:44
BOOL EnumerateSectionsStartingWith(IN HINF hInf, IN LPCWSTR pStr, IN FIND_CALLBACK Callback, IN PVOID Context)
Definition: parser.c:2387
BOOL WINAPI SetupDiGetINFClassW(IN PCWSTR InfName, OUT LPGUID ClassGuid, OUT PWSTR ClassName, IN DWORD ClassNameSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2316
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1756
UINT WINAPI SetupDefaultQueueCallbackW(PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:1729
void WINAPI SetupTermDefaultQueueCallback(PVOID context)
Definition: queue.c:1656
PVOID WINAPI SetupInitDefaultQueueCallback(HWND owner)
Definition: queue.c:1629
BOOL WINAPI SetupDiUnremoveDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: stubs.c:96
BOOL WINAPI SetupDiRemoveDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: stubs.c:82
r parent
Definition: btrfs.c:3010
r reserved
Definition: btrfs.c:3006
#define __FUNCTION__
Definition: types.h:116
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
ULONG MajorVersion
Definition: ros_glue.cpp:4
ULONG MinorVersion
Definition: ros_glue.cpp:5
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
FxAutoRegKey hKey
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ULONG_MAX
Definition: limits.h:44
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
#define REG_SZ
Definition: layer.c:22
if(dx< 0)
Definition: linetemp.h:194
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static PVOID ptr
Definition: dispmode.c:27
static UINT UINT last
Definition: font.c:45
static const WCHAR machineW[]
Definition: profile.c:105
static const char machine[]
Definition: profile.c:104
static WCHAR guidStr[]
Definition: asn.c:531
unsigned int UINT
Definition: ndis.h:50
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
#define PROCESSOR_ARCHITECTURE_IA64
Definition: ketypes.h:111
#define PROCESSOR_ARCHITECTURE_ALPHA
Definition: ketypes.h:107
#define PROCESSOR_ARCHITECTURE_UNKNOWN
Definition: ketypes.h:115
#define PROCESSOR_ARCHITECTURE_MIPS
Definition: ketypes.h:106
#define PROCESSOR_ARCHITECTURE_PPC
Definition: ketypes.h:108
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
#define PROCESSOR_ARCHITECTURE_INTEL
Definition: ketypes.h:105
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:238
#define VER_PLATFORM_WIN32_WINDOWS
Definition: rtltypes.h:237
u32_t magic(void)
#define BOOL
Definition: nt_native.h:43
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define KEY_WRITE
Definition: nt_native.h:1031
#define READ_CONTROL
Definition: nt_native.h:58
#define DWORD
Definition: nt_native.h:44
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
#define CONST
Definition: pedump.c:81
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define strcmpiW(s1, s2)
Definition: unicode.h:39
#define strlenW(s)
Definition: unicode.h:28
#define strrchrW(s, c)
Definition: unicode.h:35
#define strcatW(d, s)
Definition: unicode.h:30
#define strtoulW(s1, s2, b)
Definition: unicode.h:41
#define snprintfW
Definition: unicode.h:60
#define sprintfW
Definition: unicode.h:58
#define strcpyW(d, s)
Definition: unicode.h:29
static const WCHAR HKLM[]
Definition: reginf.c:58
#define REGSTR_VAL_LOWERFILTERS
Definition: regstr.h:424
#define REGSTR_VAL_DRVDESC
Definition: regstr.h:428
#define REGSTR_KEY_CURRENT
Definition: regstr.h:493
#define REGSTR_VAL_INFPATH
Definition: regstr.h:439
#define REGSTR_VAL_INSTALLER_32
Definition: regstr.h:487
#define REGSTR_VAL_UI_NUMBER
Definition: regstr.h:426
#define REGSTR_VAL_CAPABILITIES
Definition: regstr.h:772
#define REGSTR_VAL_NOINSTALLCLASS
Definition: regstr.h:239
#define REGSTR_VAL_DEVDESC
Definition: regstr.h:292
#define REGSTR_VAL_CLASSGUID
Definition: regstr.h:422
#define REGSTR_VAL_COMPATIBLEIDS
Definition: regstr.h:296
#define REGSTR_PATH_DEVICE_CLASSES
Definition: regstr.h:481
#define CSCONFIGFLAG_DISABLED
Definition: regstr.h:401
#define REGSTR_VAL_INFSECTIONEXT
Definition: regstr.h:441
#define REGSTR_VAL_CURRENTCONFIG
Definition: regstr.h:466
#define CONFIGFLAG_FAILEDINSTALL
Definition: regstr.h:396
#define REGSTR_VAL_DRIVER
Definition: regstr.h:385
#define REGSTR_VAL_FRIENDLYNAME
Definition: regstr.h:465
#define REGSTR_VAL_SERVICE
Definition: regstr.h:425
#define REGSTR_VAL_HARDWAREID
Definition: regstr.h:485
#define REGSTR_VAL_NODISPLAYCLASS
Definition: regstr.h:240
#define REGSTR_VAL_COINSTALLERS_32
Definition: regstr.h:484
#define REGSTR_PATH_SYSTEMENUM
Definition: regstr.h:483
#define REGSTR_VAL_MATCHINGDEVID
Definition: regstr.h:442
#define REGSTR_VAL_CSCONFIGFLAGS
Definition: regstr.h:389
#define REGSTR_VAL_NOUSECLASS
Definition: regstr.h:238
#define REGSTR_VAL_LOCATION_INFORMATION
Definition: regstr.h:423
#define REGSTR_PATH_CLASS_NT
Definition: regstr.h:479
#define REGSTR_PATH_HWPROFILES
Definition: regstr.h:482
#define REGSTR_VAL_CONFIGFLAGS
Definition: regstr.h:388
#define REGSTR_PATH_IDCONFIGDB
Definition: regstr.h:41
#define REGSTR_VAL_UPPERFILTERS
Definition: regstr.h:427
#define REGSTR_VAL_INFSECTION
Definition: regstr.h:440
#define REGSTR_VAL_CLASS
Definition: regstr.h:291
#define REGSTR_VAL_PROVIDER_NAME
Definition: regstr.h:540
#define REGSTR_VAL_MFG
Definition: regstr.h:306
#define REGSTR_PATH_CODEVICEINSTALLERS
Definition: regstr.h:480
#define CONFIGFLAG_DISABLED
Definition: regstr.h:390
#define list
Definition: rosglue.h:35
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI UuidToStringW(UUID *Uuid, RPC_WSTR *StringUuid)
Definition: rpcrt4_main.c:540
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:175
RPC_STATUS WINAPI UuidFromStringW(RPC_WSTR s, UUID *uuid)
Definition: rpcrt4_main.c:614
#define REG_DWORD
Definition: sdbapi.c:596
#define errno
Definition: errno.h:18
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static PMEMKEY RootKey
Definition: registry.c:55
#define SPINST_BITREG
Definition: setupapi.h:593
#define DI_FLAGSEX_CI_FAILED
Definition: setupapi.h:79
#define DI_FLAGSEX_NO_DRVREG_MODIFY
Definition: setupapi.h:91
#define SPINST_UNREGSVR
Definition: setupapi.h:595
#define ERROR_DI_POSTPROCESSING_REQUIRED
Definition: setupapi.h:334
#define DIF_SELECTDEVICE
Definition: setupapi.h:120
#define ERROR_NO_ASSOCIATED_CLASS
Definition: setupapi.h:296
#define DI_NEEDRESTART
Definition: setupapi.h:53
#define SPDRP_MAXIMUM_PROPERTY
Definition: setupapi.h:542
#define SP_MAX_MACHINENAME_LENGTH
Definition: setupapi.h:27
#define ERROR_INVALID_DEVINST_NAME
Definition: setupapi.h:301
#define ERROR_INVALID_MACHINENAME
Definition: setupapi.h:328
#define DI_DIDCOMPAT
Definition: setupapi.h:50
#define SP_COPY_NOOVERWRITE
Definition: setupapi.h:480
#define ERROR_DEVINST_ALREADY_EXISTS
Definition: setupapi.h:303
_In_ DWORD _Out_ PDWORD _In_opt_ PCSTR MachineName
Definition: setupapi.h:1293
#define DI_NODI_DEFAULTACTION
Definition: setupapi.h:67
#define SetupInstallFromInfSection
Definition: setupapi.h:2645
#define ERROR_INVALID_CLASS
Definition: setupapi.h:302
#define DIBCI_NODISPLAYCLASS
Definition: setupapi.h:109
#define DIF_NEWDEVICEWIZARD_PRESELECT
Definition: setupapi.h:145
#define DI_NOVCP
Definition: setupapi.h:49
_In_opt_ PSP_DEVINFO_DATA _In_ DWORD ClassInstallParamsSize
Definition: setupapi.h:1530
#define SPINST_PROFILEITEMS
Definition: setupapi.h:596
_In_ DWORD _Out_opt_ PDWORD PropertyRegDataType
Definition: setupapi.h:1551
#define DIF_REGISTERDEVICE
Definition: setupapi.h:144
#define DI_CLASSINSTALLPARAMS
Definition: setupapi.h:66
#define SPDRP_DEVICEDESC
Definition: setupapi.h:507
#define DIF_REMOVE
Definition: setupapi.h:124
#define ERROR_INVALID_REG_PROPERTY
Definition: setupapi.h:305
#define DIF_INSTALLDEVICEFILES
Definition: setupapi.h:140
#define SPINST_INI2REG
Definition: setupapi.h:591
_In_ DWORD ClassGuidListSize
Definition: setupapi.h:1281
#define DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
Definition: setupapi.h:159
#define LINE_LEN
Definition: setupapi.h:20
#define ERROR_NO_SUCH_DEVINST
Definition: setupapi.h:307
#define ERROR_NO_DEVICE_SELECTED
Definition: setupapi.h:313
#define DI_QUIETINSTALL
Definition: setupapi.h:68
#define SPINST_REGSVR
Definition: setupapi.h:594
#define DI_RESOURCEPAGE_ADDED
Definition: setupapi.h:59
#define SPOST_NONE
Definition: setupapi.h:609
#define DICS_DISABLE
Definition: setupapi.h:114
#define DIOCR_INTERFACE
Definition: setupapi.h:177
SP_ALTPLATFORM_INFO_V1 SP_ALTPLATFORM_INFO
Definition: setupapi.h:730
#define DICS_PROPCHANGE
Definition: setupapi.h:116
#define DIF_DETECT
Definition: setupapi.h:134
#define DIGCF_DEVICEINTERFACE
Definition: setupapi.h:174
#define DI_FLAGSEX_DIDCOMPATINFO
Definition: setupapi.h:81
#define DI_FLAGSEX_SETFAILEDINSTALL
Definition: setupapi.h:83
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W SP_DEVICE_INTERFACE_DETAIL_DATA_W
#define DIREG_DEV
Definition: setupapi.h:181
#define DI_ENUMSINGLEINF
Definition: setupapi.h:62
#define SPINST_INIFILES
Definition: setupapi.h:589
#define DIF_NEWDEVICEWIZARD_SELECT
Definition: setupapi.h:146
#define SPINST_REGISTRY
Definition: setupapi.h:590
#define ERROR_SECTION_NOT_FOUND
Definition: setupapi.h:293
#define DIREG_DRV
Definition: setupapi.h:182
#define ERROR_NO_DRIVER_SELECTED
Definition: setupapi.h:299
#define DIF_REGISTER_COINSTALLERS
Definition: setupapi.h:153
#define DI_DRIVERPAGE_ADDED
Definition: setupapi.h:71
#define DIF_INSTALLINTERFACES
Definition: setupapi.h:151
#define DIOD_INHERIT_CLASSDRVS
Definition: setupapi.h:179
#define DICS_ENABLE
Definition: setupapi.h:112
#define DIGCF_ALLCLASSES
Definition: setupapi.h:172
struct _SP_DEVINSTALL_PARAMS_W SP_DEVINSTALL_PARAMS_W
#define DICS_FLAG_CONFIGSPECIFIC
Definition: setupapi.h:115
#define DIGCF_PROFILE
Definition: setupapi.h:173
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1528
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:310
#define DIOD_CANCEL_REMOVE
Definition: setupapi.h:180
#define ERROR_CLASS_MISMATCH
Definition: setupapi.h:297
#define DIF_NEWDEVICEWIZARD_PREANALYZE
Definition: setupapi.h:147
#define DI_FLAGSEX_DIDINFOLIST
Definition: setupapi.h:80
#define DIF_UNREMOVE
Definition: setupapi.h:141
UINT DI_FUNCTION
Definition: setupapi.h:672
#define DICD_GENERATE_ID
Definition: setupapi.h:110
#define DIGCF_PRESENT
Definition: setupapi.h:171
#define DI_NEEDREBOOT
Definition: setupapi.h:54
#define DI_NOFILECOPY
Definition: setupapi.h:69
_In_ DWORD _Out_opt_ PDWORD _In_ DWORD PropertyBufferSize
Definition: setupapi.h:1553
#define SPRDI_FIND_DUPS
Definition: setupapi.h:623
#define DIOCR_INSTALLER
Definition: setupapi.h:176
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W * PSP_DEVICE_INTERFACE_DETAIL_DATA_W
#define SPINST_FILES
Definition: setupapi.h:592
#define DIF_INSTALLDEVICE
Definition: setupapi.h:121
#define DIBCI_NOINSTALLCLASS
Definition: setupapi.h:108
#define SPINT_ACTIVE
Definition: setupapi.h:582
#define DIF_ALLOW_INSTALL
Definition: setupapi.h:143
#define DIF_DESTROYPRIVATEDATA
Definition: setupapi.h:131
#define DI_PROPERTIES_CHANGE
Definition: setupapi.h:60
#define DI_FLAGSEX_ALLOWEXCLUDEDDRVS
Definition: setupapi.h:87
#define DIF_SELECTBESTCOMPATDRV
Definition: setupapi.h:142
#define SPDRP_CONFIGFLAGS
Definition: setupapi.h:517
#define DICS_FLAG_GLOBAL
Definition: setupapi.h:113
#define DIF_POWERMESSAGEWAKE
Definition: setupapi.h:158
DWORD(CALLBACK * PSP_DETSIG_CMPPROC)(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINFO_DATA, PVOID)
Definition: setupapi.h:1057
#define DIF_PROPERTYCHANGE
Definition: setupapi.h:137
#define DIF_ADDPROPERTYPAGE_ADVANCED
Definition: setupapi.h:154
#define SPDRP_PHYSICAL_DEVICE_OBJECT_NAME
Definition: setupapi.h:521
#define DICD_INHERIT_CLASSDRVS
Definition: setupapi.h:111
#define DIF_NEWDEVICEWIZARD_POSTANALYZE
Definition: setupapi.h:148
#define DI_DIDCLASS
Definition: setupapi.h:51
#define DIF_TROUBLESHOOTER
Definition: setupapi.h:157
#define SP_COPY_NEWER
Definition: setupapi.h:478
#define DIREG_BOTH
Definition: setupapi.h:183
#define DI_DONOTCALLCONFIGMG
Definition: setupapi.h:63
#define DIF_NEWDEVICEWIZARD_FINISHINSTALL
Definition: setupapi.h:149
#define SETUP_DEVICE_INFO_SET_MAGIC
OSVERSIONINFOEXW OsVersionInfo
Definition: setupcab.c:33
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PSP_PROPCHANGE_PARAMS PropChangeParams
PSP_ADDPROPERTYPAGE_DATA AddPropertyPageData
LIST_ENTRY ListEntry
Definition: devinst.c:61
HMODULE Module
Definition: devinst.c:63
BOOL DoPostProcessing
Definition: devinst.c:65
COINSTALLER_PROC Function
Definition: devinst.c:64
PVOID PrivateData
Definition: devinst.c:66
SP_DEVINSTALL_PARAMS_W InstallParams
LIST_ENTRY ListHead
WCHAR szData[ANYSIZE_ARRAY]
PCWSTR DeviceDescription
LIST_ENTRY InterfaceListHead
struct ClassInstallParams ClassInstallParams
WCHAR Data[ANYSIZE_ARRAY]
DEVINST dnDevInst
HMODULE hmodDevicePropPageProvider
SP_DEVINSTALL_PARAMS_W InstallParams
LIST_ENTRY ListEntry
LIST_ENTRY DriverListHead
struct DeviceInfoSet * set
struct DeviceInfo * DeviceInfo
WCHAR SymbolicLink[ANYSIZE_ARRAY]
LIST_ENTRY ListEntry
struct InfFileDetails * InfFileDetails
SP_DRVINFO_DETAIL_DATA_W Details
SP_DRVINFO_DATA_V2_W Info
ULARGE_INTEGER DriverDate
WCHAR BestSection[LINE_LEN+1]
Definition: devinst.c:75
PSP_ALTPLATFORM_INFO PlatformInfo
Definition: devinst.c:71
LPCWSTR nameW
Definition: devinst.c:3095
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG dwMajorVersion
Definition: rtltypes.h:270
ULONG dwMinorVersion
Definition: rtltypes.h:271
ULONG dwPlatformId
Definition: rtltypes.h:273
UCHAR wProductType
Definition: rtltypes.h:278
USHORT wSuiteMask
Definition: rtltypes.h:277
CHAR DevicePath[ANYSIZE_ARRAY]
Definition: setupapi.h:851
WCHAR DevicePath[ANYSIZE_ARRAY]
Definition: setupapi.h:855
ULONG_PTR Reserved
Definition: setupapi.h:838
CHAR RemoteMachineName[SP_MAX_MACHINENAME_LENGTH]
Definition: setupapi.h:867
WCHAR RemoteMachineName[SP_MAX_MACHINENAME_LENGTH]
Definition: setupapi.h:873
ULONG_PTR ClassInstallReserved
Definition: setupapi.h:898
WCHAR DriverPath[MAX_PATH]
Definition: setupapi.h:900
WCHAR ProviderName[LINE_LEN]
Definition: setupapi.h:1018
WCHAR MfgName[LINE_LEN]
Definition: setupapi.h:1017
DWORDLONG DriverVersion
Definition: setupapi.h:1020
WCHAR Description[LINE_LEN]
Definition: setupapi.h:1016
WCHAR SectionName[LINE_LEN]
Definition: setupapi.h:1076
WCHAR InfFileName[MAX_PATH]
Definition: setupapi.h:1077
WORD wYear
Definition: winbase.h:905
WORD wMonth
Definition: winbase.h:906
WORD wDay
Definition: winbase.h:908
WORD wProcessorArchitecture
Definition: winbase.h:1169
Definition: dsound.c:943
Definition: copy.c:22
uint16_t * PWSTR
Definition: typedefs.h:56
#define OPTIONAL
Definition: typedefs.h:41
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
ULONG LowPart
Definition: typedefs.h:106
int ret
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ CONST GUID _In_opt_ PCUNICODE_STRING ReferenceString
Definition: wdfdevice.h:3630
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID PropertyBuffer
Definition: wdfdevice.h:4437
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:432
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CopyMemory
Definition: winbase.h:1710
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
BOOL * LPBOOL
Definition: windef.h:162
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
#define NOERROR
Definition: winerror.h:2354
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define ERROR_SUCCESS_REBOOT_REQUIRED
Definition: winerror.h:1215
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define ERROR_INVALID_COMPUTERNAME
Definition: winerror.h:713
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
ACCESS_MASK REGSAM
Definition: winreg.h:69
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ CONST GUID * InterfaceClassGuid
Definition: iofuncs.h:1136
_In_ PSTRING FullName
Definition: rtlfuncs.h:1648
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193