ReactOS 0.4.16-dev-2613-g9533ad7
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, hRefKey, hDevParamKey;
2623 DWORD Length, RefLength, Index;
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 /* Enumerate all characters in symbolic link */
2685 Index = 0;
2686 while (SymbolicLink[Index])
2687 {
2688 /* Check for a start position of reference string */
2689 if (SymbolicLink[Index] == L'}' && SymbolicLink[Index + 1] == L'\\')
2690 {
2691 /* Found it */
2692 break;
2693 }
2694 /* Replace all '\' backslashes by '#' pounds in symbolic link */
2695 if (SymbolicLink[Index] == L'\\')
2696 {
2697 SymbolicLink[Index] = L'#';
2698 }
2699 Index++;
2700 }
2701
2702 /* Create reference string */
2703 RefLength = Length - Index * sizeof(WCHAR);
2704 ReferenceString = HeapAlloc(GetProcessHeap(), 0, RefLength);
2705 if (!ReferenceString)
2706 {
2709 return INVALID_HANDLE_VALUE;
2710 }
2711
2712 ReferenceString[0] = L'#';
2713 wcscpy(ReferenceString + 1, &SymbolicLink[Index + 2]); /* Skip first '\' backslash */
2714
2715 /* Null-terminate symbolic link at the beginning of the reference part,
2716 * as we don't need a ref part in key name. */
2718
2719 /* Open device instance key */
2720 rc = RegOpenKeyExW(hKey, SymbolicLink, 0, samDesired, &hDevKey);
2723 if (rc != ERROR_SUCCESS)
2724 {
2726 SetLastError(rc);
2727 return INVALID_HANDLE_VALUE;
2728 }
2729
2730 /* Open reference key */
2731 rc = RegOpenKeyExW(hDevKey, ReferenceString, 0, samDesired, &hRefKey);
2733 RegCloseKey(hDevKey);
2734 if (rc != ERROR_SUCCESS)
2735 {
2736 SetLastError(rc);
2737 return INVALID_HANDLE_VALUE;
2738 }
2739
2740 /* Create/open "Device Parameters" subkey */
2741 rc = RegCreateKeyExW(hRefKey, L"Device Parameters", 0, NULL, 0, samDesired, NULL, &hDevParamKey, NULL);
2742 RegCloseKey(hRefKey);
2743 if (rc == ERROR_SUCCESS)
2744 {
2745 if (InfHandle && InfSectionName)
2746 {
2747 if (!SetupInstallFromInfSection(NULL /*FIXME */,
2748 InfHandle,
2749 InfSectionName,
2751 hDevParamKey,
2752 NULL,
2753 0,
2754 set->SelectedDevice->InstallParams.InstallMsgHandler,
2755 set->SelectedDevice->InstallParams.InstallMsgHandlerContext,
2757 NULL))
2758 {
2759 RegCloseKey(hDevParamKey);
2760 return INVALID_HANDLE_VALUE;
2761 }
2762 }
2763 }
2764
2765 SetLastError(rc);
2766 return hDevParamKey;
2767}
2768
2769/***********************************************************************
2770 * SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@)
2771 */
2774 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
2776{
2777 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2778 BOOL ret = FALSE;
2779
2780 TRACE("%s(%p %p %d)\n", __FUNCTION__, DeviceInfoSet, DeviceInterfaceData, Reserved);
2781
2784 {
2786 return FALSE;
2787 }
2788 if (!DeviceInterfaceData ||
2789 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
2790 !DeviceInterfaceData->Reserved)
2791 {
2793 return FALSE;
2794 }
2795
2796 FIXME("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved);
2798 return ret;
2799}
2800
2801/***********************************************************************
2802 * SetupDiEnumDeviceInterfaces (SETUPAPI.@)
2803 *
2804 * PARAMS
2805 * DeviceInfoSet [I] Set of devices from which to enumerate
2806 * interfaces
2807 * DeviceInfoData [I] (Optional) If specified, a specific device
2808 * instance from which to enumerate interfaces.
2809 * If it isn't specified, all interfaces for all
2810 * devices in the set are enumerated.
2811 * InterfaceClassGuid [I] The interface class to enumerate.
2812 * MemberIndex [I] An index of the interface instance to enumerate.
2813 * A caller should start with MemberIndex set to 0,
2814 * and continue until the function fails with
2815 * ERROR_NO_MORE_ITEMS.
2816 * DeviceInterfaceData [I/O] Returns an enumerated interface. Its cbSize
2817 * member must be set to
2818 * sizeof(SP_DEVICE_INTERFACE_DATA).
2819 *
2820 * RETURNS
2821 * Success: non-zero value.
2822 * Failure: FALSE. Call GetLastError() for more info.
2823 */
2828 DWORD MemberIndex,
2829 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
2830{
2831 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2832 BOOL ret = FALSE;
2833
2834 TRACE("%s(%p, %p, %s, %d, %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
2835 debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
2836
2839 {
2841 return FALSE;
2842 }
2845 {
2847 return FALSE;
2848 }
2849 if (!DeviceInterfaceData ||
2850 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
2851 {
2853 return FALSE;
2854 }
2855 if (DeviceInfoData)
2856 {
2857 struct DeviceInfo *devInfo =
2859 BOOL found = FALSE;
2860 PLIST_ENTRY InterfaceListEntry = devInfo->InterfaceListHead.Flink;
2861 while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
2862 {
2863 struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
2865 {
2866 InterfaceListEntry = InterfaceListEntry->Flink;
2867 continue;
2868 }
2869 if (MemberIndex-- == 0)
2870 {
2871 /* return this item */
2872 memcpy(&DeviceInterfaceData->InterfaceClassGuid,
2873 &DevItf->InterfaceClassGuid,
2874 sizeof(GUID));
2875 DeviceInterfaceData->Flags = DevItf->Flags;
2876 DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
2877 found = TRUE;
2878 ret = TRUE;
2879 }
2880 InterfaceListEntry = InterfaceListEntry->Flink;
2881 }
2882 if (!found)
2884 }
2885 else
2886 {
2887 BOOL found = FALSE;
2888 PLIST_ENTRY ItemList = set->ListHead.Flink;
2889 while (ItemList != &set->ListHead && !found)
2890 {
2891 PLIST_ENTRY InterfaceListEntry;
2892 struct DeviceInfo *devInfo =
2893 CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
2894 InterfaceListEntry = devInfo->InterfaceListHead.Flink;
2895 while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
2896 {
2897 struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
2899 {
2900 InterfaceListEntry = InterfaceListEntry->Flink;
2901 continue;
2902 }
2903 if (MemberIndex-- == 0)
2904 {
2905 /* return this item */
2906 memcpy(&DeviceInterfaceData->InterfaceClassGuid,
2907 &DevItf->InterfaceClassGuid,
2908 sizeof(GUID));
2909 DeviceInterfaceData->Flags = DevItf->Flags;
2910 DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
2911 found = TRUE;
2912 ret = TRUE;
2913 }
2914 InterfaceListEntry = InterfaceListEntry->Flink;
2915 }
2916 ItemList = ItemList->Flink;
2917
2918 }
2919 if (!found)
2921 }
2922 return ret;
2923}
2924
2925/***********************************************************************
2926 * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
2927 *
2928 * Destroy a DeviceInfoList and free all used memory of the list.
2929 *
2930 * PARAMS
2931 * devinfo [I] DeviceInfoList pointer to list to destroy
2932 *
2933 * RETURNS
2934 * Success: non zero value.
2935 * Failure: zero value.
2936 */
2938{
2939 BOOL ret = FALSE;
2940
2941 TRACE("%s(%p)\n", __FUNCTION__, devinfo);
2942 if (devinfo && devinfo != INVALID_HANDLE_VALUE)
2943 {
2944 struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
2945
2946 if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
2947 {
2949 }
2950 }
2951
2952 if (ret == FALSE)
2954
2955 return ret;
2956}
2957
2958/***********************************************************************
2959 * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
2960 */
2963 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
2964 PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
2965 DWORD DeviceInterfaceDetailDataSize,
2968{
2969 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
2970 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailDataW = NULL;
2971 DWORD sizeW = 0, bytesNeeded;
2972 BOOL ret = FALSE;
2973
2974 TRACE("%s(%p, %p, %p, %d, %p, %p)\n", __FUNCTION__, DeviceInfoSet,
2975 DeviceInterfaceData, DeviceInterfaceDetailData,
2976 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
2977
2980 {
2982 return FALSE;
2983 }
2984 if (!DeviceInterfaceData ||
2985 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
2986 !DeviceInterfaceData->Reserved)
2987 {
2989 return FALSE;
2990 }
2991 if (DeviceInterfaceDetailData && (DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A)))
2992 {
2994 return FALSE;
2995 }
2996
2997 if((DeviceInterfaceDetailDataSize != 0) &&
2998 (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(CHAR))))
2999 {
3001 return FALSE;
3002 }
3003
3004 if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
3005 {
3007 return FALSE;
3008 }
3009
3010
3011 if (DeviceInterfaceDetailData != NULL)
3012 {
3014 + (DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath)) * sizeof(WCHAR);
3015 DeviceInterfaceDetailDataW = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)MyMalloc(sizeW);
3016 if (!DeviceInterfaceDetailDataW)
3017 {
3019 }
3020 DeviceInterfaceDetailDataW->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
3021 }
3022 if (!DeviceInterfaceDetailData || (DeviceInterfaceDetailData && DeviceInterfaceDetailDataW))
3023 {
3026 DeviceInterfaceData,
3027 DeviceInterfaceDetailDataW,
3028 sizeW,
3029 &sizeW,
3033 if (RequiredSize)
3034 *RequiredSize = bytesNeeded;
3035 if (ret && DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize >= bytesNeeded)
3036 {
3038 CP_ACP, 0,
3039 DeviceInterfaceDetailDataW->DevicePath, -1,
3040 DeviceInterfaceDetailData->DevicePath, DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath),
3041 NULL, NULL))
3042 {
3043 ret = FALSE;
3044 }
3045 }
3046 }
3047 MyFree(DeviceInterfaceDetailDataW);
3048
3049 return ret;
3050}
3051
3052/***********************************************************************
3053 * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
3054 */
3057 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
3058 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
3059 DWORD DeviceInterfaceDetailDataSize,
3062{
3063 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
3064 BOOL ret = FALSE;
3065
3066 TRACE("%s(%p, %p, %p, %d, %p, %p)\n", __FUNCTION__, DeviceInfoSet,
3067 DeviceInterfaceData, DeviceInterfaceDetailData,
3068 DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
3069
3072 {
3074 return FALSE;
3075 }
3076 if (!DeviceInterfaceData ||
3077 DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
3078 !DeviceInterfaceData->Reserved)
3079 {
3081 return FALSE;
3082 }
3083 if (DeviceInterfaceDetailData && DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W))
3084 {
3086 return FALSE;
3087 }
3088 if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
3089 {
3091 return FALSE;
3092 }
3094 {
3096 return FALSE;
3097 }
3098 if ((DeviceInterfaceDetailData != NULL)
3099 && (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) + sizeof(WCHAR)))
3100 {
3102 return FALSE;
3103 }
3104 else
3105 {
3106 struct DeviceInterface *deviceInterface = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
3107 LPCWSTR devName = deviceInterface->SymbolicLink;
3108 DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) +
3109 (lstrlenW(devName) + 1) * sizeof(WCHAR);
3110
3111 if (sizeRequired > DeviceInterfaceDetailDataSize)
3112 {
3114 if (RequiredSize)
3115 *RequiredSize = sizeRequired;
3116 }
3117 else
3118 {
3119 strcpyW(DeviceInterfaceDetailData->DevicePath, devName);
3120 TRACE("DevicePath is %s\n", debugstr_w(DeviceInterfaceDetailData->DevicePath));
3121 if (DeviceInfoData)
3122 {
3124 &deviceInterface->DeviceInfo->ClassGuid,
3125 sizeof(GUID));
3126 DeviceInfoData->DevInst = deviceInterface->DeviceInfo->dnDevInst;
3127 DeviceInfoData->Reserved = (ULONG_PTR)deviceInterface->DeviceInfo;
3128 }
3129 ret = TRUE;
3130 }
3131 }
3132 return ret;
3133}
3134
3136{
3140};
3141
3143 { REG_SZ, "DeviceDesc", REGSTR_VAL_DEVDESC },
3144 { REG_MULTI_SZ, "HardwareId", REGSTR_VAL_HARDWAREID },
3145 { REG_MULTI_SZ, "CompatibleIDs", REGSTR_VAL_COMPATIBLEIDS },
3146 { 0, NULL, NULL }, /* SPDRP_UNUSED0 */
3147 { REG_SZ, "Service", REGSTR_VAL_SERVICE },
3148 { 0, NULL, NULL }, /* SPDRP_UNUSED1 */
3149 { 0, NULL, NULL }, /* SPDRP_UNUSED2 */
3150 { REG_SZ, "Class", REGSTR_VAL_CLASS },
3151 { REG_SZ, "ClassGUID", REGSTR_VAL_CLASSGUID },
3152 { REG_SZ, "Driver", REGSTR_VAL_DRIVER },
3153 { REG_DWORD, "ConfigFlags", REGSTR_VAL_CONFIGFLAGS },
3154 { REG_SZ, "Mfg", REGSTR_VAL_MFG },
3155 { REG_SZ, "FriendlyName", REGSTR_VAL_FRIENDLYNAME },
3156 { REG_SZ, "LocationInformation", REGSTR_VAL_LOCATION_INFORMATION },
3157 { 0, NULL, NULL }, /* SPDRP_PHYSICAL_DEVICE_OBJECT_NAME */
3158 { REG_DWORD, "Capabilities", REGSTR_VAL_CAPABILITIES },
3159 { REG_DWORD, "UINumber", REGSTR_VAL_UI_NUMBER },
3160 { REG_MULTI_SZ, "UpperFilters", REGSTR_VAL_UPPERFILTERS },
3161 { REG_MULTI_SZ, "LowerFilters", REGSTR_VAL_LOWERFILTERS },
3162 { 0, NULL, NULL }, /* SPDRP_BUSTYPEGUID */
3163 { 0, NULL, NULL }, /* SPDRP_LEGACYBUSTYPE */
3164 { 0, NULL, NULL }, /* SPDRP_BUSNUMBER */
3165 { 0, NULL, NULL }, /* SPDRP_ENUMERATOR_NAME */
3166 { REG_BINARY, "Security", REGSTR_SECURITY },
3167 { 0, NULL, NULL }, /* SPDRP_SECURITY_SDS */
3168 { 0, NULL, NULL }, /* SPDRP_DEVTYPE */
3169 { 0, NULL, NULL }, /* SPDRP_EXCLUSIVE */
3170 { 0, NULL, NULL }, /* SPDRP_CHARACTERISTICS */
3171 { 0, NULL, NULL }, /* SPDRP_ADDRESS */
3172 { REG_SZ, "UINumberDescFormat", REGSTR_UI_NUMBER_DESC_FORMAT },
3173 { 0, NULL, NULL }, /* SPDRP_DEVICE_POWER_DATA */
3174 { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY */
3175 { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_HW_DEFAULT */
3176 { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_OVERRIDE */
3177 { 0, NULL, NULL }, /* SPDRP_INSTALL_STATE */
3178};
3179
3180/***********************************************************************
3181 * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
3182 */
3191{
3192 BOOL ret;
3193 BOOL bIsStringProperty;
3194 DWORD RegType;
3195 DWORD RequiredSizeA, RequiredSizeW;
3196 DWORD PropertyBufferSizeW = 0;
3197 PBYTE PropertyBufferW = NULL;
3198
3199 TRACE("%s(%p %p %d %p %p %d %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
3201 RequiredSize);
3202
3203 if (PropertyBufferSize != 0)
3204 {
3205 PropertyBufferSizeW = PropertyBufferSize * 2;
3206 PropertyBufferW = HeapAlloc(GetProcessHeap(), 0, PropertyBufferSizeW);
3207 if (!PropertyBufferW)
3208 {
3210 return FALSE;
3211 }
3212 }
3213
3216 Property,
3217 &RegType,
3218 PropertyBufferW,
3219 PropertyBufferSizeW,
3220 &RequiredSizeW);
3221
3223 {
3224 bIsStringProperty = (RegType == REG_SZ || RegType == REG_MULTI_SZ || RegType == REG_EXPAND_SZ);
3225
3226 if (bIsStringProperty)
3227 RequiredSizeA = RequiredSizeW / sizeof(WCHAR);
3228 else
3229 RequiredSizeA = RequiredSizeW;
3230 if (RequiredSize)
3231 *RequiredSize = RequiredSizeA;
3233 *PropertyRegDataType = RegType;
3234 }
3235
3236 if (!ret)
3237 {
3238 HeapFree(GetProcessHeap(), 0, PropertyBufferW);
3239 return ret;
3240 }
3241
3242 if (RequiredSizeA <= PropertyBufferSize)
3243 {
3244 if (bIsStringProperty && PropertyBufferSize > 0)
3245 {
3246 if (WideCharToMultiByte(CP_ACP, 0, (LPWSTR)PropertyBufferW, RequiredSizeW / sizeof(WCHAR), (LPSTR)PropertyBuffer, PropertyBufferSize, NULL, NULL) == 0)
3247 {
3248 /* Last error is already set by WideCharToMultiByte */
3249 ret = FALSE;
3250 }
3251 }
3252 else
3253 memcpy(PropertyBuffer, PropertyBufferW, RequiredSizeA);
3254 }
3255 else
3256 {
3258 ret = FALSE;
3259 }
3260
3261 HeapFree(GetProcessHeap(), 0, PropertyBufferW);
3262 return ret;
3263}
3264
3265/***********************************************************************
3266 * SetupDiGetDeviceRegistryPropertyW (SETUPAPI.@)
3267 */
3276{
3277 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
3278 struct DeviceInfo *devInfo;
3279 CONFIGRET cr;
3280 LONG lError = ERROR_SUCCESS;
3281 DWORD size;
3282
3283 TRACE("%s(%p %p %d %p %p %d %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
3285 RequiredSize);
3286
3288 {
3290 return FALSE;
3291 }
3292 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
3293 {
3295 return FALSE;
3296 }
3299 {
3301 return FALSE;
3302 }
3303
3305 {
3307 return FALSE;
3308 }
3309
3310 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
3311
3312 if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
3314 {
3315 HKEY hKey;
3317 hKey = SETUPDI_OpenDevKey(set->HKLM, devInfo, KEY_QUERY_VALUE);
3319 return FALSE;
3323
3324 if (RequiredSize)
3325 *RequiredSize = size;
3326
3327 switch (lError)
3328 {
3329 case ERROR_SUCCESS:
3330 if (PropertyBuffer == NULL && size != 0)
3332 break;
3333 case ERROR_MORE_DATA:
3335 break;
3336 default:
3337 break;
3338 }
3339 }
3341 {
3342 size = (strlenW(devInfo->Data) + 1) * sizeof(WCHAR);
3343
3346 if (RequiredSize)
3347 *RequiredSize = size;
3348 if (PropertyBufferSize >= size)
3349 {
3350 strcpyW((LPWSTR)PropertyBuffer, devInfo->Data);
3351 }
3352 else
3354 }
3355 else
3356 {
3358
3363 &size,
3364 0,
3365 set->hMachine);
3366 if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL))
3367 {
3368 if (RequiredSize)
3369 *RequiredSize = size;
3370 }
3371
3372 if (cr != CR_SUCCESS)
3373 {
3374 switch (cr)
3375 {
3376 case CR_INVALID_DEVINST:
3377 lError = ERROR_NO_SUCH_DEVINST;
3378 break;
3379
3382 break;
3383
3384 case CR_BUFFER_SMALL:
3386 break;
3387
3388 default :
3389 lError = ERROR_INVALID_DATA;
3390 break;
3391 }
3392 }
3393 }
3394
3395 SetLastError(lError);
3396 return (lError == ERROR_SUCCESS);
3397}
3398
3399/***********************************************************************
3400 * Internal for SetupDiSetDeviceRegistryPropertyA/W
3401 */
3406 const BYTE *PropertyBuffer,
3408 BOOL isAnsi)
3409{
3410 BOOL ret = FALSE;
3411 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
3412 struct DeviceInfo *deviceInfo;
3413
3414 TRACE("%s(%p %p %d %p %d)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, Property,
3416
3418 {
3420 return FALSE;
3421 }
3422 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
3423 {
3425 return FALSE;
3426 }
3429 {
3431 return FALSE;
3432 }
3433
3434 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
3435
3436 if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
3438 && PropertyMap[Property].nameA)
3439 {
3440 HKEY hKey;
3441 LONG l;
3442 hKey = SETUPDI_OpenDevKey(set->HKLM, deviceInfo, KEY_SET_VALUE);
3444 return FALSE;
3445 /* Write new data */
3446 if (isAnsi)
3447 {
3448 l = RegSetValueExA(
3449 hKey, PropertyMap[Property].nameA, 0,
3452 }
3453 else
3454 {
3455 l = RegSetValueExW(
3459 }
3460 if (!l)
3461 ret = TRUE;
3462 else
3463 SetLastError(l);
3465 }
3466 else
3467 {
3468 ERR("Property 0x%lx not implemented\n", Property);
3470 }
3471
3472 TRACE("Returning %d\n", ret);
3473 return ret;
3474}
3475/***********************************************************************
3476 * SetupDiSetDeviceRegistryPropertyA (SETUPAPI.@)
3477 */
3482 const BYTE *PropertyBuffer,
3484{
3487 Property,
3490 TRUE);
3491}
3492
3493/***********************************************************************
3494 * SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
3495 */
3500 const BYTE *PropertyBuffer,
3502{
3505 Property,
3508 FALSE);
3509}
3510
3511/***********************************************************************
3512 * SetupDiInstallClassA (SETUPAPI.@)
3513 */
3516 PCSTR InfFileName,
3517 DWORD Flags,
3518 HSPFILEQ FileQueue)
3519{
3520 return SetupDiInstallClassExA(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
3521}
3522
3523/***********************************************************************
3524 * SetupDiInstallClassExA (SETUPAPI.@)
3525 */
3529 IN PCSTR InfFileName OPTIONAL,
3530 IN DWORD Flags,
3531 IN HSPFILEQ FileQueue OPTIONAL,
3535{
3536 PWSTR InfFileNameW = NULL;
3537 BOOL Result;
3538
3539 if (!InfFileName)
3540 {
3542 return FALSE;
3543 }
3544 else
3545 {
3546 InfFileNameW = pSetupMultiByteToUnicode(InfFileName, CP_ACP);
3547 if (InfFileNameW == NULL)
3548 {
3550 return FALSE;
3551 }
3552 }
3553
3556
3557 MyFree(InfFileNameW);
3558
3559 return Result;
3560}
3561
3563{
3564 WCHAR FullBuffer[MAX_PATH];
3569
3570 /* Obtain the Class GUID for this class */
3572 hInf,
3573 Version,
3575 Buffer,
3576 sizeof(Buffer) / sizeof(WCHAR),
3577 &RequiredSize))
3578 {
3579 return INVALID_HANDLE_VALUE;
3580 }
3581
3582 /* Build the corresponding registry key name */
3583 lstrcpyW(FullBuffer, REGSTR_PATH_CLASS_NT);
3584 lstrcatW(FullBuffer, BackSlash);
3585 lstrcatW(FullBuffer, Buffer);
3586
3587 /* Obtain the Class name for this class */
3589 hInf,
3590 Version,
3592 Buffer,
3593 sizeof(Buffer) / sizeof(WCHAR),
3594 &RequiredSize))
3595 {
3596 return INVALID_HANDLE_VALUE;
3597 }
3598
3599 /* Try to open or create the registry key */
3600 TRACE("Opening class key %s\n", debugstr_w(FullBuffer));
3601#if 0 // I keep this for reference...
3603 FullBuffer,
3604 0,
3606 &hClassKey))
3607 {
3608 /* Use RegCreateKeyExW */
3609 }
3610#endif
3612 FullBuffer,
3613 0,
3614 NULL,
3617 NULL,
3618 &hClassKey,
3619 &Disposition))
3620 {
3621 ERR("RegCreateKeyExW(%s) failed\n", debugstr_w(FullBuffer));
3622 return INVALID_HANDLE_VALUE;
3623 }
3625 TRACE("The class key %s was successfully created\n", debugstr_w(FullBuffer));
3626 else
3627 TRACE("The class key %s was successfully opened\n", debugstr_w(FullBuffer));
3628
3629 TRACE( "setting value %s to %s\n", debugstr_w(REGSTR_VAL_CLASS), debugstr_w(Buffer) );
3632 0,
3633 REG_SZ,
3634 (LPBYTE)Buffer,
3635 RequiredSize * sizeof(WCHAR)))
3636 {
3639 FullBuffer);
3640 return INVALID_HANDLE_VALUE;
3641 }
3642
3643 return hClassKey;
3644}
3645
3646/***********************************************************************
3647 * SetupDiInstallClassW (SETUPAPI.@)
3648 */
3651 PCWSTR InfFileName,
3652 DWORD Flags,
3653 HSPFILEQ FileQueue)
3654{
3655 return SetupDiInstallClassExW(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
3656}
3657
3658
3659/***********************************************************************
3660 * SetupDiOpenClassRegKey (SETUPAPI.@)
3661 */
3663 const GUID* ClassGuid,
3664 REGSAM samDesired)
3665{
3666 return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
3668}
3669
3670
3671/***********************************************************************
3672 * SetupDiOpenClassRegKeyExA (SETUPAPI.@)
3673 */
3675 const GUID* ClassGuid,
3676 REGSAM samDesired,
3677 DWORD Flags,
3680{
3681 PWSTR MachineNameW = NULL;
3682 HKEY hKey;
3683
3684 TRACE("%s(%s 0x%lx 0x%lx %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), samDesired,
3686
3687 if (MachineName)
3688 {
3690 if (MachineNameW == NULL)
3691 return INVALID_HANDLE_VALUE;
3692 }
3693
3695 Flags, MachineNameW, Reserved);
3696
3697 MyFree(MachineNameW);
3698
3699 return hKey;
3700}
3701
3702
3703/***********************************************************************
3704 * SetupDiOpenClassRegKeyExW (SETUPAPI.@)
3705 */
3707 const GUID* ClassGuid,
3708 REGSAM samDesired,
3709 DWORD Flags,
3712{
3713 HKEY HKLM;
3714 HKEY hClassesKey;
3715 HKEY key;
3716 LPCWSTR lpKeyName;
3717 LONG l;
3718
3719 TRACE("%s(%s 0x%lx 0x%lx %s %p)\n", __FUNCTION__, debugstr_guid(ClassGuid), samDesired,
3721
3722 if (MachineName != NULL)
3723 {
3725 if (l != ERROR_SUCCESS)
3726 {
3727 SetLastError(l);
3728 return INVALID_HANDLE_VALUE;
3729 }
3730 }
3731 else
3733
3734 if (Flags == DIOCR_INSTALLER)
3735 {
3736 lpKeyName = REGSTR_PATH_CLASS_NT;
3737 }
3738 else if (Flags == DIOCR_INTERFACE)
3739 {
3740 lpKeyName = REGSTR_PATH_DEVICE_CLASSES;
3741 }
3742 else
3743 {
3744 ERR("Invalid Flags parameter!\n");
3747 return INVALID_HANDLE_VALUE;
3748 }
3749
3750 if (!ClassGuid)
3751 {
3752 if ((l = RegOpenKeyExW(HKLM,
3753 lpKeyName,
3754 0,
3755 samDesired,
3756 &hClassesKey)))
3757 {
3759 hClassesKey = INVALID_HANDLE_VALUE;
3760 }
3761 if (MachineName != NULL)
3763 key = hClassesKey;
3764 }
3765 else
3766 {
3767 WCHAR bracedGuidString[39];
3768
3769 SETUPDI_GuidToString(ClassGuid, bracedGuidString);
3770
3771 if (!(l = RegOpenKeyExW(HKLM,
3772 lpKeyName,
3773 0,
3774 samDesired,
3775 &hClassesKey)))
3776 {
3777 if (MachineName != NULL)
3779
3780 if ((l = RegOpenKeyExW(hClassesKey,
3781 bracedGuidString,
3782 0,
3783 samDesired,
3784 &key)))
3785 {
3786 SetLastError(l);
3788 }
3789 RegCloseKey(hClassesKey);
3790 }
3791 else
3792 {
3794 SetLastError(l);
3796 }
3797 }
3798
3799 return key;
3800}
3801
3802/***********************************************************************
3803 * SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
3804 */
3808 DWORD OpenFlags,
3809 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
3810{
3811 struct DeviceInfoSet * list;
3812 PCWSTR pEnd;
3813 DWORD dwLength, dwError, dwIndex, dwKeyName, dwSubIndex;
3814 CLSID ClassId;
3815 WCHAR Buffer[MAX_PATH + 1];
3816 WCHAR SymBuffer[MAX_PATH + 1];
3817 WCHAR InstancePath[MAX_PATH + 1];
3818 HKEY hKey, hDevKey, hSymKey;
3819 struct DeviceInfo * deviceInfo;
3820 struct DeviceInterface *deviceInterface;
3821 BOOL Ret;
3822 PLIST_ENTRY ItemList;
3823 PLIST_ENTRY InterfaceListEntry;
3824
3825 TRACE("%s(%p %s %08x %p)\n", __FUNCTION__,
3826 DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
3827
3828
3829 if (DeviceInterfaceData && DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
3830 {
3832 return FALSE;
3833 }
3834
3836 {
3838 return FALSE;
3839 }
3840
3841 list = (struct DeviceInfoSet * )DeviceInfoSet;
3842
3844 if (dwLength < 39)
3845 {
3846 /* path must be at least a guid length + L'\0' */
3848 return FALSE;
3849 }
3850
3851 if (DevicePath[0] != L'\\' ||
3852 DevicePath[1] != L'\\' ||
3853 (DevicePath[2] != L'?' && DevicePath[2] != L'.') ||
3854 DevicePath[3] != L'\\')
3855 {
3856 /* invalid formatted path */
3858 return FALSE;
3859 }
3860
3861 /* check for reference strings */
3862 pEnd = wcschr(&DevicePath[4], L'\\');
3863 if (!pEnd)
3864 {
3865 /* no reference string */
3866 pEnd = DevicePath + dwLength;
3867 }
3868
3869 /* copy guid */
3870 wcscpy(Buffer, pEnd - 37);
3871 Buffer[36] = L'\0';
3872
3873 dwError = UuidFromStringW(Buffer, &ClassId);
3874 if (dwError != NOERROR)
3875 {
3876 /* invalid formatted path */
3878 return FALSE;
3879 }
3880
3881 hKey = SetupDiOpenClassRegKeyExW(&ClassId, KEY_READ, DIOCR_INTERFACE, list->MachineName, NULL);
3882
3884 {
3885 /* invalid device class */
3886 return FALSE;
3887 }
3888
3889 ItemList = list->ListHead.Flink;
3890 while (ItemList != &list->ListHead)
3891 {
3892 deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
3893 InterfaceListEntry = deviceInfo->InterfaceListHead.Flink;
3894 while (InterfaceListEntry != &deviceInfo->InterfaceListHead)
3895 {
3896 deviceInterface = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
3897 if (!IsEqualIID(&deviceInterface->InterfaceClassGuid, &ClassId))
3898 {
3899 InterfaceListEntry = InterfaceListEntry->Flink;
3900 continue;
3901 }
3902
3903 if (!wcsicmp(deviceInterface->SymbolicLink, DevicePath))
3904 {
3905 if (DeviceInterfaceData)
3906 {
3907 DeviceInterfaceData->Reserved = (ULONG_PTR)deviceInterface;
3908 DeviceInterfaceData->Flags = deviceInterface->Flags;
3909 CopyMemory(&DeviceInterfaceData->InterfaceClassGuid, &ClassId, sizeof(GUID));
3910 }
3911
3912 return TRUE;
3913 }
3914
3915 }
3916 }
3917
3918
3919 dwIndex = 0;
3920 do
3921 {
3922 Buffer[0] = 0;
3923 dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
3924 dwError = RegEnumKeyExW(hKey, dwIndex, Buffer, &dwKeyName, NULL, NULL, NULL, NULL);
3925
3926 if (dwError != ERROR_SUCCESS)
3927 break;
3928
3929 if (RegOpenKeyExW(hKey, Buffer, 0, KEY_READ, &hDevKey) != ERROR_SUCCESS)
3930 break;
3931
3932 dwSubIndex = 0;
3933 InstancePath[0] = 0;
3934 dwKeyName = sizeof(InstancePath);
3935
3936 dwError = RegQueryValueExW(hDevKey, L"DeviceInstance", NULL, NULL, (LPBYTE)InstancePath, &dwKeyName);
3937
3938 while(TRUE)
3939 {
3940 Buffer[0] = 0;
3941 dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
3942 dwError = RegEnumKeyExW(hDevKey, dwSubIndex, Buffer, &dwKeyName, NULL, NULL, NULL, NULL);
3943
3944 if (dwError != ERROR_SUCCESS)
3945 break;
3946
3947 dwError = RegOpenKeyExW(hDevKey, Buffer, 0, KEY_READ, &hSymKey);
3948 if (dwError != ERROR_SUCCESS)
3949 break;
3950
3951 /* query for symbolic link */
3952 dwKeyName = sizeof(SymBuffer);
3953 SymBuffer[0] = L'\0';
3954 dwError = RegQueryValueExW(hSymKey, L"SymbolicLink", NULL, NULL, (LPBYTE)SymBuffer, &dwKeyName);
3955
3956 if (dwError != ERROR_SUCCESS)
3957 {
3958 RegCloseKey(hSymKey);
3959 break;
3960 }
3961
3962 if (!wcsicmp(SymBuffer, DevicePath))
3963 {
3964 Ret = CreateDeviceInfo(list, InstancePath, &ClassId, &deviceInfo);
3965 RegCloseKey(hSymKey);
3966 RegCloseKey(hDevKey);
3968
3969 if (Ret)
3970 {
3971 deviceInterface = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInterface) + (wcslen(SymBuffer) + 1) * sizeof(WCHAR));
3972 if (deviceInterface)
3973 {
3974
3975 CopyMemory(&deviceInterface->InterfaceClassGuid, &ClassId, sizeof(GUID));
3976 deviceInterface->DeviceInfo = deviceInfo;
3977 deviceInterface->Flags = SPINT_ACTIVE; //FIXME
3978
3979 wcscpy(deviceInterface->SymbolicLink, SymBuffer);
3980
3981 InsertTailList(&deviceInfo->InterfaceListHead, &deviceInterface->ListEntry);
3982 InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
3983
3984
3985 if (DeviceInterfaceData)
3986 {
3987 DeviceInterfaceData->Reserved = (ULONG_PTR)deviceInterface;
3988 DeviceInterfaceData->Flags = deviceInterface->Flags;
3989 CopyMemory(&DeviceInterfaceData->InterfaceClassGuid, &ClassId, sizeof(GUID));
3990 }
3991 else
3992 {
3993 Ret = FALSE;
3995 }
3996 }
3997 }
3998 else
3999 {
4000 HeapFree(GetProcessHeap(), 0, deviceInfo);
4001 Ret = FALSE;
4002 }
4003 return Ret;
4004 }
4005 RegCloseKey(hSymKey);
4006 dwSubIndex++;
4007 }
4008
4009 RegCloseKey(hDevKey);
4010 dwIndex++;
4011 } while(TRUE);
4012
4014 return FALSE;
4015}
4016
4017/***********************************************************************
4018 * SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
4019 */
4023 DWORD OpenFlags,
4024 PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
4025{
4026 LPWSTR DevicePathW = NULL;
4027 BOOL bResult;
4028
4029 TRACE("%s(%p %s %08lx %p)\n", __FUNCTION__, DeviceInfoSet, debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
4030
4032 if (DevicePathW == NULL)
4033 return FALSE;
4034
4036 DevicePathW, OpenFlags, DeviceInterfaceData);
4037
4038 MyFree(DevicePathW);
4039
4040 return bResult;
4041}
4042
4043/***********************************************************************
4044 * SetupDiSetClassInstallParamsA (SETUPAPI.@)
4045 */
4051{
4052 FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData,
4053 ClassInstallParams->InstallFunction, ClassInstallParamsSize);
4054 return FALSE;
4055}
4056
4057static BOOL WINAPI
4061{
4063}
4064
4065/***********************************************************************
4066 * SetupDiCallClassInstaller (SETUPAPI.@)
4067 */
4069 DI_FUNCTION InstallFunction,
4072{
4073 BOOL ret = FALSE;
4074
4075 TRACE("%s(%u %p %p)\n", __FUNCTION__, InstallFunction, DeviceInfoSet, DeviceInfoData);
4076
4077 if (!DeviceInfoSet)
4083 else if (((struct DeviceInfoSet *)DeviceInfoSet)->HKLM != HKEY_LOCAL_MACHINE)
4085 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4087 else
4088 {
4090#define CLASS_COINSTALLER 0x1
4091#define DEVICE_COINSTALLER 0x2
4092#define CLASS_INSTALLER 0x4
4093 UCHAR CanHandle = 0;
4095
4096 switch (InstallFunction)
4097 {
4100 break;
4103 break;
4104 case DIF_ALLOW_INSTALL:
4105 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4106 break;
4107 case DIF_DETECT:
4108 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4109 break;
4111 CanHandle = CLASS_INSTALLER;
4112 break;
4113 case DIF_INSTALLDEVICE:
4116 break;
4118 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4120 break;
4124 break;
4127 break;
4129 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4130 break;
4132 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4133 break;
4135 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4136 break;
4138 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4139 break;
4142 break;
4143 case DIF_PROPERTYCHANGE:
4146 break;
4148 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4150 break;
4151 case DIF_REGISTERDEVICE:
4152 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4154 break;
4155 case DIF_REMOVE:
4158 break;
4160 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4162 break;
4163 case DIF_SELECTDEVICE:
4164 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
4166 break;
4167 case DIF_TROUBLESHOOTER:
4169 break;
4170 case DIF_UNREMOVE:
4173 break;
4174 default:
4175 ERR("Install function %u not supported\n", InstallFunction);
4177 }
4178
4181 /* Don't process this call, as a parameter is invalid */
4182 CanHandle = 0;
4183
4184 if (CanHandle != 0)
4185 {
4186 LIST_ENTRY ClassCoInstallersListHead;
4187 LIST_ENTRY DeviceCoInstallersListHead;
4188 HMODULE ClassInstallerLibrary = NULL;
4189 CLASS_INSTALL_PROC ClassInstaller = NULL;
4191 PLIST_ENTRY ListEntry;
4192 HKEY hKey;
4193 DWORD dwRegType, dwLength;
4194 DWORD rc = NO_ERROR;
4195
4196 InitializeListHead(&ClassCoInstallersListHead);
4197 InitializeListHead(&DeviceCoInstallersListHead);
4198
4199 if (CanHandle & DEVICE_COINSTALLER)
4200 {
4203 {
4205 if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
4206 {
4207 LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
4208 if (KeyBuffer != NULL)
4209 {
4211 if (rc == ERROR_SUCCESS)
4212 {
4213 LPWSTR ptr;
4214 for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
4215 {
4216 /* Add coinstaller to DeviceCoInstallersListHead list */
4217 struct CoInstallerElement *coinstaller;
4218 TRACE("Got device 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(&DeviceCoInstallersListHead, &coinstaller->ListEntry);
4225 else
4226 HeapFree(GetProcessHeap(), 0, coinstaller);
4227 }
4228 }
4229 HeapFree(GetProcessHeap(), 0, KeyBuffer);
4230 }
4231 }
4233 }
4234 }
4235 if (CanHandle & CLASS_COINSTALLER)
4236 {
4237 rc = RegOpenKeyExW(
4240 0, /* Options */
4242 &hKey);
4243 if (rc == ERROR_SUCCESS)
4244 {
4245 WCHAR szGuidString[40];
4246 if (pSetupStringFromGuid(&DeviceInfoData->ClassGuid, szGuidString, ARRAYSIZE(szGuidString)) == ERROR_SUCCESS)
4247 {
4248 rc = RegQueryValueExW(hKey, szGuidString, NULL, &dwRegType, NULL, &dwLength);
4249 if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
4250 {
4251 LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
4252 if (KeyBuffer != NULL)
4253 {
4254 rc = RegQueryValueExW(hKey, szGuidString, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
4255 if (rc == ERROR_SUCCESS)
4256 {
4257 LPWSTR ptr;
4258 for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
4259 {
4260 /* Add coinstaller to ClassCoInstallersListHead list */
4261 struct CoInstallerElement *coinstaller;
4262 TRACE("Got class coinstaller '%s'\n", debugstr_w(ptr));
4263 coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement));
4264 if (!coinstaller)
4265 continue;
4266 ZeroMemory(coinstaller, sizeof(struct CoInstallerElement));
4267 if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS)
4268 InsertTailList(&ClassCoInstallersListHead, &coinstaller->ListEntry);
4269 else
4270 HeapFree(GetProcessHeap(), 0, coinstaller);
4271 }
4272 }
4273 HeapFree(GetProcessHeap(), 0, KeyBuffer);
4274 }
4275 }
4276 }
4278 }
4279 }
4280 if ((CanHandle & CLASS_INSTALLER) && !(InstallParams.FlagsEx & DI_FLAGSEX_CI_FAILED))
4281 {
4284 {
4286 if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
4287 {
4288 LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
4289 if (KeyBuffer != NULL)
4290 {
4292 if (rc == ERROR_SUCCESS)
4293 {
4294 /* Get ClassInstaller function pointer */
4295 TRACE("Got class installer '%s'\n", debugstr_w(KeyBuffer));
4296 if (GetFunctionPointer(KeyBuffer, &ClassInstallerLibrary, (PVOID*)&ClassInstaller) != ERROR_SUCCESS)
4297 {
4298 InstallParams.FlagsEx |= DI_FLAGSEX_CI_FAILED;
4300 }
4301 }
4302 HeapFree(GetProcessHeap(), 0, KeyBuffer);
4303 }
4304 }
4306 }
4307 }
4308
4309 /* Call Class co-installers */
4310 Context.PostProcessing = FALSE;
4311 rc = NO_ERROR;
4312 ListEntry = ClassCoInstallersListHead.Flink;
4313 while (rc == NO_ERROR && ListEntry != &ClassCoInstallersListHead)
4314 {
4315 struct CoInstallerElement *coinstaller;
4317 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4318 coinstaller->PrivateData = Context.PrivateData;
4320 {
4321 coinstaller->DoPostProcessing = TRUE;
4322 rc = NO_ERROR;
4323 }
4325 }
4326
4327 /* Call Device co-installers */
4328 ListEntry = DeviceCoInstallersListHead.Flink;
4329 while (rc == NO_ERROR && ListEntry != &DeviceCoInstallersListHead)
4330 {
4331 struct CoInstallerElement *coinstaller;
4333 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4334 coinstaller->PrivateData = Context.PrivateData;
4336 {
4337 coinstaller->DoPostProcessing = TRUE;
4338 rc = NO_ERROR;
4339 }
4341 }
4342
4343 /* Call Class installer */
4344 if (ClassInstaller)
4345 {
4346 rc = (*ClassInstaller)(InstallFunction, DeviceInfoSet, DeviceInfoData);
4347 FreeFunctionPointer(ClassInstallerLibrary, ClassInstaller);
4348 }
4349 else
4351
4352 /* Call default handler */
4353 if (rc == ERROR_DI_DO_DEFAULT)
4354 {
4355 if (DefaultHandler && !(InstallParams.Flags & DI_NODI_DEFAULTACTION))
4356 {
4358 rc = NO_ERROR;
4359 else
4360 rc = GetLastError();
4361 }
4362 else
4363 rc = NO_ERROR;
4364 }
4365
4366 /* Call Class co-installers that required postprocessing */
4367 Context.PostProcessing = TRUE;
4368 ListEntry = ClassCoInstallersListHead.Flink;
4369 while (ListEntry != &ClassCoInstallersListHead)
4370 {
4371 struct CoInstallerElement *coinstaller;
4373 if (coinstaller->DoPostProcessing)
4374 {
4375 Context.InstallResult = rc;
4376 Context.PrivateData = coinstaller->PrivateData;
4377 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4378 }
4379 FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
4381 }
4382
4383 /* Call Device co-installers that required postprocessing */
4384 ListEntry = DeviceCoInstallersListHead.Flink;
4385 while (ListEntry != &DeviceCoInstallersListHead)
4386 {
4387 struct CoInstallerElement *coinstaller;
4389 if (coinstaller->DoPostProcessing)
4390 {
4391 Context.InstallResult = rc;
4392 Context.PrivateData = coinstaller->PrivateData;
4393 rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
4394 }
4395 FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
4397 }
4398
4399 /* Free allocated memory */
4400 while (!IsListEmpty(&ClassCoInstallersListHead))
4401 {
4402 ListEntry = RemoveHeadList(&ClassCoInstallersListHead);
4404 }
4405 while (!IsListEmpty(&DeviceCoInstallersListHead))
4406 {
4407 ListEntry = RemoveHeadList(&DeviceCoInstallersListHead);
4409 }
4410
4411 ret = (rc == NO_ERROR);
4412 }
4413 }
4414
4415 TRACE("Returning %d\n", ret);
4416 return ret;
4417}
4418
4419/***********************************************************************
4420 * SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
4421 */
4426{
4427 SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
4428 BOOL ret = FALSE;
4429
4431
4434 else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_A))
4436 else
4437 {
4438 deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
4440
4441 if (ret)
4442 {
4443 /* Do W->A conversion */
4444 memcpy(
4446 &deviceInstallParamsW,
4448 if (WideCharToMultiByte(CP_ACP, 0, deviceInstallParamsW.DriverPath, -1,
4449 DeviceInstallParams->DriverPath, MAX_PATH, NULL, NULL) == 0)
4450 {
4451 DeviceInstallParams->DriverPath[0] = '\0';
4452 ret = FALSE;
4453 }
4454 }
4455 }
4456
4457 TRACE("Returning %d\n", ret);
4458 return ret;
4459}
4460
4461/***********************************************************************
4462 * SetupDiGetDeviceInfoListClass (SETUPAPI.@)
4463 */
4467 OUT LPGUID ClassGuid)
4468{
4469 struct DeviceInfoSet *list;
4470 BOOL ret = FALSE;
4471
4472 TRACE("%s(%p %p)\n", __FUNCTION__, DeviceInfoSet, ClassGuid);
4473
4474 if (!DeviceInfoSet)
4478 else if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
4480 else
4481 {
4482 *ClassGuid = list->ClassGuid;
4483
4484 ret = TRUE;
4485 }
4486
4487 TRACE("Returning %d\n", ret);
4488 return ret;
4489}
4490
4491/***********************************************************************
4492 * SetupDiGetDeviceInstallParamsW (SETUPAPI.@)
4493 */
4499{
4500 struct DeviceInfoSet *list;
4501 BOOL ret = FALSE;
4502
4504
4505 if (!DeviceInfoSet)
4509 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4511 else if (!DeviceInstallParams)
4513 else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
4515 else
4516 {
4518
4519 if (DeviceInfoData)
4520 Source = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
4521 else
4522 Source = &list->InstallParams;
4523
4524 ret = TRUE;
4525
4526 _SEH2_TRY
4527 {
4529 }
4531 {
4533 ret = FALSE;
4534 }
4535 _SEH2_END;
4536 }
4537
4538 TRACE("Returning %d\n", ret);
4539 return ret;
4540}
4541
4542static BOOL
4545{
4546 DWORD SupportedFlags =
4547 DI_NOVCP | /* 0x00000008 */
4548 DI_DIDCOMPAT | /* 0x00000010 */
4549 DI_DIDCLASS | /* 0x00000020 */
4550 DI_NEEDRESTART | /* 0x00000080 */
4551 DI_NEEDREBOOT | /* 0x00000100 */
4552 DI_RESOURCEPAGE_ADDED | /* 0x00002000 */
4553 DI_PROPERTIES_CHANGE | /* 0x00004000 */
4554 DI_ENUMSINGLEINF | /* 0x00010000 */
4555 DI_DONOTCALLCONFIGMG | /* 0x00020000 */
4556 DI_CLASSINSTALLPARAMS | /* 0x00100000 */
4557 DI_NODI_DEFAULTACTION | /* 0x00200000 */
4558 DI_QUIETINSTALL | /* 0x00800000 */
4559 DI_NOFILECOPY | /* 0x01000000 */
4560 DI_DRIVERPAGE_ADDED; /* 0x04000000 */
4561 DWORD SupportedFlagsEx =
4562 DI_FLAGSEX_CI_FAILED | /* 0x00000004 */
4563 DI_FLAGSEX_DIDINFOLIST | /* 0x00000010 */
4564 DI_FLAGSEX_DIDCOMPATINFO | /* 0x00000020 */
4565 DI_FLAGSEX_ALLOWEXCLUDEDDRVS | /* 0x00000800 */
4566 DI_FLAGSEX_NO_DRVREG_MODIFY | /* 0x00008000 */
4567 DI_FLAGSEX_INSTALLEDDRIVER; /* 0x04000000 */
4568 BOOL ret = FALSE;
4569
4570 /* FIXME: add support for more flags */
4571
4572 /* FIXME: DI_CLASSINSTALLPARAMS flag is not correctly used.
4573 * It should be checked before accessing to other values
4574 * of the SP_DEVINSTALL_PARAMS structure */
4575
4576 if (DeviceInstallParams->Flags & ~SupportedFlags)
4577 {
4578 FIXME("Unknown Flags: 0x%08lx\n", DeviceInstallParams->Flags & ~SupportedFlags);
4580 }
4581 else if (DeviceInstallParams->FlagsEx & ~SupportedFlagsEx)
4582 {
4583 FIXME("Unknown FlagsEx: 0x%08lx\n", DeviceInstallParams->FlagsEx & ~SupportedFlagsEx);
4585 }
4586 else if ((DeviceInstallParams->Flags & DI_NOVCP)
4587 && (DeviceInstallParams->FileQueue == NULL || DeviceInstallParams->FileQueue == (HSPFILEQ)INVALID_HANDLE_VALUE))
4589 else
4590 {
4591 /* FIXME: check Reserved field */
4592 ret = TRUE;
4593 }
4594
4595 return ret;
4596}
4597
4598/***********************************************************************
4599 * SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
4600 */
4606{
4607 struct DeviceInfoSet *list;
4608 BOOL ret = FALSE;
4609
4611
4612 if (!DeviceInfoSet)
4616 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4618 else if (!DeviceInstallParams)
4620 else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
4623 {
4625
4626 if (DeviceInfoData)
4627 Destination = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
4628 else
4629 Destination = &list->InstallParams;
4631 ret = TRUE;
4632 }
4633
4634 TRACE("Returning %d\n", ret);
4635 return ret;
4636}
4637
4638/***********************************************************************
4639 * SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
4640 */
4646{
4647 SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
4648 int len = 0;
4649 BOOL ret = FALSE;
4650
4652
4655 else if (DeviceInstallParams->cbSize < sizeof(SP_DEVINSTALL_PARAMS_A))
4657 else
4658 {
4659 memcpy(&deviceInstallParamsW, DeviceInstallParams, FIELD_OFFSET(SP_DEVINSTALL_PARAMS_A, DriverPath));
4660 deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
4661 len = MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, NULL, 0);
4662 if (!len)
4663 {
4664 ERR("DrivePath is NULL\n");
4665 ret = FALSE;
4666 }
4667 else
4668 {
4669 MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, deviceInstallParamsW.DriverPath, len);
4671 }
4672 }
4673
4674 TRACE("Returning %d\n", ret);
4675 return ret;
4676}
4677
4678static HKEY
4680 IN HKEY HKLM,
4681 IN DWORD HwProfile,
4682 IN DWORD samDesired)
4683{
4684 HKEY hHWProfilesKey = NULL;
4685 HKEY hHWProfileKey = NULL;
4687 LONG rc;
4688
4689 rc = RegOpenKeyExW(HKLM,
4691 0,
4693 &hHWProfilesKey);
4694 if (rc != ERROR_SUCCESS)
4695 {
4696 SetLastError(rc);
4697 goto cleanup;
4698 }
4699 if (HwProfile == 0)
4700 {
4701 rc = RegOpenKeyExW(hHWProfilesKey,
4703 0,
4705 &hHWProfileKey);
4706 }
4707 else
4708 {
4709 WCHAR subKey[5];
4710 snprintfW(subKey, 4, InstanceKeyFormat, HwProfile);
4711 subKey[4] = '\0';
4712 rc = RegOpenKeyExW(hHWProfilesKey,
4713 subKey,
4714 0,
4716 &hHWProfileKey);
4717 }
4718 if (rc != ERROR_SUCCESS)
4719 {
4720 SetLastError(rc);
4721 goto cleanup;
4722 }
4723 ret = hHWProfileKey;
4724
4725cleanup:
4726 if (hHWProfilesKey != NULL)
4727 RegCloseKey(hHWProfilesKey);
4728 if (hHWProfileKey != NULL && hHWProfileKey != ret)
4729 RegCloseKey(hHWProfileKey);
4730 return ret;
4731}
4732
4733static BOOL
4735 struct DeviceInfoSet *deviceInfoSet,
4736 struct DeviceInfo *deviceInfo)
4737{
4739
4740 ListEntry = deviceInfoSet->ListHead.Flink;
4741 while (ListEntry != &deviceInfoSet->ListHead)
4742 {
4743 if (deviceInfo == CONTAINING_RECORD(ListEntry, struct DeviceInfo, ListEntry))
4744 return TRUE;
4745
4747 }
4748
4749 return FALSE;
4750}
4751
4752/***********************************************************************
4753 * SetupDiDeleteDeviceInfo (SETUPAPI.@)
4754 */
4759{
4760 struct DeviceInfoSet *deviceInfoSet;
4761 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData;
4762 BOOL ret = FALSE;
4763
4765
4766 if (!DeviceInfoSet)
4768 else if ((deviceInfoSet = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
4770 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4772 else if (!IsDeviceInfoInDeviceInfoSet(deviceInfoSet, deviceInfo))
4774 else
4775 {
4776 RemoveEntryList(&deviceInfo->ListEntry);
4777 DestroyDeviceInfo(deviceInfo);
4778 ret = TRUE;
4779 }
4780
4781 return ret;
4782}
4783
4784
4785/***********************************************************************
4786 * SetupDiOpenDeviceInfoA (SETUPAPI.@)
4787 */
4791 IN PCSTR DeviceInstanceId,
4793 IN DWORD OpenFlags,
4795{
4796 LPWSTR DeviceInstanceIdW = NULL;
4797 BOOL bResult;
4798
4799 TRACE("%s(%p %s %p %lx %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInstanceId, hwndParent, OpenFlags, DeviceInfoData);
4800
4801 DeviceInstanceIdW = pSetupMultiByteToUnicode(DeviceInstanceId, CP_ACP);
4802 if (DeviceInstanceIdW == NULL)
4803 return FALSE;
4804
4806 DeviceInstanceIdW, hwndParent, OpenFlags, DeviceInfoData);
4807
4808 MyFree(DeviceInstanceIdW);
4809
4810 return bResult;
4811}
4812
4813
4814/***********************************************************************
4815 * SetupDiOpenDeviceInfoW (SETUPAPI.@)
4816 */
4820 IN PCWSTR DeviceInstanceId,
4822 IN DWORD OpenFlags,
4824{
4825 struct DeviceInfoSet *list;
4827 DWORD rc, dwSize;
4828 BOOL ret = FALSE;
4829
4830 TRACE("%s(%p %s %p %lx %p)\n", __FUNCTION__,
4831 DeviceInfoSet, debugstr_w(DeviceInstanceId),
4832 hwndParent, OpenFlags, DeviceInfoData);
4833
4834 if (OpenFlags & DIOD_CANCEL_REMOVE)
4835 FIXME("DIOD_CANCEL_REMOVE flag not implemented\n");
4836
4837 if (!DeviceInfoSet)
4841 else if (!DeviceInstanceId)
4843 else if (OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS))
4844 {
4845 TRACE("Unknown flags: 0x%08lx\n", OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS));
4847 }
4848 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4850 else
4851 {
4852 struct DeviceInfo *deviceInfo = NULL;
4853 /* Search if device already exists in DeviceInfoSet.
4854 * If yes, return the existing element
4855 * If no, create a new element using information in registry
4856 */
4857 PLIST_ENTRY ItemList = list->ListHead.Flink;
4858 while (ItemList != &list->ListHead)
4859 {
4860 deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
4861 if (!wcscmp(deviceInfo->instanceId, DeviceInstanceId))
4862 break;
4863 deviceInfo = NULL;
4864 ItemList = ItemList->Flink;
4865 }
4866
4867 if (deviceInfo)
4868 {
4869 /* good one found */
4870 ret = TRUE;
4871 }
4872 else
4873 {
4875 WCHAR szClassGuid[MAX_GUID_STRING_LEN];
4876
4877 /* Open supposed registry key */
4878 rc = RegOpenKeyExW(
4879 list->HKLM,
4881 0, /* Options */
4883 &hEnumKey);
4884 if (rc != ERROR_SUCCESS)
4885 {
4886 SetLastError(rc);
4887 goto cleanup;
4888 }
4889 rc = RegOpenKeyExW(
4890 hEnumKey,
4891 DeviceInstanceId,
4892 0, /* Options */
4894 &hKey);
4896 if (rc != ERROR_SUCCESS)
4897 {
4898 if (rc == ERROR_FILE_NOT_FOUND)
4900 SetLastError(rc);
4901 goto cleanup;
4902 }
4903
4905 dwSize = MAX_GUID_STRING_LEN * sizeof(WCHAR);
4906
4909 NULL,
4910 NULL,
4911 (LPBYTE)szClassGuid,
4912 &dwSize) == ERROR_SUCCESS)
4913 {
4914 szClassGuid[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
4915
4916 /* Convert a string to a ClassGuid */
4917 UuidFromStringW(&szClassGuid[1], &ClassGUID);
4918 }
4919
4920 if (!CreateDeviceInfo(list, DeviceInstanceId, &ClassGUID, &deviceInfo))
4921 goto cleanup;
4922
4923 InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
4924
4925 ret = TRUE;
4926 }
4927
4928 if (ret && deviceInfo && DeviceInfoData)
4929 {
4930 memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID));
4931 DeviceInfoData->DevInst = deviceInfo->dnDevInst;
4932 DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
4933 }
4934 }
4935
4936cleanup:
4937 if (hKey != NULL)
4939 return ret;
4940}
4941
4942
4943/***********************************************************************
4944 * SetupDiGetSelectedDevice (SETUPAPI.@)
4945 */
4950{
4951 struct DeviceInfoSet *list;
4952 BOOL ret = FALSE;
4953
4955
4956 if (!DeviceInfoSet)
4960 else if (list->SelectedDevice == NULL)
4962 else if (!DeviceInfoData)
4964 else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
4966 else
4967 {
4969 &list->SelectedDevice->ClassGuid,
4970 sizeof(GUID));
4971 DeviceInfoData->DevInst = list->SelectedDevice->dnDevInst;
4972 DeviceInfoData->Reserved = (ULONG_PTR)list->SelectedDevice;
4973 ret = TRUE;
4974 }
4975
4976 TRACE("Returning %d\n", ret);
4977 return ret;
4978}
4979
4980
4981/***********************************************************************
4982 * SetupDiSetSelectedDevice (SETUPAPI.@)
4983 */
4988{
4989 struct DeviceInfoSet *list;
4990 BOOL ret = FALSE;
4991
4993
4994 if (!DeviceInfoSet)
4998 else if (!DeviceInfoData)
5000 else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
5002 else if (DeviceInfoData->Reserved == 0)
5004 else
5005 {
5006 list->SelectedDevice = (struct DeviceInfo *)DeviceInfoData->Reserved;
5007 ret = TRUE;
5008 }
5009
5010 TRACE("Returning %d\n", ret);
5011 return ret;
5012}
5013
5014
5015/* Return the current hardware profile id, or -1 if error */
5016static DWORD
5019{
5020 HKEY hKey = NULL;
5021 DWORD dwRegType, dwLength;
5022 DWORD hwProfile;
5023 LONG rc;
5024 DWORD ret = (DWORD)-1;
5025
5028 0, /* Options */
5030 &hKey);
5031 if (rc != ERROR_SUCCESS)
5032 {
5033 SetLastError(rc);
5034 goto cleanup;
5035 }
5036
5037 dwLength = sizeof(DWORD);
5040 NULL,
5041 &dwRegType,
5042 (LPBYTE)&hwProfile, &dwLength);
5043 if (rc != ERROR_SUCCESS)
5044 {
5045 SetLastError(rc);
5046 goto cleanup;
5047 }
5048 else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
5049 {
5051 goto cleanup;
5052 }
5053
5054 ret = hwProfile;
5055
5056cleanup:
5057 if (hKey != NULL)
5059
5060 return ret;
5061}
5062
5063static BOOL
5067{
5068#ifndef __WINESRC__
5069 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5070 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5071 CONFIGRET cr;
5072
5073 cr = CM_Enable_DevNode_Ex(deviceInfo->dnDevInst, 0, set->hMachine);
5074 if (cr != CR_SUCCESS)
5075 {
5077 return FALSE;
5078 }
5079
5080 return TRUE;
5081#else
5082 FIXME("Stub: ResetDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
5083 return TRUE;
5084#endif
5085}
5086
5087static BOOL
5091{
5092#ifndef __WINESRC__
5093 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5094 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5095 CONFIGRET cr;
5096
5097 cr = CM_Disable_DevNode_Ex(deviceInfo->dnDevInst, 0, set->hMachine);
5098 if (cr != CR_SUCCESS)
5099 {
5101 return FALSE;
5102 }
5103
5104 return TRUE;
5105#else
5106 FIXME("Stub: StopDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
5107 return TRUE;
5108#endif
5109}
5110
5111/***********************************************************************
5112 * SetupDiChangeState (SETUPAPI.@)
5113 */
5118{
5119 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5120 struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5121 PSP_PROPCHANGE_PARAMS PropChange;
5123 LPCWSTR RegistryValueName;
5124 DWORD dwConfigFlags, dwLength, dwRegType;
5125 LONG rc;
5126 BOOL ret = FALSE;
5127
5129
5130 if (!DeviceInfoData)
5131 PropChange = ((struct DeviceInfoSet *)DeviceInfoSet)->ClassInstallParams.PropChangeParams;
5132 else
5133 PropChange = ((struct DeviceInfo *)DeviceInfoData->Reserved)->ClassInstallParams.PropChangeParams;
5134 if (!PropChange)
5135 {
5137 goto cleanup;
5138 }
5139
5140 if (PropChange->Scope == DICS_FLAG_GLOBAL)
5141 RegistryValueName = REGSTR_VAL_CONFIGFLAGS;
5142 else
5143 RegistryValueName = REGSTR_VAL_CSCONFIGFLAGS;
5144
5145 switch (PropChange->StateChange)
5146 {
5147 case DICS_ENABLE:
5148 case DICS_DISABLE:
5149 {
5150 if (PropChange->Scope == DICS_FLAG_GLOBAL)
5151 hRootKey = set->HKLM;
5152 else /* PropChange->Scope == DICS_FLAG_CONFIGSPECIFIC */
5153 {
5154 hRootKey = OpenHardwareProfileKey(set->HKLM, PropChange->HwProfile, KEY_CREATE_SUB_KEY);
5155 if (hRootKey == INVALID_HANDLE_VALUE)
5156 goto cleanup;
5157 }
5158
5159 /* Enable/disable device in registry */
5160 hKey = SETUPDI_OpenDrvKey(hRootKey, deviceInfo, KEY_QUERY_VALUE | KEY_SET_VALUE);
5162 hKey = SETUPDI_CreateDevKey(hRootKey, deviceInfo, KEY_QUERY_VALUE | KEY_SET_VALUE);
5164 break;
5165 dwLength = sizeof(DWORD);
5166 rc = RegQueryValueExW(
5167 hKey,
5168 RegistryValueName,
5169 NULL,
5170 &dwRegType,
5171 (LPBYTE)&dwConfigFlags, &dwLength);
5172 if (rc == ERROR_FILE_NOT_FOUND)
5173 dwConfigFlags = 0;
5174 else if (rc != ERROR_SUCCESS)
5175 {
5176 SetLastError(rc);
5177 goto cleanup;
5178 }
5179 else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
5180 {
5182 goto cleanup;
5183 }
5184 if (PropChange->StateChange == DICS_ENABLE)
5185 dwConfigFlags &= ~(PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
5186 else
5187 dwConfigFlags |= (PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
5188 rc = RegSetValueExW(
5189 hKey,
5190 RegistryValueName,
5191 0,
5192 REG_DWORD,
5193 (LPBYTE)&dwConfigFlags, sizeof(DWORD));
5194 if (rc != ERROR_SUCCESS)
5195 {
5196 SetLastError(rc);
5197 goto cleanup;
5198 }
5199
5200 /* Enable/disable device if needed */
5201 if (PropChange->Scope == DICS_FLAG_GLOBAL
5202 || PropChange->HwProfile == 0
5203 || PropChange->HwProfile == SETUPAPI_GetCurrentHwProfile(DeviceInfoSet))
5204 {
5205 if (PropChange->StateChange == DICS_ENABLE)
5207 else
5209 }
5210 else
5211 ret = TRUE;
5212 break;
5213 }
5214 case DICS_PROPCHANGE:
5215 {
5217 break;
5218 }
5219 default:
5220 {
5221 ERR("Unknown StateChange 0x%lx\n", PropChange->StateChange);
5223 }
5224 }
5225
5226cleanup:
5227 if (hRootKey != INVALID_HANDLE_VALUE && hRootKey != set->HKLM)
5228 RegCloseKey(hRootKey);
5229
5232
5233 TRACE("Returning %d\n", ret);
5234 return ret;
5235}
5236
5237/***********************************************************************
5238 * SetupDiSelectDevice (SETUPAPI.@)
5239 */
5244{
5245 FIXME("%p %p\n", DeviceInfoSet, DeviceInfoData);
5247 return FALSE;
5248}
5249
5250
5251/***********************************************************************
5252 * SetupDiRegisterCoDeviceInstallers (SETUPAPI.@)
5253 */
5258{
5259 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5260 struct DeviceInfo *deviceInfo;
5261 BOOL ret = FALSE; /* Return value */
5262
5264
5265 if (!DeviceInfoSet)
5269 else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
5271 else if (!DeviceInfoData)
5273 else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
5275 else
5276 {
5278 struct DriverInfoElement *SelectedDriver;
5279 BOOL Result;
5280 DWORD DoAction;
5281 WCHAR SectionName[MAX_PATH];
5282 DWORD SectionNameLength = 0;
5284 PVOID Context = NULL;
5285
5286 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
5288 if (!Result)
5289 goto cleanup;
5290
5291 SelectedDriver = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
5292 if (SelectedDriver == NULL)
5293 {
5295 goto cleanup;
5296 }
5297
5298 /* Get .CoInstallers section name */
5300 SelectedDriver->InfFileDetails->hInf,
5301 SelectedDriver->Details.SectionName,
5302 SectionName, MAX_PATH, &SectionNameLength, NULL);
5303 if (!Result || SectionNameLength > MAX_PATH - strlenW(DotCoInstallers) - 1)
5304 goto cleanup;
5305 lstrcatW(SectionName, DotCoInstallers);
5306
5307 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5308
5309 /* Open/Create driver key information */
5310#if _WIN32_WINNT >= 0x502
5311 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_READ | KEY_WRITE);
5312#else
5313 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_ALL_ACCESS);
5314#endif
5316#if _WIN32_WINNT >= 0x502
5318#else
5320#endif
5322 goto cleanup;
5323
5324 /* Install .CoInstallers section */
5325 DoAction = SPINST_REGISTRY;
5327 {
5328 DoAction |= SPINST_FILES;
5330 if (!Context)
5331 goto cleanup;
5332 }
5334 SelectedDriver->InfFileDetails->hInf, SectionName,
5335 DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
5338 if (!Result)
5339 goto cleanup;
5340
5341 ret = TRUE;
5342
5343cleanup:
5344 if (Context)
5348 }
5349
5350 TRACE("Returning %d\n", ret);
5351 return ret;
5352}
5353
5354static BOOL
5357 OUT LPBOOL IsOEMLocation)
5358{
5359 PWCHAR last;
5360
5361 last = strrchrW(FullName, '\\');
5362 if (!last)
5363 {
5364 /* No directory specified */
5365 *IsOEMLocation = FALSE;
5366 }
5367 else
5368 {
5369 LPWSTR Windir;
5370 UINT ret;
5371
5372 Windir = MyMalloc((MAX_PATH + 1 + strlenW(InfDirectory)) * sizeof(WCHAR));
5373 if (!Windir)
5374 {
5376 return FALSE;
5377 }
5378
5380 if (ret == 0 || ret > MAX_PATH)
5381 {
5382 MyFree(Windir);
5384 return FALSE;
5385 }
5386 if (*Windir && Windir[strlenW(Windir) - 1] != '\\')
5387 strcatW(Windir, BackSlash);
5388 strcatW(Windir, InfDirectory);
5389
5390 if (strncmpiW(FullName, Windir, last - FullName) == 0)
5391 {
5392 /* The path is %SYSTEMROOT%\Inf */
5393 *IsOEMLocation = FALSE;
5394 }
5395 else
5396 {
5397 /* The file is in another place */
5398 *IsOEMLocation = TRUE;
5399 }
5400 MyFree(Windir);
5401 }
5402 return TRUE;
5403}
5404
5405/***********************************************************************
5406 * SetupDiInstallDevice (SETUPAPI.@)
5407 */
5412{
5413 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
5414 struct DeviceInfo *deviceInfo;
5416 struct DriverInfoElement *SelectedDriver;
5418 WCHAR SectionName[MAX_PATH];
5419 WCHAR Buffer[32];
5420 DWORD SectionNameLength = 0;
5421 BOOL Result = FALSE;
5422 ULONG DoAction;
5424 LPWSTR pSectionName = NULL;
5425 WCHAR ClassName[MAX_CLASS_NAME_LEN];
5427 LPWSTR lpGuidString = NULL, lpFullGuidString = NULL;
5428 BOOL RebootRequired = FALSE;
5430 BOOL NeedtoCopyFile;
5431 LARGE_INTEGER fullVersion;
5432 LONG rc;
5433 PVOID Context = NULL;
5434 BOOL ret = FALSE; /* Return value */
5435
5437
5438 if (!DeviceInfoSet)
5442 else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
5444 else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
5446 else
5447 Result = TRUE;
5448
5449 if (!Result)
5450 {
5451 /* One parameter is bad */
5452 goto cleanup;
5453 }
5454
5455 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
5457 if (!Result)
5458 goto cleanup;
5459
5460 if (InstallParams.FlagsEx & DI_FLAGSEX_SETFAILEDINSTALL)
5461 {
5462 /* Set FAILEDINSTALL in ConfigFlags registry value */
5463 DWORD ConfigFlags, regType;
5468 &regType,
5469 (PBYTE)&ConfigFlags,
5470 sizeof(ConfigFlags),
5471 NULL);
5472 if (!Result || regType != REG_DWORD)
5473 {
5475 goto cleanup;
5476 }
5477 ConfigFlags |= CONFIGFLAG_FAILEDINSTALL;
5482 (PBYTE)&ConfigFlags,
5483 sizeof(ConfigFlags));
5484 if (!Result)
5485 {
5487 goto cleanup;
5488 }
5489
5490 ret = TRUE;
5491 goto cleanup;
5492 }
5493
5494 SelectedDriver = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
5495 if (SelectedDriver == NULL)
5496 {
5498 goto cleanup;
5499 }
5500
5501 FileTimeToSystemTime(&SelectedDriver->Info.DriverDate, &DriverDate);
5502
5504 SelectedDriver->InfFileDetails->hInf,
5505 SelectedDriver->Details.SectionName,
5506 SectionName, MAX_PATH, &SectionNameLength, NULL);
5507 if (!Result || SectionNameLength > MAX_PATH - strlenW(DotServices))
5508 goto cleanup;
5509 pSectionName = &SectionName[strlenW(SectionName)];
5510
5511 /* Get information from [Version] section */
5513 goto cleanup;
5514 /* Format ClassGuid to a string */
5515 if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
5516 goto cleanup;
5517 RequiredSize = lstrlenW(lpGuidString);
5518 lpFullGuidString = HeapAlloc(GetProcessHeap(), 0, (RequiredSize + 3) * sizeof(WCHAR));
5519 if (!lpFullGuidString)
5520 {
5522 goto cleanup;
5523 }
5524 lpFullGuidString[0] = '{';
5525 memcpy(&lpFullGuidString[1], lpGuidString, RequiredSize * sizeof(WCHAR));
5526 lpFullGuidString[RequiredSize + 1] = '}';
5527 lpFullGuidString[RequiredSize + 2] = '\0';
5528
5529 /* Copy .inf file to Inf\ directory (if needed) */
5530 Result = InfIsFromOEMLocation(SelectedDriver->Details.InfFileName, &NeedtoCopyFile);
5531 if (!Result)
5532 goto cleanup;
5533 if (NeedtoCopyFile)
5534 {
5535 WCHAR NewFileName[MAX_PATH];
5536 struct InfFileDetails *newInfFileDetails;
5538 SelectedDriver->Details.InfFileName,
5539 NULL,
5540 SPOST_NONE,
5542 NewFileName, MAX_PATH,
5543 NULL,
5544 NULL);
5546 goto cleanup;
5547 /* Create a new struct InfFileDetails, and set it to
5548 * SelectedDriver->InfFileDetails, to release use of
5549 * current InfFile */
5550 newInfFileDetails = CreateInfFileDetails(NewFileName);
5551 if (!newInfFileDetails)
5552 goto cleanup;
5553 DereferenceInfFile(SelectedDriver->InfFileDetails);
5554 SelectedDriver->InfFileDetails = newInfFileDetails;
5555 strcpyW(SelectedDriver->Details.InfFileName, NewFileName);
5556 }
5557
5558 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
5559
5560 /* Open/Create driver key information */
5561#if _WIN32_WINNT >= 0x502
5562 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_READ | KEY_WRITE);
5563#else
5564 hKey = SETUPDI_OpenDrvKey(set->HKLM, deviceInfo, KEY_ALL_ACCESS);
5565#endif
5567#if _WIN32_WINNT >= 0x502
5569#else
5571#endif
5573 goto cleanup;
5574
5575 /* Install main section */
5576 DoAction = 0;
5578 DoAction |= SPINST_REGISTRY;
5580 {
5581 DoAction |= SPINST_FILES;
5583 if (!Context)
5584 goto cleanup;
5585 }
5586 *pSectionName = '\0';
5588 SelectedDriver->InfFileDetails->hInf, SectionName,
5589 DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
5592 if (!Result)
5593 goto cleanup;
5596
5597 /* Write information to driver key */
5598 *pSectionName = UNICODE_NULL;
5599 memcpy(&fullVersion, &SelectedDriver->Info.DriverVersion, sizeof(LARGE_INTEGER));
5600 TRACE("Write information to driver key\n");
5601 TRACE("DriverDate : '%u-%u-%u'\n", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
5602 TRACE("DriverDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
5603 TRACE("DriverVersion : '%ld.%ld.%lu.%ld'\n", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
5604 TRACE("InfPath : '%s'\n", debugstr_w(SelectedDriver->InfFileDetails->FileName));
5605 TRACE("InfSection : '%s'\n", debugstr_w(SelectedDriver->Details.SectionName));
5606 TRACE("InfSectionExt : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)]));
5607 TRACE("MatchingDeviceId: '%s'\n", debugstr_w(SelectedDriver->MatchingId));
5608 TRACE("ProviderName : '%s'\n", debugstr_w(SelectedDriver->Info.ProviderName));
5609 sprintfW(Buffer, DateFormat, DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
5610 rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
5611 if (rc == ERROR_SUCCESS)
5612 rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE_DATA, 0, REG_BINARY, (const BYTE *)&SelectedDriver->Info.DriverDate, sizeof(FILETIME));
5613 if (rc == ERROR_SUCCESS)
5614 rc = RegSetValueExW(hKey, REGSTR_VAL_DRVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
5615 if (rc == ERROR_SUCCESS)
5616 {
5617 sprintfW(Buffer, VersionFormat, fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
5618 rc = RegSetValueExW(hKey, REGSTR_DRIVER_VERSION, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
5619 }
5620 if (rc == ERROR_SUCCESS)
5621 rc = RegSetValueExW(hKey, REGSTR_VAL_INFPATH, 0, REG_SZ, (const BYTE *)SelectedDriver->InfFileDetails->FileName, (strlenW(SelectedDriver->InfFileDetails->FileName) + 1) * sizeof(WCHAR));
5622 if (rc == ERROR_SUCCESS)
5623 rc = RegSetValueExW(hKey, REGSTR_VAL_INFSECTION, 0, REG_SZ, (const BYTE *)SelectedDriver->Details.SectionName, (strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
5624 if (rc == ERROR_SUCCESS)
5625 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));
5626 if (rc == ERROR_SUCCESS)
5627 rc = RegSetValueExW(hKey, REGSTR_VAL_MATCHINGDEVID, 0, REG_SZ, (const BYTE *)SelectedDriver->MatchingId, (strlenW(SelectedDriver->MatchingId) + 1) * sizeof(WCHAR));
5628 if (rc == ERROR_SUCCESS)
5629 rc = RegSetValueExW(hKey, REGSTR_VAL_PROVIDER_NAME, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.ProviderName, (strlenW(SelectedDriver->Info.ProviderName) + 1) * sizeof(WCHAR));
5630 if (rc != ERROR_SUCCESS)
5631 {
5632 SetLastError(rc);
5633 goto cleanup;
5634 }
5637
5638 /* FIXME: Process .LogConfigOverride section */
5639
5640 /* Install .Services section */
5641 strcpyW(pSectionName, DotServices);
5643 SelectedDriver->InfFileDetails->hInf,
5644 SectionName,
5645 0,
5648 NULL,
5649 NULL);
5650 if (!Result)
5651 {
5653 goto cleanup;
5655 }
5657 RebootRequired = TRUE;
5658
5659 /* Open device registry key */
5662 goto cleanup;
5663
5664 /* Install .HW section */
5665 DoAction = 0;
5667 DoAction |= SPINST_REGISTRY;
5668 strcpyW(pSectionName, DotHW);
5670 SelectedDriver->InfFileDetails->hInf, SectionName,
5671 DoAction, hKey, NULL, 0,
5672 NULL, NULL,
5674 if (!Result)
5675 goto cleanup;
5676
5677 /* Write information to enum key */
5678 TRACE("Write information to enum key\n");
5679 TRACE("Class : '%s'\n", debugstr_w(ClassName));
5680 TRACE("ClassGUID : '%s'\n", debugstr_w(lpFullGuidString));
5681 TRACE("DeviceDesc : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
5682 TRACE("Mfg : '%s'\n", debugstr_w(SelectedDriver->Info.MfgName));
5683 rc = RegSetValueExW(hKey, REGSTR_VAL_CLASS, 0, REG_SZ, (const BYTE *)ClassName, (strlenW(ClassName) + 1) * sizeof(WCHAR));
5684 if (rc == ERROR_SUCCESS)
5685 rc = RegSetValueExW(hKey, REGSTR_VAL_CLASSGUID, 0, REG_SZ, (const BYTE *)lpFullGuidString, (strlenW(lpFullGuidString) + 1) * sizeof(WCHAR));
5686 if (rc == ERROR_SUCCESS)
5687 rc = RegSetValueExW(hKey, REGSTR_VAL_DEVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
5688 if (rc == ERROR_SUCCESS)
5689 rc = RegSetValueExW(hKey, REGSTR_VAL_MFG, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.MfgName, (strlenW(SelectedDriver->Info.MfgName) + 1) * sizeof(WCHAR));
5690 if (rc != ERROR_SUCCESS)
5691 {
5692 SetLastError(rc);
5693 goto cleanup;
5694 }
5695
5696 /* Start the device */
5697 if (!RebootRequired && !(InstallParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG)))
5699 else
5700 ret = TRUE;
5701
5702cleanup:
5703 /* End of installation */
5706 if (lpGuidString)
5707 RpcStringFreeW(&lpGuidString);
5708 HeapFree(GetProcessHeap(), 0, lpFullGuidString);
5709 if (Context)
5711 TRACE("Returning %d\n", ret);
5712 return ret;
5713}
5714
5716{
5717 HKEY enumKey, key = INVALID_HANDLE_VALUE;
5718 LONG l;
5719
5721 if (!l)
5722 {
5723 l = RegCreateKeyExW(enumKey, devInfo->instanceId, 0, NULL, REG_OPTION_NON_VOLATILE, samDesired, NULL, &key, NULL);
5724 RegCloseKey(enumKey);
5725 }
5726 if (l)
5727 SetLastError(l);
5728 return key;
5729}
5730
5732{
5734 LPWSTR lpGuidString = NULL;
5735 LPWSTR DriverKey = NULL; /* {GUID}\Index */
5736 LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
5737 DWORD Index; /* Index used in the DriverKey name */
5738 DWORD dwSize;
5740 DWORD rc;
5741 HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
5742 HKEY hEnumKey = NULL;
5744 HKEY hDeviceKey = INVALID_HANDLE_VALUE;
5745 HKEY hKey = NULL;
5746
5747 /* Open device key, to read Driver value */
5748 hDeviceKey = SETUPDI_OpenDevKey(RootKey, devInfo, KEY_QUERY_VALUE | KEY_SET_VALUE);
5749 if (hDeviceKey == INVALID_HANDLE_VALUE)
5750 goto cleanup;
5751
5753 if (rc != ERROR_SUCCESS)
5754 {
5755 SetLastError(rc);
5756 goto cleanup;
5757 }
5758
5759 rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, NULL, &dwSize);
5760 if (rc != ERROR_SUCCESS)
5761 {
5762 /* Create a new driver key */
5763
5764 if (UuidToStringW(ClassGuid, &lpGuidString) != RPC_S_OK)
5765 goto cleanup;
5766
5767 /* The driver key is in \System\CurrentControlSet\Control\Class\{GUID}\Index */
5768 DriverKey = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
5769 if (!DriverKey)
5770 {
5772 goto cleanup;
5773 }
5774
5775 DriverKey[0] = '{';
5776 strcpyW(&DriverKey[1], lpGuidString);
5777 pDeviceInstance = &DriverKey[strlenW(DriverKey)];
5778 *pDeviceInstance++ = '}';
5779 *pDeviceInstance++ = '\\';
5780
5781 /* Try all values for Index between 0 and 9999 */
5782 Index = 0;
5783 while (Index <= 9999)
5784 {
5785 sprintfW(pDeviceInstance, InstanceKeyFormat, Index);
5787 DriverKey,
5788 0,
5789 NULL,
5791#if _WIN32_WINNT >= 0x502
5793#else
5795#endif
5796 NULL,
5797 &hKey,
5798 &Disposition);
5799 if (rc != ERROR_SUCCESS)
5800 {
5801 SetLastError(rc);
5802 goto cleanup;
5803 }
5805 break;
5807 hKey = NULL;
5808 Index++;
5809 }
5810
5811 if (Index > 9999)
5812 {
5813 /* Unable to create more than 9999 devices within the same class */
5815 goto cleanup;
5816 }
5817
5818 /* Write the new Driver value */
5819 rc = RegSetValueExW(hDeviceKey, REGSTR_VAL_DRIVER, 0, REG_SZ, (const BYTE *)DriverKey, (strlenW(DriverKey) + 1) * sizeof(WCHAR));
5820 if (rc != ERROR_SUCCESS)
5821 {
5822 SetLastError(rc);
5823 goto cleanup;
5824 }
5825 }
5826 else
5827 {
5828 /* Open the existing driver key */
5829
5830 DriverKey = HeapAlloc(GetProcessHeap(), 0, dwSize);
5831 if (!DriverKey)
5832 {
5834 goto cleanup;
5835 }
5836
5837 rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, (LPBYTE)DriverKey, &dwSize);
5838 if (rc != ERROR_SUCCESS)
5839 {
5840 SetLastError(rc);
5841 goto cleanup;
5842 }
5843
5845 DriverKey,
5846 0,
5847 NULL,
5849#if _WIN32_WINNT >= 0x502
5851#else
5853#endif
5854 NULL,
5855 &hKey,
5856 &Disposition);
5857 if (rc != ERROR_SUCCESS)
5858 {
5859 SetLastError(rc);
5860 goto cleanup;
5861 }
5862 }
5863
5864 key = hKey;
5865
5866cleanup:
5867 if (lpGuidString)
5868 RpcStringFreeW(&lpGuidString);
5869 HeapFree(GetProcessHeap(), 0, DriverKey);
5870 if (hHWProfileKey != INVALID_HANDLE_VALUE)
5871 RegCloseKey(hHWProfileKey);
5872 if (hEnumKey != NULL)
5874 if (hClassKey != NULL)
5876 if (hDeviceKey != INVALID_HANDLE_VALUE)
5877 RegCloseKey(hDeviceKey);
5878 if (hKey != NULL && hKey != key)
5880
5881 TRACE("Returning 0x%p\n", hKey);
5882 return hKey;
5883}
5884
5886{
5887 HKEY enumKey, key = INVALID_HANDLE_VALUE;
5888 LONG l;
5889
5891 if (!l)
5892 {
5893 l = RegOpenKeyExW(enumKey, devInfo->instanceId, 0, samDesired, &key);
5894 RegCloseKey(enumKey);
5895 }
5896 if (l)
5897 SetLastError(l);
5898 return key;
5899}
5900
5902{
5903 LPWSTR DriverKey = NULL;
5904 DWORD dwLength = 0;
5905 DWORD dwRegType;
5906 DWORD rc;
5907 HKEY hEnumKey = NULL;
5908 HKEY hKey = NULL;
5910
5913 goto cleanup;
5914 /* Read the 'Driver' key */
5916 if (rc != ERROR_SUCCESS)
5917 {
5918 SetLastError(rc);
5919 goto cleanup;
5920 }
5921 else if (dwRegType != REG_SZ)
5922 {
5924 goto cleanup;
5925 }
5926 DriverKey = HeapAlloc(GetProcessHeap(), 0, dwLength);
5927 if (!DriverKey)
5928 {
5930 goto cleanup;
5931 }
5932 rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
5933 if (rc != ERROR_SUCCESS)
5934 {
5935 SetLastError(rc);
5936 goto cleanup;
5937 }
5939 hKey = NULL;
5940 /* Need to open the driver key */
5941 rc = RegOpenKeyExW(
5942 RootKey,
5944 0, /* Options */
5946 &hEnumKey);
5947 if (rc != ERROR_SUCCESS)
5948 {
5949 SetLastError(rc);
5950 goto cleanup;
5951 }
5952 rc = RegOpenKeyExW(
5953 hEnumKey,
5954 DriverKey,
5955 0, /* Options */
5956 samDesired,
5957 &hKey);
5958 if (rc != ERROR_SUCCESS)
5959 {
5960 SetLastError(rc);
5961 goto cleanup;
5962 }
5963 key = hKey;
5964
5965cleanup:
5966 if (hEnumKey != NULL)
5968 if (hKey != NULL && hKey != key)
5970 if (DriverKey)
5971 HeapFree(GetProcessHeap(), 0, DriverKey);
5972 return key;
5973}
5974
5975/***********************************************************************
5976 * SetupDiOpenDevRegKey (SETUPAPI.@)
5977 */
5981 DWORD Scope,
5982 DWORD HwProfile,
5983 DWORD KeyType,
5984 REGSAM samDesired)
5985{
5987 struct DeviceInfo *devInfo;
5989 HKEY RootKey;
5990
5991 TRACE("%s(%p %p %d %d %d %x)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
5992 Scope, HwProfile, KeyType, samDesired);
5993
5995 {
5997 return INVALID_HANDLE_VALUE;
5998 }
5999 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
6000 {
6002 return INVALID_HANDLE_VALUE;
6003 }
6006 {
6008 return INVALID_HANDLE_VALUE;
6009 }
6010 if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
6011 {
6013 return INVALID_HANDLE_VALUE;
6014 }
6015 if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
6016 {
6018 return INVALID_HANDLE_VALUE;
6019 }
6020 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
6021 if (devInfo->set != set)
6022 {
6024 return INVALID_HANDLE_VALUE;
6025 }
6026 if (Scope != DICS_FLAG_GLOBAL)
6027 {
6028 RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
6030 return INVALID_HANDLE_VALUE;
6031 }
6032 else
6033 RootKey = set->HKLM;
6034 switch (KeyType)
6035 {
6036 case DIREG_DEV:
6037 key = SETUPDI_OpenDevKey(RootKey, devInfo, samDesired);
6038 if (Scope == DICS_FLAG_GLOBAL)
6039 {
6040 LONG rc;
6041 HKEY hTempKey = key;
6042 rc = RegOpenKeyExW(hTempKey,
6043 L"Device Parameters",
6044 0,
6045 samDesired,
6046 &key);
6047 if (rc == ERROR_SUCCESS)
6048 RegCloseKey(hTempKey);
6049 }
6050 break;
6051 case DIREG_DRV:
6052 key = SETUPDI_OpenDrvKey(RootKey, devInfo, samDesired);
6053 break;
6054 default:
6055 WARN("unknown KeyType %d\n", KeyType);
6056 }
6057 if (RootKey != set->HKLM)
6059 return key;
6060}
6061
6063{
6064 FIXME("\n");
6065 return FALSE;
6066}
6067
6069{
6070 FIXME("\n");
6071 return FALSE;
6072}
6073
6074/***********************************************************************
6075 * SetupDiDeleteDevRegKey (SETUPAPI.@)
6076 */
6080 DWORD Scope,
6081 DWORD HwProfile,
6082 DWORD KeyType)
6083{
6084 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
6085 struct DeviceInfo *devInfo;
6086 BOOL ret = FALSE;
6087 HKEY RootKey;
6088
6089 TRACE("%s(%p %p %d %d %d)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData, Scope, HwProfile,
6090 KeyType);
6091
6093 {
6095 return FALSE;
6096 }
6097 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
6098 {
6100 return FALSE;
6101 }
6104 {
6106 return FALSE;
6107 }
6108 if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
6109 {
6111 return FALSE;
6112 }
6113 if (KeyType != DIREG_DEV && KeyType != DIREG_DRV && KeyType != DIREG_BOTH)
6114 {
6116 return FALSE;
6117 }
6118 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
6119 if (devInfo->set != set)
6120 {
6122 return FALSE;
6123 }
6124 if (Scope != DICS_FLAG_GLOBAL)
6125 {
6126 RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
6128 return FALSE;
6129 }
6130 else
6131 RootKey = set->HKLM;
6132 switch (KeyType)
6133 {
6134 case DIREG_DEV:
6135 ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
6136 break;
6137 case DIREG_DRV:
6138 ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
6139 break;
6140 case DIREG_BOTH:
6141 ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
6142 if (ret)
6143 ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
6144 break;
6145 default:
6146 WARN("unknown KeyType %d\n", KeyType);
6147 }
6148 if (RootKey != set->HKLM)
6150 return ret;
6151}
6152
6153/***********************************************************************
6154 * SetupDiRestartDevices (SETUPAPI.@)
6155 */
6156BOOL
6157WINAPI
6161{
6162 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
6163 struct DeviceInfo *devInfo;
6164 CONFIGRET cr;
6165
6167
6169 {
6171 return FALSE;
6172 }
6173 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
6174 {
6176 return FALSE;
6177 }
6178
6181 {
6183 return FALSE;
6184 }
6185
6186 devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
6187
6188 cr = CM_Enable_DevNode_Ex(devInfo->dnDevInst, 0, set->hMachine);
6189 if (cr != CR_SUCCESS)
6190 {
6192 return FALSE;
6193 }
6194
6195 return TRUE;
6196}
6197
6198/***********************************************************************
6199 * SetupDiGetCustomDevicePropertyA (SETUPAPI.@)
6200 */
6201BOOL
6202WINAPI
6206 IN PCSTR CustomPropertyName,
6207 IN DWORD Flags,
6212{
6213 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
6214 struct DeviceInfo *deviceInfo;
6215 DWORD ConfigFlags = 0, PropertySize;
6216 CONFIGRET cr;
6217
6218 TRACE("%s(%p %p %s 0x%lx %p %p %lu %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
6220
6222 {
6224 return FALSE;
6225 }
6226 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
6227 {
6229 return FALSE;
6230 }
6233 {
6235 return FALSE;
6236 }
6238 {
6240 return FALSE;
6241 }
6242
6243 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
6244 if (deviceInfo->set != set)
6245 {
6247 return FALSE;
6248 }
6249
6251 {
6252 ConfigFlags |= CM_CUSTOMDEVPROP_MERGE_MULTISZ;
6253 }
6254
6255 PropertySize = PropertyBufferSize;
6257 CustomPropertyName,
6260 &PropertySize,
6261 ConfigFlags,
6262 set->hMachine);
6263 if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL))
6264 {
6265 if (RequiredSize)
6266 *RequiredSize = PropertySize;
6267 }
6268
6269 if (cr != CR_SUCCESS)
6270 {
6272 return FALSE;
6273 }
6274
6275 return TRUE;
6276}
6277
6278/***********************************************************************
6279 * SetupDiGetCustomDevicePropertyW (SETUPAPI.@)
6280 */
6281BOOL
6282WINAPI
6286 IN PCWSTR CustomPropertyName,
6287 IN DWORD Flags,
6292{
6293 struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
6294 struct DeviceInfo *deviceInfo;
6295 DWORD ConfigFlags = 0, PropertySize;
6296 CONFIGRET cr;
6297
6298 TRACE("%s(%p %p %s 0x%lx %p %p %lu %p)\n", __FUNCTION__, DeviceInfoSet, DeviceInfoData,
6300
6302 {
6304 return FALSE;
6305 }
6306 if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
6307 {
6309 return FALSE;
6310 }
6313 {
6315 return FALSE;
6316 }
6318 {
6320 return FALSE;
6321 }
6322
6323 deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
6324 if (deviceInfo->set != set)
6325 {
6327 return FALSE;
6328 }
6329
6331 {
6332 ConfigFlags |= CM_CUSTOMDEVPROP_MERGE_MULTISZ;
6333 }
6334
6335 PropertySize = PropertyBufferSize;
6337 CustomPropertyName,
6340 &PropertySize,
6341 ConfigFlags,
6342 set->hMachine);
6343 if ((cr == CR_SUCCESS) || (cr == CR_BUFFER_SMALL))
6344 {
6345 if (RequiredSize)
6346 *RequiredSize = PropertySize;
6347 }
6348
6349 if (cr != CR_SUCCESS)
6350 {
6352 return FALSE;
6353 }
6354
6355 return TRUE;
6356}
#define _WIN32_WINNT
Definition: precomp.h:14
static const WCHAR nameW[]
Definition: main.c:49
HKEY hClassKey
Definition: umpnpmgr.c:45
static HANDLE hEnumKey
Definition: devinst.c:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#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
#define CM_Get_DevInst_Custom_Property_ExA
Definition: cfgmgr32.h:1788
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_CUSTOMDEVPROP_MERGE_MULTISZ
Definition: cfgmgr32.h:835
#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 CM_Get_DevInst_Custom_Property_ExW
Definition: cfgmgr32.h:1787
#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:3572
CONFIGRET WINAPI CM_Disconnect_Machine(_In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:1892
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:6454
CONFIGRET WINAPI CM_Get_Parent_Ex(_Out_ PDEVINST pdnDevInst, _In_ DEVINST dnDevInst, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:5480
CONFIGRET WINAPI CM_Connect_MachineW(_In_opt_ PCWSTR UNCServerName, _Out_ PHMACHINE phMachine)
Definition: cfgmgr.c:1270
CONFIGRET WINAPI CM_Disable_DevNode_Ex(_In_ DEVINST dnDevInst, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:1826
CONFIGRET WINAPI CM_Locate_DevNode_ExW(_Out_ PDEVINST pdnDevInst, _In_opt_ DEVINSTID_W pDeviceID, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:6077
CONFIGRET WINAPI CM_Enumerate_Classes_Ex(_In_ ULONG ulClassIndex, _Out_ LPGUID ClassGuid, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:2094
CONFIGRET WINAPI CM_Enable_DevNode_Ex(_In_ DEVINST dnDevInst, _In_ ULONG ulFlags, _In_opt_ HMACHINE hMachine)
Definition: cfgmgr.c:2012
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:2316
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
GUID guid
Definition: version.c:147
static const WCHAR sizeW[]
Definition: editor.c:79
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
#define EINVAL
Definition: errno.h:44
#define ERANGE
Definition: errno.h:55
#define errno
Definition: errno.h:120
#define ULONG_MAX
Definition: limits.h:31
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:5355
BOOL WINAPI SetupDiSetClassInstallParamsA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_CLASSINSTALL_HEADER ClassInstallParams, DWORD ClassInstallParamsSize)
Definition: devinst.c:4046
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:4789
#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:5255
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:6158
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:4020
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:3183
static HKEY OpenHardwareProfileKey(IN HKEY HKLM, IN DWORD HwProfile, IN DWORD samDesired)
Definition: devinst.c:4679
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:3527
static BOOL SETUPDI_DeleteDrvKey(HKEY RootKey, struct DeviceInfo *devInfo)
Definition: devinst.c:6068
BOOL WINAPI SetupDiSetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4602
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:3514
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:4495
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:4068
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:2772
HKEY SETUPDI_CreateDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, UUID *ClassGuid, REGSAM samDesired)
Definition: devinst.c:5731
HKEY SETUPDI_OpenDevKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
Definition: devinst.c:5885
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:2824
BOOL WINAPI SetupDiSelectDevice(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: devinst.c:5241
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:3478
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:3649
BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
Definition: devinst.c:3268
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
BOOL WINAPI SetupDiGetCustomDevicePropertyA(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, IN PCSTR CustomPropertyName, IN DWORD Flags, OUT PDWORD PropertyRegDataType OPTIONAL, OUT PBYTE PropertyBuffer, IN DWORD PropertyBufferSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: devinst.c:6203
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:6077
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:3402
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:6062
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:4756
BOOL WINAPI SetupDiChangeState(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5115
BOOL WINAPI SetupDiInstallDevice(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5409
BOOL WINAPI SetupDiOpenDeviceInterfaceW(HDEVINFO DeviceInfoSet, PCWSTR DevicePath, DWORD OpenFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
Definition: devinst.c:3805
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:5901
#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:4818
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:5064
BOOL WINAPI SetupDiSetDeviceInstallParamsA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
Definition: devinst.c:4642
HKEY WINAPI SetupDiOpenDevRegKey(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Scope, DWORD HwProfile, DWORD KeyType, REGSAM samDesired)
Definition: devinst.c:5978
static BOOL IsDeviceInfoInDeviceInfoSet(struct DeviceInfoSet *deviceInfoSet, struct DeviceInfo *deviceInfo)
Definition: devinst.c:4734
static BOOL WINAPI IntSetupDiRegisterDeviceInfo(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4058
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:3496
HKEY SETUP_CreateClassKey(HINF hInf)
Definition: devinst.c:3562
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:5017
BOOL WINAPI SetupDiSetSelectedDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:4985
BOOL WINAPI SetupDiGetCustomDevicePropertyW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, IN PCWSTR CustomPropertyName, IN DWORD Flags, OUT PDWORD PropertyRegDataType OPTIONAL, OUT PBYTE PropertyBuffer, IN DWORD PropertyBufferSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: devinst.c:6283
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:2961
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:3055
static struct PropertyMapEntry PropertyMap[]
Definition: devinst.c:3142
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:4947
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:5715
BOOL WINAPI SetupDiGetDeviceInstallParamsA(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
Definition: devinst.c:4422
static const WCHAR DotHW[]
Definition: devinst.c:30
HKEY WINAPI SetupDiOpenClassRegKey(const GUID *ClassGuid, REGSAM samDesired)
Definition: devinst.c:3662
static BOOL StopDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: devinst.c:5088
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:4543
BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
Definition: devinst.c:2937
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:3706
HKEY WINAPI SetupDiOpenClassRegKeyExA(const GUID *ClassGuid, REGSAM samDesired, DWORD Flags, PCSTR MachineName, PVOID Reserved)
Definition: devinst.c:3674
HDEVINFO WINAPI SetupDiCreateDeviceInfoList(const GUID *ClassGuid, HWND hwndParent)
Definition: devinst.c:1205
BOOL WINAPI SetupDiGetDeviceInfoListClass(IN HDEVINFO DeviceInfoSet, OUT LPGUID ClassGuid)
Definition: devinst.c:4465
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:1947
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:1911
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:1330
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:2375
BOOL WINAPI SetupInstallServicesFromInfSectionExW(_In_ HINF InfHandle, _In_ PCWSTR SectionName, _In_ DWORD Flags, _In_opt_ HDEVINFO DeviceInfoSet, _In_opt_ PSP_DEVINFO_DATA DeviceInfoData, _Reserved_ PVOID Reserved1, _Reserved_ PVOID Reserved2)
Definition: install.c:2118
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:388
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:2400
BOOL WINAPI SetupDiGetINFClassW(IN PCWSTR InfName, OUT LPGUID ClassGuid, OUT PWSTR ClassName, IN DWORD ClassNameSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2323
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1763
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
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
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
ULONG MajorVersion
Definition: ros_glue.cpp:4
ULONG MinorVersion
Definition: ros_glue.cpp:5
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_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:90
#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
#define ZeroMemory
Definition: minwinbase.h:31
#define CopyMemory
Definition: minwinbase.h:29
BOOL * LPBOOL
Definition: minwindef.h:138
#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:770
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
_In_ PIOMMU_DEVICE_PATH DevicePath
Definition: haltypes.h:1823
#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:3051
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:238
#define VER_PLATFORM_WIN32_WINDOWS
Definition: rtltypes.h:237
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define REG_BINARY
Definition: nt_native.h:1499
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1021
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1060
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1087
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1022
#define BOOL
Definition: nt_native.h:43
#define KEY_WRITE
Definition: nt_native.h:1034
#define READ_CONTROL
Definition: nt_native.h:58
#define DWORD
Definition: nt_native.h:44
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define KEY_SET_VALUE
Definition: nt_native.h:1020
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define CONST
Definition: pedump.c:81
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
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:573
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:181
RPC_STATUS WINAPI UuidFromStringW(RPC_WSTR s, UUID *uuid)
Definition: rpcrt4_main.c:655
@ Reserved2
Definition: sacdrv.h:1470
@ Reserved1
Definition: sacdrv.h:1464
#define REG_DWORD
Definition: sdbapi.c:615
wcscpy
static PMEMKEY RootKey
Definition: registry.c:55
#define SPINST_BITREG
Definition: setupapi.h:594
#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:596
#define ERROR_DI_POSTPROCESSING_REQUIRED
Definition: setupapi.h:335
#define DIF_SELECTDEVICE
Definition: setupapi.h:121
#define ERROR_NO_ASSOCIATED_CLASS
Definition: setupapi.h:297
#define DI_NEEDRESTART
Definition: setupapi.h:53
#define SPDRP_MAXIMUM_PROPERTY
Definition: setupapi.h:543
#define SP_MAX_MACHINENAME_LENGTH
Definition: setupapi.h:27
#define ERROR_INVALID_DEVINST_NAME
Definition: setupapi.h:302
#define ERROR_INVALID_MACHINENAME
Definition: setupapi.h:329
#define DI_DIDCOMPAT
Definition: setupapi.h:50
#define SP_COPY_NOOVERWRITE
Definition: setupapi.h:481
#define ERROR_DEVINST_ALREADY_EXISTS
Definition: setupapi.h:304
_In_ DWORD _Out_ PDWORD _In_opt_ PCSTR MachineName
Definition: setupapi.h:1294
#define DI_NODI_DEFAULTACTION
Definition: setupapi.h:67
#define SetupInstallFromInfSection
Definition: setupapi.h:2646
#define ERROR_INVALID_CLASS
Definition: setupapi.h:303
#define DIBCI_NODISPLAYCLASS
Definition: setupapi.h:109
#define DIF_NEWDEVICEWIZARD_PRESELECT
Definition: setupapi.h:146
#define DI_NOVCP
Definition: setupapi.h:49
_In_opt_ PSP_DEVINFO_DATA _In_ DWORD ClassInstallParamsSize
Definition: setupapi.h:1531
#define SPINST_PROFILEITEMS
Definition: setupapi.h:597
_In_ DWORD _Out_opt_ PDWORD PropertyRegDataType
Definition: setupapi.h:1552
#define DIF_REGISTERDEVICE
Definition: setupapi.h:145
#define DI_CLASSINSTALLPARAMS
Definition: setupapi.h:66
#define SPDRP_DEVICEDESC
Definition: setupapi.h:508
#define DIF_REMOVE
Definition: setupapi.h:125
#define ERROR_INVALID_REG_PROPERTY
Definition: setupapi.h:306
#define DIF_INSTALLDEVICEFILES
Definition: setupapi.h:141
#define SPINST_INI2REG
Definition: setupapi.h:592
_In_ DWORD ClassGuidListSize
Definition: setupapi.h:1282
#define DIF_ADDREMOTEPROPERTYPAGE_ADVANCED
Definition: setupapi.h:160
#define LINE_LEN
Definition: setupapi.h:20
#define ERROR_NO_SUCH_DEVINST
Definition: setupapi.h:308
#define ERROR_NO_DEVICE_SELECTED
Definition: setupapi.h:314
#define DI_QUIETINSTALL
Definition: setupapi.h:68
#define SPINST_REGSVR
Definition: setupapi.h:595
#define DI_RESOURCEPAGE_ADDED
Definition: setupapi.h:59
#define SPOST_NONE
Definition: setupapi.h:610
#define DICS_DISABLE
Definition: setupapi.h:114
#define DIOCR_INTERFACE
Definition: setupapi.h:178
SP_ALTPLATFORM_INFO_V1 SP_ALTPLATFORM_INFO
Definition: setupapi.h:731
#define DICS_PROPCHANGE
Definition: setupapi.h:116
#define DIF_DETECT
Definition: setupapi.h:135
#define DIGCF_DEVICEINTERFACE
Definition: setupapi.h:175
#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:182
#define DI_ENUMSINGLEINF
Definition: setupapi.h:62
#define SPINST_INIFILES
Definition: setupapi.h:590
#define DIF_NEWDEVICEWIZARD_SELECT
Definition: setupapi.h:147
#define SPINST_REGISTRY
Definition: setupapi.h:591
#define ERROR_SECTION_NOT_FOUND
Definition: setupapi.h:294
#define DIREG_DRV
Definition: setupapi.h:183
#define ERROR_NO_DRIVER_SELECTED
Definition: setupapi.h:300
#define DIF_REGISTER_COINSTALLERS
Definition: setupapi.h:154
#define DI_DRIVERPAGE_ADDED
Definition: setupapi.h:71
#define DIF_INSTALLINTERFACES
Definition: setupapi.h:152
#define DIOD_INHERIT_CLASSDRVS
Definition: setupapi.h:180
#define DICS_ENABLE
Definition: setupapi.h:112
#define DIGCF_ALLCLASSES
Definition: setupapi.h:173
struct _SP_DEVINSTALL_PARAMS_W SP_DEVINSTALL_PARAMS_W
#define DICS_FLAG_CONFIGSPECIFIC
Definition: setupapi.h:115
#define DIGCF_PROFILE
Definition: setupapi.h:174
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1529
#define ERROR_DI_DO_DEFAULT
Definition: setupapi.h:311
#define DIOD_CANCEL_REMOVE
Definition: setupapi.h:181
#define ERROR_CLASS_MISMATCH
Definition: setupapi.h:298
#define DIF_NEWDEVICEWIZARD_PREANALYZE
Definition: setupapi.h:148
#define DI_FLAGSEX_DIDINFOLIST
Definition: setupapi.h:80
#define DIF_UNREMOVE
Definition: setupapi.h:142
UINT DI_FUNCTION
Definition: setupapi.h:673
#define DICD_GENERATE_ID
Definition: setupapi.h:110
#define DIGCF_PRESENT
Definition: setupapi.h:172
#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:1554
#define SPRDI_FIND_DUPS
Definition: setupapi.h:624
#define DIOCR_INSTALLER
Definition: setupapi.h:177
struct _SP_DEVICE_INTERFACE_DETAIL_DATA_W * PSP_DEVICE_INTERFACE_DETAIL_DATA_W
#define SPINST_FILES
Definition: setupapi.h:593
#define DIF_INSTALLDEVICE
Definition: setupapi.h:122
#define DIBCI_NOINSTALLCLASS
Definition: setupapi.h:108
#define SPINT_ACTIVE
Definition: setupapi.h:583
#define DIF_ALLOW_INSTALL
Definition: setupapi.h:144
#define DIF_DESTROYPRIVATEDATA
Definition: setupapi.h:132
#define DI_PROPERTIES_CHANGE
Definition: setupapi.h:60
#define DI_FLAGSEX_ALLOWEXCLUDEDDRVS
Definition: setupapi.h:87
#define DIF_SELECTBESTCOMPATDRV
Definition: setupapi.h:143
#define SPDRP_CONFIGFLAGS
Definition: setupapi.h:518
#define DICS_FLAG_GLOBAL
Definition: setupapi.h:113
#define DIF_POWERMESSAGEWAKE
Definition: setupapi.h:159
DWORD(CALLBACK * PSP_DETSIG_CMPPROC)(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINFO_DATA, PVOID)
Definition: setupapi.h:1058
#define DIF_PROPERTYCHANGE
Definition: setupapi.h:138
#define DIF_ADDPROPERTYPAGE_ADVANCED
Definition: setupapi.h:155
#define SPDRP_PHYSICAL_DEVICE_OBJECT_NAME
Definition: setupapi.h:522
#define DICD_INHERIT_CLASSDRVS
Definition: setupapi.h:111
#define DIF_NEWDEVICEWIZARD_POSTANALYZE
Definition: setupapi.h:149
#define DI_DIDCLASS
Definition: setupapi.h:51
#define DIF_TROUBLESHOOTER
Definition: setupapi.h:158
#define DICUSTOMDEVPROP_MERGE_MULTISZ
Definition: setupapi.h:120
#define SP_COPY_NEWER
Definition: setupapi.h:479
#define DIREG_BOTH
Definition: setupapi.h:184
#define DI_DONOTCALLCONFIGMG
Definition: setupapi.h:63
#define DIF_NEWDEVICEWIZARD_FINISHINSTALL
Definition: setupapi.h:150
#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
_In_ PVOID Context
Definition: storport.h:2269
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:3139
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:852
WCHAR DevicePath[ANYSIZE_ARRAY]
Definition: setupapi.h:856
ULONG_PTR Reserved
Definition: setupapi.h:839
CHAR RemoteMachineName[SP_MAX_MACHINENAME_LENGTH]
Definition: setupapi.h:868
WCHAR RemoteMachineName[SP_MAX_MACHINENAME_LENGTH]
Definition: setupapi.h:874
ULONG_PTR ClassInstallReserved
Definition: setupapi.h:899
WCHAR DriverPath[MAX_PATH]
Definition: setupapi.h:901
WCHAR ProviderName[LINE_LEN]
Definition: setupapi.h:1019
WCHAR MfgName[LINE_LEN]
Definition: setupapi.h:1018
DWORDLONG DriverVersion
Definition: setupapi.h:1021
WCHAR Description[LINE_LEN]
Definition: setupapi.h:1017
WCHAR SectionName[LINE_LEN]
Definition: setupapi.h:1077
WCHAR InfFileName[MAX_PATH]
Definition: setupapi.h:1078
WORD wProcessorArchitecture
Definition: winbase.h:894
Definition: dsound.c:943
Definition: copy.c:22
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
#define OPTIONAL
Definition: typedefs.h:41
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
char * LPSTR
Definition: typedefs.h:51
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
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ CONST GUID _In_opt_ PCUNICODE_STRING ReferenceString
Definition: wdfdevice.h:3636
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID PropertyBuffer
Definition: wdfdevice.h:4443
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4445
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3281
_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
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define WINAPI
Definition: msvc.h:6
#define strncmpiW(s1, s2, n)
Definition: unicode.h:46
#define strcmpiW(s1, s2)
Definition: unicode.h:45
#define strlenW(s)
Definition: unicode.h:34
#define strrchrW(s, c)
Definition: unicode.h:41
#define strcatW(d, s)
Definition: unicode.h:36
#define strtoulW(s1, s2, b)
Definition: unicode.h:47
#define snprintfW
Definition: unicode.h:66
#define sprintfW
Definition: unicode.h:64
#define strcpyW(d, s)
Definition: unicode.h:35
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1448
#define ERROR_BAD_PATHNAME
Definition: winerror.h:355
#define ERROR_GEN_FAILURE
Definition: winerror.h:256
#define NOERROR
Definition: winerror.h:3448
#define ERROR_FILE_EXISTS
Definition: winerror.h:287
#define ERROR_SUCCESS_REBOOT_REQUIRED
Definition: winerror.h:1580
#define ERROR_INVALID_FLAGS
Definition: winerror.h:907
#define ERROR_INVALID_COMPUTERNAME
Definition: winerror.h:1042
#define ERROR_INVALID_DATA
Definition: winerror.h:238
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
ACCESS_MASK REGSAM
Definition: winreg.h:76
_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:1665
unsigned char BYTE
Definition: xxhash.c:193