ReactOS  0.4.14-dev-608-gd495a4f
driver.c
Go to the documentation of this file.
1 /*
2  * SetupAPI driver-related functions
3  *
4  * Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "setupapi_private.h"
22 
23 /* Unicode constants */
24 static const WCHAR BackSlash[] = {'\\',0};
25 static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0};
26 static const WCHAR DotCoInstallers[] = {'.','C','o','I','n','s','t','a','l','l','e','r','s',0};
27 static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
28 static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
29 
30 static const WCHAR INF_MANUFACTURER[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0};
31 static const WCHAR INF_PROVIDER[] = {'P','r','o','v','i','d','e','r',0};
32 static const WCHAR INF_DRIVER_VER[] = {'D','r','i','v','e','r','V','e','r',0};
33 
34 
35 /***********************************************************************
36  * struct InfFileDetails management
37  */
38 static VOID
40 {
42 }
43 
44 VOID
46 {
47  if (InterlockedDecrement(&infFile->References) == 0)
48  {
49  SetupCloseInfFile(infFile->hInf);
50  HeapFree(GetProcessHeap(), 0, infFile);
51  }
52 }
53 
54 struct InfFileDetails *
56  IN LPCWSTR FullInfFileName)
57 {
58  struct InfFileDetails *details;
59  PWCHAR last;
60  DWORD Needed;
61 
62  Needed = FIELD_OFFSET(struct InfFileDetails, szData)
63  + strlenW(FullInfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
64 
65  details = HeapAlloc(GetProcessHeap(), 0, Needed);
66  if (!details)
67  {
69  return NULL;
70  }
71 
72  memset(details, 0, Needed);
73  strcpyW(details->szData, FullInfFileName);
74  last = strrchrW(details->szData, '\\');
75  if (last)
76  {
77  details->DirectoryName = details->szData;
78  details->FileName = last + 1;
79  *last = '\0';
80  }
81  else
82  details->FileName = details->szData;
84  details->hInf = SetupOpenInfFileW(FullInfFileName, NULL, INF_STYLE_WIN4, NULL);
85  if (details->hInf == INVALID_HANDLE_VALUE)
86  {
88  return NULL;
89  }
90  return details;
91 }
92 
93 BOOL
95 {
97  HeapFree(GetProcessHeap(), 0, driverInfo->MatchingId);
98  HeapFree(GetProcessHeap(), 0, driverInfo);
99  return TRUE;
100 }
101 
102 /***********************************************************************
103  * Helper functions for SetupDiBuildDriverInfoList
104  */
105 static BOOL
107  IN PLIST_ENTRY DriverListHead,
108  IN DWORD DriverType, /* SPDIT_CLASSDRIVER or SPDIT_COMPATDRIVER */
109  IN LPGUID ClassGuid,
111  IN LPCWSTR InfFile,
112  IN LPCWSTR SectionName,
113  IN LPCWSTR DriverDescription,
114  IN LPCWSTR ProviderName,
115  IN LPCWSTR ManufacturerName,
116  IN LPCWSTR MatchingId,
117  IN FILETIME DriverDate,
118  IN DWORDLONG DriverVersion,
119  IN DWORD Rank)
120 {
121  struct DriverInfoElement *driverInfo = NULL;
123  BOOL Result = FALSE;
124  PLIST_ENTRY PreviousEntry;
125  BOOL ret = FALSE;
126 
127  driverInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DriverInfoElement));
128  if (!driverInfo)
129  {
131  goto cleanup;
132  }
133  memset(driverInfo, 0, sizeof(struct DriverInfoElement));
134 
135  driverInfo->Params.cbSize = sizeof(SP_DRVINSTALL_PARAMS);
136  driverInfo->Params.Reserved = (ULONG_PTR)driverInfo;
137 
138  driverInfo->Details.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
139  driverInfo->Details.Reserved = (ULONG_PTR)driverInfo;
140 
141  /* Copy InfFileName field */
142  lstrcpynW(driverInfo->Details.InfFileName, InfFile, MAX_PATH - 1);
143  driverInfo->Details.InfFileName[MAX_PATH - 1] = '\0';
144 
145  /* Fill InfDate field */
146  hFile = CreateFileW(
147  InfFile,
149  NULL, OPEN_EXISTING, 0, NULL);
151  goto cleanup;
152  Result = GetFileTime(hFile, NULL, NULL, &driverInfo->Details.InfDate);
153  if (!Result)
154  goto cleanup;
155 
156  /* Fill SectionName field */
157  lstrcpynW(driverInfo->Details.SectionName, SectionName, LINE_LEN);
158 
159  /* Fill DrvDescription field */
160  lstrcpynW(driverInfo->Details.DrvDescription, DriverDescription, LINE_LEN);
161 
162  /* Copy MatchingId information */
163  if (MatchingId)
164  {
165  driverInfo->MatchingId = HeapAlloc(GetProcessHeap(), 0, (strlenW(MatchingId) + 1) * sizeof(WCHAR));
166  if (!driverInfo->MatchingId)
167  {
169  goto cleanup;
170  }
171  RtlCopyMemory(driverInfo->MatchingId, MatchingId, (strlenW(MatchingId) + 1) * sizeof(WCHAR));
172  }
173  else
174  driverInfo->MatchingId = NULL;
175 
176  TRACE("Adding driver '%s' [%s/%s] (Rank 0x%lx)\n",
177  debugstr_w(driverInfo->Details.DrvDescription), debugstr_w(InfFile),
178  debugstr_w(SectionName), Rank);
179 
180  driverInfo->Params.Rank = Rank;
181  memcpy(&driverInfo->DriverDate, &DriverDate, sizeof(FILETIME));
182  memcpy(&driverInfo->ClassGuid, ClassGuid, sizeof(GUID));
183  driverInfo->Info.DriverType = DriverType;
184  driverInfo->Info.Reserved = (ULONG_PTR)driverInfo;
185  lstrcpynW(driverInfo->Info.Description, driverInfo->Details.DrvDescription, LINE_LEN - 1);
186  driverInfo->Info.Description[LINE_LEN - 1] = '\0';
187  lstrcpynW(driverInfo->Info.MfgName, ManufacturerName, LINE_LEN - 1);
188  driverInfo->Info.MfgName[LINE_LEN - 1] = '\0';
189  if (ProviderName)
190  {
191  lstrcpynW(driverInfo->Info.ProviderName, ProviderName, LINE_LEN - 1);
192  driverInfo->Info.ProviderName[LINE_LEN - 1] = '\0';
193  }
194  else
195  driverInfo->Info.ProviderName[0] = '\0';
196  driverInfo->Info.DriverDate = DriverDate;
197  driverInfo->Info.DriverVersion = DriverVersion;
199  driverInfo->InfFileDetails = InfFileDetails;
200 
201  /* Insert current driver in driver list, according to its rank */
202  PreviousEntry = DriverListHead->Flink;
203  while (PreviousEntry != DriverListHead)
204  {
205  struct DriverInfoElement *CurrentDriver;
206  CurrentDriver = CONTAINING_RECORD(PreviousEntry, struct DriverInfoElement, ListEntry);
207  if (CurrentDriver->Params.Rank > Rank ||
208  (CurrentDriver->Params.Rank == Rank && CurrentDriver->DriverDate.QuadPart < driverInfo->DriverDate.QuadPart))
209  {
210  /* Insert before the current item */
211  InsertHeadList(PreviousEntry->Blink, &driverInfo->ListEntry);
212  break;
213  }
214  PreviousEntry = PreviousEntry->Flink;
215  }
216  if (PreviousEntry == DriverListHead)
217  {
218  /* Insert at the end of the list */
219  InsertTailList(DriverListHead, &driverInfo->ListEntry);
220  }
221 
222  ret = TRUE;
223 
224 cleanup:
225  if (!ret)
226  {
227  if (driverInfo)
228  HeapFree(GetProcessHeap(), 0, driverInfo->MatchingId);
229  HeapFree(GetProcessHeap(), 0, driverInfo);
230  }
233 
234  return ret;
235 }
236 
237 static BOOL
239  IN PLIST_ENTRY DriverListHead,
240  IN DWORD DriverType, /* SPDIT_CLASSDRIVER or SPDIT_COMPATDRIVER */
242  IN INFCONTEXT ContextDevice,
244  IN LPCWSTR InfFile,
245  IN LPCWSTR ProviderName,
246  IN LPCWSTR ManufacturerName,
249  IN DWORDLONG DriverVersion,
250  IN DWORD Rank)
251 {
252  LPWSTR SectionName = NULL;
253  LPWSTR DriverDescription = NULL;
254  BOOL Result;
255  BOOL ret = FALSE;
256 
257  /* Read SectionName */
258  SectionName = MyMalloc(LINE_LEN);
259  if (!SectionName)
260  {
262  goto cleanup;
263  }
264  ZeroMemory(SectionName, LINE_LEN);
266  &ContextDevice,
267  1,
268  SectionName,
269  LINE_LEN,
270  NULL);
271  if (!Result)
272  goto cleanup;
273 
274  /* Read DriverDescription */
275  DriverDescription = MyMalloc(LINE_LEN);
276  if (!DriverDescription)
277  {
279  goto cleanup;
280  }
281  ZeroMemory(DriverDescription, LINE_LEN);
283  &ContextDevice,
284  0, /* Field index */
285  DriverDescription, LINE_LEN,
286  NULL);
287 
289  DriverListHead,
290  DriverType,
291  ClassGuid,
293  InfFile,
294  SectionName,
295  DriverDescription,
296  ProviderName,
297  ManufacturerName,
298  MatchingId,
299  DriverDate,
300  DriverVersion,
301  Rank);
302 
303 cleanup:
304  MyFree(SectionName);
305  MyFree(DriverDescription);
306 
307  return ret;
308 }
309 
310 static BOOL
312  IN HINF hInf,
314  OUT LPWSTR* pProviderName,
316  OUT DWORDLONG* DriverVersion)
317 {
319  WCHAR guidW[MAX_GUID_STRING_LEN + 1];
320  LPWSTR DriverVer = NULL;
321  LPWSTR ProviderName = NULL;
322  LPWSTR pComma; /* Points into DriverVer */
323  LPWSTR pVersion = NULL; /* Points into DriverVer */
324  SYSTEMTIME SystemTime;
325  BOOL Result;
326  BOOL ret = FALSE; /* Final result */
327 
328  /* Get class Guid */
329  if (!SetupGetLineTextW(
330  NULL, /* Context */
331  hInf,
333  guidW, sizeof(guidW),
334  NULL /* Required size */))
335  {
336  goto cleanup;
337  }
338  guidW[37] = '\0'; /* Replace the } by a NULL character */
339  if (UuidFromStringW(&guidW[1], ClassGuid) != RPC_S_OK)
340  {
342  goto cleanup;
343  }
344 
345  /* Get provider name */
347  NULL, /* Context */
348  hInf, Version, INF_PROVIDER,
349  NULL, 0,
350  &RequiredSize);
351  if (Result)
352  {
353  /* We know the needed buffer size */
354  ProviderName = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
355  if (!ProviderName)
356  {
358  goto cleanup;
359  }
361  NULL, /* Context */
362  hInf, Version, INF_PROVIDER,
363  ProviderName, RequiredSize,
364  &RequiredSize);
365  }
366  if (!Result)
367  goto cleanup;
368  *pProviderName = ProviderName;
369 
370  /* Read the "DriverVer" value */
372  NULL, /* Context */
373  hInf, Version, INF_DRIVER_VER,
374  NULL, 0,
375  &RequiredSize);
376  if (Result)
377  {
378  /* We know know the needed buffer size */
379  DriverVer = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
380  if (!DriverVer)
381  {
383  goto cleanup;
384  }
386  NULL, /* Context */
387  hInf, Version, INF_DRIVER_VER,
388  DriverVer, RequiredSize,
389  &RequiredSize);
390  }
391  else
392  {
393  /* windows sets default date of 00/00/0000 when this directive is missing*/
394  memset(DriverDate, 0, sizeof(FILETIME));
395  *DriverVersion = 0;
396  return TRUE;
397  }
398 
399  /* Get driver date and driver version, by analyzing the "DriverVer" value */
400  pComma = strchrW(DriverVer, ',');
401  if (pComma != NULL)
402  {
403  *pComma = UNICODE_NULL;
404  pVersion = pComma + 1;
405  }
406  /* Get driver date version. Invalid date = 00/00/00 */
407  memset(DriverDate, 0, sizeof(FILETIME));
408  if (strlenW(DriverVer) == 10
409  && (DriverVer[2] == '-' || DriverVer[2] == '/')
410  && (DriverVer[5] == '-' || DriverVer[5] == '/'))
411  {
412  memset(&SystemTime, 0, sizeof(SYSTEMTIME));
413  DriverVer[2] = DriverVer[5] = UNICODE_NULL;
414  SystemTime.wMonth = ((DriverVer[0] - '0') * 10) + DriverVer[1] - '0';
415  SystemTime.wDay = ((DriverVer[3] - '0') * 10) + DriverVer[4] - '0';
416  SystemTime.wYear = ((DriverVer[6] - '0') * 1000) + ((DriverVer[7] - '0') * 100) + ((DriverVer[8] - '0') * 10) + DriverVer[9] - '0';
417  SystemTimeToFileTime(&SystemTime, DriverDate);
418  }
419  /* Get driver version. Invalid version = 0.0.0.0 */
420  *DriverVersion = 0;
421  if (pVersion)
422  {
423  WORD Major, Minor = 0, Revision = 0, Build = 0;
424  LPWSTR pMinor = NULL, pRevision = NULL, pBuild = NULL;
425  LARGE_INTEGER fullVersion;
426 
427  pMinor = strchrW(pVersion, '.');
428  if (pMinor)
429  {
430  *pMinor = 0;
431  pRevision = strchrW(++pMinor, '.');
432  Minor = atoiW(pMinor);
433  }
434  if (pRevision)
435  {
436  *pRevision = 0;
437  pBuild = strchrW(++pRevision, '.');
438  Revision = atoiW(pRevision);
439  }
440  if (pBuild)
441  {
442  *pBuild = 0;
443  pBuild++;
444  Build = atoiW(pBuild);
445  }
446  Major = atoiW(pVersion);
447  fullVersion.u.HighPart = Major << 16 | Minor;
448  fullVersion.u.LowPart = Revision << 16 | Build;
449  memcpy(DriverVersion, &fullVersion, sizeof(LARGE_INTEGER));
450  }
451 
452  ret = TRUE;
453 
454 cleanup:
455  if (!ret)
456  {
457  HeapFree(GetProcessHeap(), 0, ProviderName);
458  *pProviderName = NULL;
459  }
460  HeapFree(GetProcessHeap(), 0, DriverVer);
461 
462  return ret;
463 }
464 
465 static BOOL
469  OUT LPWSTR *pHardwareIDs OPTIONAL,
470  OUT LPDWORD pHardwareIDsRequiredSize OPTIONAL,
471  OUT LPWSTR *pCompatibleIDs OPTIONAL,
472  OUT LPDWORD pCompatibleIDsRequiredSize OPTIONAL)
473 {
474  LPWSTR HardwareIDs = NULL;
475  LPWSTR CompatibleIDs = NULL;
477  BOOL Result;
478 
479  /* Get hardware IDs list */
480  Result = FALSE;
481  RequiredSize = 512; /* Initial buffer size */
484  {
485  MyFree(HardwareIDs);
486  HardwareIDs = MyMalloc(RequiredSize);
487  if (!HardwareIDs)
488  {
490  goto done;
491  }
496  NULL,
497  (PBYTE)HardwareIDs,
498  RequiredSize,
499  &RequiredSize);
500  }
501  if (!Result)
502  {
504  {
505  /* No hardware ID for this device */
506  MyFree(HardwareIDs);
507  HardwareIDs = NULL;
508  RequiredSize = 0;
509  }
510  else
511  goto done;
512  }
513  if (pHardwareIDs)
514  *pHardwareIDs = HardwareIDs;
515  if (pHardwareIDsRequiredSize)
516  *pHardwareIDsRequiredSize = RequiredSize;
517 
518  /* Get compatible IDs list */
519  Result = FALSE;
520  RequiredSize = 512; /* Initial buffer size */
523  {
524  MyFree(CompatibleIDs);
525  CompatibleIDs = MyMalloc(RequiredSize);
526  if (!CompatibleIDs)
527  {
529  goto done;
530  }
535  NULL,
536  (PBYTE)CompatibleIDs,
537  RequiredSize,
538  &RequiredSize);
539  }
540  if (!Result)
541  {
543  {
544  /* No compatible ID for this device */
545  MyFree(CompatibleIDs);
546  CompatibleIDs = NULL;
547  RequiredSize = 0;
548  }
549  else
550  goto done;
551  }
552  if (pCompatibleIDs)
553  *pCompatibleIDs = CompatibleIDs;
554  if (pCompatibleIDsRequiredSize)
555  *pCompatibleIDsRequiredSize = RequiredSize;
556 
557  Result = TRUE;
558 
559 done:
560  if (!Result)
561  {
562  MyFree(HardwareIDs);
563  MyFree(CompatibleIDs);
564  }
565  return Result;
566 }
567 
568 #if _WIN32_WINNT < 0x0600
569 /* WARNING:
570  * This code has been copied from advapi32/reg/reg.c,
571  * so this dll can be tested as is on Windows XP
572  */
573 
574 #define RRF_RT_REG_NONE (1 << 0)
575 #define RRF_RT_REG_SZ (1 << 1)
576 #define RRF_RT_REG_EXPAND_SZ (1 << 2)
577 #define RRF_RT_REG_BINARY (1 << 3)
578 #define RRF_RT_REG_DWORD (1 << 4)
579 #define RRF_RT_REG_MULTI_SZ (1 << 5)
580 #define RRF_RT_REG_QWORD (1 << 6)
581 #define RRF_RT_DWORD (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD)
582 #define RRF_RT_QWORD (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD)
583 #define RRF_NOEXPAND (1 << 28)
584 #define RRF_ZEROONFAILURE (1 << 29)
585 
586 static VOID
588  PLONG ret )
589 {
590  /* Check if the type is restricted by the passed flags */
591  if (*ret == ERROR_SUCCESS || *ret == ERROR_MORE_DATA)
592  {
593  DWORD dwMask = 0;
594 
595  switch (dwType)
596  {
597  case REG_NONE: dwMask = RRF_RT_REG_NONE; break;
598  case REG_SZ: dwMask = RRF_RT_REG_SZ; break;
599  case REG_EXPAND_SZ: dwMask = RRF_RT_REG_EXPAND_SZ; break;
600  case REG_MULTI_SZ: dwMask = RRF_RT_REG_MULTI_SZ; break;
601  case REG_BINARY: dwMask = RRF_RT_REG_BINARY; break;
602  case REG_DWORD: dwMask = RRF_RT_REG_DWORD; break;
603  case REG_QWORD: dwMask = RRF_RT_REG_QWORD; break;
604  }
605 
606  if (dwFlags & dwMask)
607  {
608  /* Type is not restricted, check for size mismatch */
609  if (dwType == REG_BINARY)
610  {
611  DWORD cbExpect = 0;
612 
613  if ((dwFlags & RRF_RT_DWORD) == RRF_RT_DWORD)
614  cbExpect = 4;
615  else if ((dwFlags & RRF_RT_QWORD) == RRF_RT_QWORD)
616  cbExpect = 8;
617 
618  if (cbExpect && cbData != cbExpect)
620  }
621  }
622  else *ret = ERROR_UNSUPPORTED_TYPE;
623  }
624 }
625 
626 static LONG WINAPI
627 RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue,
628  DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
629  LPDWORD pcbData )
630 {
631  DWORD dwType, cbData = pcbData ? *pcbData : 0;
632  PVOID pvBuf = NULL;
633  LONG ret;
634 
635  TRACE("(%p,%s,%s,%ld,%p,%p,%p=%ld)\n",
636  hKey, debugstr_w(pszSubKey), debugstr_w(pszValue), dwFlags, pdwType,
637  pvData, pcbData, cbData);
638 
641 
642  if (pszSubKey && pszSubKey[0])
643  {
644  ret = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_QUERY_VALUE, &hKey);
645  if (ret != ERROR_SUCCESS) return ret;
646  }
647 
648  ret = RegQueryValueExW(hKey, pszValue, NULL, &dwType, pvData, &cbData);
649 
650  /* If we are going to expand we need to read in the whole the value even
651  * if the passed buffer was too small as the expanded string might be
652  * smaller than the unexpanded one and could fit into cbData bytes. */
653  if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) &&
654  (dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)))
655  {
656  do {
657  if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
658 
659  pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData);
660  if (!pvBuf)
661  {
663  break;
664  }
665 
666  if (ret == ERROR_MORE_DATA)
667  ret = RegQueryValueExW(hKey, pszValue, NULL,
668  &dwType, pvBuf, &cbData);
669  else
670  {
671  /* Even if cbData was large enough we have to copy the
672  * string since ExpandEnvironmentStrings can't handle
673  * overlapping buffers. */
674  CopyMemory(pvBuf, pvData, cbData);
675  }
676 
677  /* Both the type or the value itself could have been modified in
678  * between so we have to keep retrying until the buffer is large
679  * enough or we no longer have to expand the value. */
680  } while (dwType == REG_EXPAND_SZ && ret == ERROR_MORE_DATA);
681 
682  if (ret == ERROR_SUCCESS)
683  {
684  if (dwType == REG_EXPAND_SZ)
685  {
686  cbData = ExpandEnvironmentStringsW(pvBuf, pvData,
687  pcbData ? (*pcbData)/sizeof(WCHAR) : 0);
688  dwType = REG_SZ;
689  if(pcbData && cbData > ((*pcbData)/sizeof(WCHAR)))
691  }
692  else if (pcbData)
693  CopyMemory(pvData, pvBuf, *pcbData);
694  }
695 
696  if (pvBuf) HeapFree(GetProcessHeap(), 0, pvBuf);
697  }
698 
699  if (pszSubKey && pszSubKey[0])
700  RegCloseKey(hKey);
701 
702  RegpApplyRestrictions(dwFlags, dwType, cbData, &ret);
703 
706 
707  if (pdwType) *pdwType = dwType;
708  if (pcbData) *pcbData = cbData;
709 
710  return ret;
711 }
712 #endif /* End of code copied from advapi32/reg/reg.c */
713 
714 /***********************************************************************
715  * SetupDiBuildDriverInfoList (SETUPAPI.@)
716  */
717 BOOL WINAPI
722 {
723  struct DeviceInfoSet *list;
725  PVOID Buffer = NULL;
726  struct InfFileDetails *currentInfFileDetails = NULL;
727  LPWSTR ProviderName = NULL;
728  LPWSTR ManufacturerName = NULL;
729  WCHAR ManufacturerSection[LINE_LEN + 1];
730  LPWSTR HardwareIDs = NULL;
731  LPWSTR CompatibleIDs = NULL;
732  LPWSTR FullInfFileName = NULL;
733  LPWSTR ExcludeFromSelect = NULL;
734  FILETIME DriverDate;
735  DWORDLONG DriverVersion = 0;
737  BOOL ret = FALSE;
738 
739  TRACE("%p %p %ld\n", DeviceInfoSet, DeviceInfoData, DriverType);
740 
741  if (!DeviceInfoSet)
745  else if (list->HKLM != HKEY_LOCAL_MACHINE)
751  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
753  else
754  {
755  PLIST_ENTRY pDriverListHead = &list->DriverListHead;
756  BOOL Result;
757 
758  InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
760  if (!Result)
761  goto done;
762 
763  if (DeviceInfoData)
764  {
765  struct DeviceInfo *devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
766  if (!(devInfo->CreationFlags & DICD_INHERIT_CLASSDRVS))
767  pDriverListHead = &devInfo->DriverListHead;
768  }
769 
771  {
772  /* Get hardware and compatible IDs lists */
776  &HardwareIDs,
777  NULL,
778  &CompatibleIDs,
779  NULL);
780  if (!Result)
781  goto done;
782  if (!HardwareIDs && !CompatibleIDs)
783  {
785  goto done;
786  }
787  }
788 
789  if (InstallParams.FlagsEx & DI_FLAGSEX_INSTALLEDDRIVER)
790  {
791  HKEY hDriverKey;
792  WCHAR InfFileName[MAX_PATH];
793  WCHAR InfFileSection[MAX_PATH];
795  struct DeviceInfo *devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
796  struct InfFileDetails *infFileDetails = NULL;
797  FILETIME DriverDate;
798  LONG rc;
799  DWORD len;
800 
801  /* Prepend inf directory name to file name */
802  len = sizeof(InfFileName) / sizeof(InfFileName[0]);
804  if (RequiredSize == 0 || RequiredSize >= len)
805  goto done;
806  if (*InfFileName && InfFileName[strlenW(InfFileName) - 1] != '\\')
807  strcatW(InfFileName, BackSlash);
808  strcatW(InfFileName, InfDirectory);
809 
810  /* Read some information from registry, before creating the driver structure */
811  hDriverKey = SETUPDI_OpenDrvKey(((struct DeviceInfoSet *)DeviceInfoSet)->HKLM, devInfo, KEY_QUERY_VALUE);
812  if (hDriverKey == INVALID_HANDLE_VALUE)
813  goto done;
814  RequiredSize = (len - strlenW(InfFileName)) * sizeof(WCHAR);
815  rc = RegGetValueW(
816  hDriverKey,
817  NULL,
820  NULL,
821  &InfFileName[strlenW(InfFileName)],
822  &RequiredSize);
823  if (rc != ERROR_SUCCESS)
824  {
825  SetLastError(rc);
826  CloseHandle(hDriverKey);
827  goto done;
828  }
829  RequiredSize = sizeof(InfFileSection);
830  rc = RegGetValueW(
831  hDriverKey,
832  NULL,
835  NULL,
836  InfFileSection,
837  &RequiredSize);
838  if (rc != ERROR_SUCCESS)
839  {
840  SetLastError(rc);
841  CloseHandle(hDriverKey);
842  goto done;
843  }
844  TRACE("Current driver in %s/%s\n", debugstr_w(InfFileName), debugstr_w(InfFileSection));
845  infFileDetails = CreateInfFileDetails(InfFileName);
846  if (!infFileDetails)
847  {
848  CloseHandle(hDriverKey);
849  goto done;
850  }
851  DriverDate.dwLowDateTime = DriverDate.dwHighDateTime = 0; /* FIXME */
852  CloseHandle(hDriverKey);
854  pDriverListHead,
856  &devInfo->ClassGuid,
857  infFileDetails,
858  InfFileName,
859  InfFileSection, /* Yes, we don't care of section extension */
860  L"DriverDescription", /* FIXME */
861  L"ProviderName", /* FIXME */
862  L"ManufacturerName", /* FIXME */
863  L"MatchingId", /* FIXME */
864  DriverDate,
865  0, /* FIXME: DriverVersion */
866  0);
867  if (!ret)
868  DereferenceInfFile(infFileDetails);
869  Result = FALSE;
870  }
872  {
873  /* InstallParams.DriverPath contains the name of a .inf file */
875  Buffer = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
876  if (!Buffer)
877  {
879  goto done;
880  }
882  ((LPWSTR)Buffer)[RequiredSize - 1] = 0;
883  Result = TRUE;
884  }
885  else
886  {
887  /* Enumerate .inf files */
888  Result = FALSE;
889  RequiredSize = 32768; /* Initial buffer size */
892  {
894  Buffer = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
895  if (!Buffer)
896  {
897  Result = FALSE;
899  break;
900  }
905  &RequiredSize);
906  }
908  {
909  /* No .inf file in specified directory. So, we should
910  * success as we created an empty driver info list.
911  */
912  ret = TRUE;
913  goto done;
914  }
915  }
916  if (Result)
917  {
919  LPWSTR pFullFilename;
920 
922  {
923  /* Only a filename */
924  FullInfFileName = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
925  if (!FullInfFileName)
926  goto done;
927  pFullFilename = &FullInfFileName[0];
928  }
929  else if (*InstallParams.DriverPath)
930  {
931  /* Directory name specified */
932  DWORD len;
934  if (len == 0)
935  goto done;
936  FullInfFileName = HeapAlloc(GetProcessHeap(), 0, (len + 1 + MAX_PATH) * sizeof(WCHAR));
937  if (!FullInfFileName)
938  goto done;
939  len = GetFullPathNameW(InstallParams.DriverPath, len, FullInfFileName, NULL);
940  if (len == 0)
941  goto done;
942  if (*FullInfFileName && FullInfFileName[strlenW(FullInfFileName) - 1] != '\\')
943  strcatW(FullInfFileName, BackSlash);
944  pFullFilename = &FullInfFileName[strlenW(FullInfFileName)];
945  }
946  else
947  {
948  /* Nothing specified ; need to get the %SYSTEMROOT%\ directory */
949  DWORD len;
951  if (len == 0)
952  goto done;
953  FullInfFileName = HeapAlloc(GetProcessHeap(), 0, (len + 1 + strlenW(InfDirectory) + MAX_PATH) * sizeof(WCHAR));
954  if (!FullInfFileName)
955  goto done;
956  len = GetSystemWindowsDirectoryW(FullInfFileName, len);
957  if (len == 0)
958  goto done;
959  if (*FullInfFileName && FullInfFileName[strlenW(FullInfFileName) - 1] != '\\')
960  strcatW(FullInfFileName, BackSlash);
961  strcatW(FullInfFileName, InfDirectory);
962  pFullFilename = &FullInfFileName[strlenW(FullInfFileName)];
963  }
964 
966  {
967  INFCONTEXT ContextManufacturer, ContextDevice;
968  GUID ClassGuid;
969 
970  strcpyW(pFullFilename, filename);
971  TRACE("Opening file %s\n", debugstr_w(FullInfFileName));
972 
973  currentInfFileDetails = CreateInfFileDetails(FullInfFileName);
974  if (!currentInfFileDetails)
975  continue;
976 
978  currentInfFileDetails->hInf,
979  &ClassGuid,
980  &ProviderName,
981  &DriverDate,
982  &DriverVersion))
983  {
984  DereferenceInfFile(currentInfFileDetails);
985  currentInfFileDetails = NULL;
986  continue;
987  }
988 
990  {
991  /* Check if the ClassGuid in this .inf file is corresponding with our needs */
992  if (!IsEqualIID(&list->ClassGuid, &GUID_NULL) && !IsEqualIID(&list->ClassGuid, &ClassGuid))
993  {
994  goto next;
995  }
996  }
997 
999  {
1000  /* Read ExcludeFromSelect control flags */
1001  /* FIXME */
1002  }
1003  else
1004  FIXME("ExcludeFromSelect list ignored\n");
1005 
1006  /* Get the manufacturers list */
1007  Result = SetupFindFirstLineW(currentInfFileDetails->hInf, INF_MANUFACTURER, NULL, &ContextManufacturer);
1008  while (Result)
1009  {
1011  &ContextManufacturer,
1012  0, /* Field index */
1013  NULL, 0,
1014  &RequiredSize);
1015  if (Result)
1016  {
1017  /* We got the needed size for the buffer */
1018  ManufacturerName = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
1019  if (!ManufacturerName)
1020  {
1022  goto done;
1023  }
1025  &ContextManufacturer,
1026  0, /* Field index */
1027  ManufacturerName, RequiredSize,
1028  &RequiredSize);
1029  }
1030  /* Get manufacturer section name */
1032  &ContextManufacturer,
1033  1, /* Field index */
1034  ManufacturerSection, LINE_LEN,
1035  &RequiredSize);
1036  if (Result)
1037  {
1038  ManufacturerSection[RequiredSize] = 0; /* Final NULL char */
1039  /* Add (possible) extension to manufacturer section name */
1041  currentInfFileDetails->hInf, ManufacturerSection, ManufacturerSection, LINE_LEN, NULL, NULL);
1042  if (Result)
1043  {
1044  TRACE("Enumerating devices in manufacturer %s\n", debugstr_w(ManufacturerSection));
1045  Result = SetupFindFirstLineW(currentInfFileDetails->hInf, ManufacturerSection, NULL, &ContextDevice);
1046  }
1047  }
1048  while (Result)
1049  {
1051  {
1052  /* FIXME: Check ExcludeFromSelect list */
1053  if (!AddDriverToList(
1054  pDriverListHead,
1055  DriverType,
1056  &ClassGuid,
1057  ContextDevice,
1058  currentInfFileDetails,
1059  FullInfFileName,
1060  ProviderName,
1061  ManufacturerName,
1062  NULL,
1063  DriverDate, DriverVersion,
1064  0))
1065  {
1066  break;
1067  }
1068  }
1069  else /* DriverType = SPDIT_COMPATDRIVER */
1070  {
1071  /* 1. Get all fields */
1072  DWORD FieldCount = SetupGetFieldCount(&ContextDevice);
1073  DWORD DriverRank;
1074  DWORD i;
1075  LPCWSTR currentId;
1076  BOOL DriverAlreadyAdded;
1077 
1078  for (i = 2; i <= FieldCount; i++)
1079  {
1080  LPWSTR DeviceId = NULL;
1081  Result = FALSE;
1082  RequiredSize = 128; /* Initial buffer size */
1085  {
1086  HeapFree(GetProcessHeap(), 0, DeviceId);
1087  DeviceId = HeapAlloc(GetProcessHeap(), 0, RequiredSize * sizeof(WCHAR));
1088  if (!DeviceId)
1089  {
1091  goto done;
1092  }
1094  &ContextDevice,
1095  i,
1096  DeviceId, RequiredSize,
1097  &RequiredSize);
1098  }
1099  if (!Result)
1100  {
1101  HeapFree(GetProcessHeap(), 0, DeviceId);
1102  goto done;
1103  }
1104  /* FIXME: Check ExcludeFromSelect list */
1105  DriverAlreadyAdded = FALSE;
1106  if (HardwareIDs)
1107  {
1108  for (DriverRank = 0, currentId = (LPCWSTR)HardwareIDs; !DriverAlreadyAdded && *currentId; currentId += strlenW(currentId) + 1, DriverRank++)
1109  {
1110  if (strcmpiW(DeviceId, currentId) == 0)
1111  {
1113  pDriverListHead,
1114  DriverType,
1115  &ClassGuid,
1116  ContextDevice,
1117  currentInfFileDetails,
1118  FullInfFileName,
1119  ProviderName,
1120  ManufacturerName,
1121  currentId,
1122  DriverDate, DriverVersion,
1123  DriverRank + (i == 2 ? 0 : 0x1000 + i - 3));
1124  DriverAlreadyAdded = TRUE;
1125  }
1126  }
1127  }
1128  if (CompatibleIDs)
1129  {
1130  for (DriverRank = 0, currentId = (LPCWSTR)CompatibleIDs; !DriverAlreadyAdded && *currentId; currentId += strlenW(currentId) + 1, DriverRank++)
1131  {
1132  if (strcmpiW(DeviceId, currentId) == 0)
1133  {
1135  pDriverListHead,
1136  DriverType,
1137  &ClassGuid,
1138  ContextDevice,
1139  currentInfFileDetails,
1140  FullInfFileName,
1141  ProviderName,
1142  ManufacturerName,
1143  currentId,
1144  DriverDate, DriverVersion,
1145  DriverRank + (i == 2 ? 0x2000 : 0x3000 + i - 3));
1146  DriverAlreadyAdded = TRUE;
1147  }
1148  }
1149  }
1150  HeapFree(GetProcessHeap(), 0, DeviceId);
1151  }
1152  }
1153  Result = SetupFindNextLine(&ContextDevice, &ContextDevice);
1154  }
1155 
1156  HeapFree(GetProcessHeap(), 0, ManufacturerName);
1157  ManufacturerName = NULL;
1158  Result = SetupFindNextLine(&ContextManufacturer, &ContextManufacturer);
1159  }
1160 
1161  ret = TRUE;
1162 next:
1163  HeapFree(GetProcessHeap(), 0, ProviderName);
1164  HeapFree(GetProcessHeap(), 0, ExcludeFromSelect);
1165  ProviderName = ExcludeFromSelect = NULL;
1166 
1167  DereferenceInfFile(currentInfFileDetails);
1168  currentInfFileDetails = NULL;
1169  }
1170  ret = TRUE;
1171  }
1172  }
1173 
1174 done:
1175  if (ret)
1176  {
1177  if (DeviceInfoData)
1178  {
1181  }
1182  else
1183  {
1186  }
1188  }
1189 
1190  HeapFree(GetProcessHeap(), 0, ProviderName);
1191  HeapFree(GetProcessHeap(), 0, ManufacturerName);
1192  MyFree(HardwareIDs);
1193  MyFree(CompatibleIDs);
1194  HeapFree(GetProcessHeap(), 0, FullInfFileName);
1195  HeapFree(GetProcessHeap(), 0, ExcludeFromSelect);
1196  if (currentInfFileDetails)
1197  DereferenceInfFile(currentInfFileDetails);
1199 
1200  TRACE("Returning %d\n", ret);
1201  return ret;
1202 }
1203 
1204 /***********************************************************************
1205  * SetupDiDestroyDriverInfoList (SETUPAPI.@)
1206  */
1207 BOOL WINAPI
1212 {
1213  struct DeviceInfoSet *list;
1214  BOOL ret = FALSE;
1215 
1216  TRACE("%p %p 0x%lx\n", DeviceInfoSet, DeviceInfoData, DriverType);
1217 
1218  if (!DeviceInfoSet)
1226  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
1228  else
1229  {
1230  PLIST_ENTRY ListEntry;
1231  struct DriverInfoElement *driverInfo;
1232  SP_DEVINSTALL_PARAMS_W InstallParams;
1233 
1234  InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
1236  goto done;
1237 
1238  if (!DeviceInfoData)
1239  /* Fall back to destroying class driver list */
1241 
1243  {
1244  while (!IsListEmpty(&list->DriverListHead))
1245  {
1246  ListEntry = RemoveHeadList(&list->DriverListHead);
1247  driverInfo = CONTAINING_RECORD(ListEntry, struct DriverInfoElement, ListEntry);
1248  DestroyDriverInfoElement(driverInfo);
1249  }
1250  InstallParams.ClassInstallReserved = 0;
1251  InstallParams.Flags &= ~(DI_DIDCLASS | DI_MULTMFGS);
1252  InstallParams.FlagsEx &= ~DI_FLAGSEX_DIDINFOLIST;
1254  }
1255  else
1256  {
1257  SP_DEVINSTALL_PARAMS_W InstallParamsSet;
1258  struct DeviceInfo *deviceInfo;
1259 
1260  InstallParamsSet.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
1261  if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, NULL, &InstallParamsSet))
1262  goto done;
1263  deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
1264  while (!IsListEmpty(&deviceInfo->DriverListHead))
1265  {
1266  ListEntry = RemoveHeadList(&deviceInfo->DriverListHead);
1267  driverInfo = CONTAINING_RECORD(ListEntry, struct DriverInfoElement, ListEntry);
1268  if ((PVOID)InstallParamsSet.ClassInstallReserved == driverInfo)
1269  {
1270  InstallParamsSet.ClassInstallReserved = 0;
1271  SetupDiSetDeviceInstallParamsW(DeviceInfoSet, NULL, &InstallParamsSet);
1272  }
1273  DestroyDriverInfoElement(driverInfo);
1274  }
1279  }
1280  }
1281 
1282 done:
1283  TRACE("Returning %d\n", ret);
1284  return ret;
1285 }
1286 
1287 /***********************************************************************
1288  * SetupDiEnumDriverInfoA (SETUPAPI.@)
1289  */
1290 BOOL WINAPI
1295  IN DWORD MemberIndex,
1296  OUT PSP_DRVINFO_DATA_A DriverInfoData)
1297 {
1298  SP_DRVINFO_DATA_V2_W driverInfoData2W;
1299  BOOL ret = FALSE;
1300 
1301  TRACE("%p %p 0x%lx %ld %p\n", DeviceInfoSet, DeviceInfoData,
1302  DriverType, MemberIndex, DriverInfoData);
1303 
1304  if (DriverInfoData == NULL)
1306  else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_A) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_A))
1308  else
1309  {
1310  driverInfoData2W.cbSize = sizeof(SP_DRVINFO_DATA_V2_W);
1312  DriverType, MemberIndex, &driverInfoData2W);
1313 
1314  if (ret)
1315  {
1316  /* Do W->A conversion */
1317  DriverInfoData->DriverType = driverInfoData2W.DriverType;
1318  DriverInfoData->Reserved = driverInfoData2W.Reserved;
1319  if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.Description, -1,
1320  DriverInfoData->Description, LINE_LEN, NULL, NULL) == 0)
1321  {
1322  DriverInfoData->Description[0] = '\0';
1323  ret = FALSE;
1324  }
1325  if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.MfgName, -1,
1326  DriverInfoData->MfgName, LINE_LEN, NULL, NULL) == 0)
1327  {
1328  DriverInfoData->MfgName[0] = '\0';
1329  ret = FALSE;
1330  }
1331  if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.ProviderName, -1,
1332  DriverInfoData->ProviderName, LINE_LEN, NULL, NULL) == 0)
1333  {
1334  DriverInfoData->ProviderName[0] = '\0';
1335  ret = FALSE;
1336  }
1337  if (DriverInfoData->cbSize == sizeof(SP_DRVINFO_DATA_V2_A))
1338  {
1339  /* Copy more fields */
1340  DriverInfoData->DriverDate = driverInfoData2W.DriverDate;
1341  DriverInfoData->DriverVersion = driverInfoData2W.DriverVersion;
1342  }
1343  }
1344  }
1345 
1346  TRACE("Returning %d\n", ret);
1347  return ret;
1348 }
1349 
1350 
1351 /***********************************************************************
1352  * SetupDiEnumDriverInfoW (SETUPAPI.@)
1353  */
1354 BOOL WINAPI
1359  IN DWORD MemberIndex,
1360  OUT PSP_DRVINFO_DATA_W DriverInfoData)
1361 {
1362  PLIST_ENTRY ListHead;
1363  BOOL ret = FALSE;
1364 
1365  TRACE("%p %p 0x%lx %ld %p\n", DeviceInfoSet, DeviceInfoData,
1366  DriverType, MemberIndex, DriverInfoData);
1367 
1368  if (!DeviceInfoSet || !DriverInfoData)
1378  else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_W) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_W))
1380  else
1381  {
1382  struct DeviceInfo *devInfo = NULL;
1383  PLIST_ENTRY ItemList;
1384  if (DeviceInfoData)
1385  devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
1386  if (!devInfo || (devInfo->CreationFlags & DICD_INHERIT_CLASSDRVS))
1387  {
1388  ListHead = &((struct DeviceInfoSet *)DeviceInfoSet)->DriverListHead;
1389  }
1390  else
1391  {
1392  ListHead = &devInfo->DriverListHead;
1393  }
1394 
1395  ItemList = ListHead->Flink;
1396  while (ItemList != ListHead && MemberIndex-- > 0)
1397  ItemList = ItemList->Flink;
1398  if (ItemList == ListHead)
1400  else
1401  {
1402  struct DriverInfoElement *DrvInfo = CONTAINING_RECORD(ItemList, struct DriverInfoElement, ListEntry);
1403 
1404  memcpy(
1405  &DriverInfoData->DriverType,
1406  &DrvInfo->Info.DriverType,
1407  DriverInfoData->cbSize - FIELD_OFFSET(SP_DRVINFO_DATA_W, DriverType));
1408  ret = TRUE;
1409  }
1410  }
1411 
1412  TRACE("Returning %d\n", ret);
1413  return ret;
1414 }
1415 
1416 /***********************************************************************
1417  * SetupDiGetSelectedDriverA (SETUPAPI.@)
1418  */
1419 BOOL WINAPI
1423  OUT PSP_DRVINFO_DATA_A DriverInfoData)
1424 {
1425  SP_DRVINFO_DATA_V2_W driverInfoData2W;
1426  BOOL ret = FALSE;
1427 
1428  if (DriverInfoData == NULL)
1430  else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_A) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_A))
1432  else
1433  {
1434  driverInfoData2W.cbSize = sizeof(SP_DRVINFO_DATA_V2_W);
1435 
1438  &driverInfoData2W);
1439 
1440  if (ret)
1441  {
1442  /* Do W->A conversion */
1443  DriverInfoData->DriverType = driverInfoData2W.DriverType;
1444  DriverInfoData->Reserved = driverInfoData2W.Reserved;
1445  if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.Description, -1,
1446  DriverInfoData->Description, LINE_LEN, NULL, NULL) == 0)
1447  {
1448  DriverInfoData->Description[0] = '\0';
1449  ret = FALSE;
1450  }
1451  if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.MfgName, -1,
1452  DriverInfoData->MfgName, LINE_LEN, NULL, NULL) == 0)
1453  {
1454  DriverInfoData->MfgName[0] = '\0';
1455  ret = FALSE;
1456  }
1457  if (WideCharToMultiByte(CP_ACP, 0, driverInfoData2W.ProviderName, -1,
1458  DriverInfoData->ProviderName, LINE_LEN, NULL, NULL) == 0)
1459  {
1460  DriverInfoData->ProviderName[0] = '\0';
1461  ret = FALSE;
1462  }
1463  if (DriverInfoData->cbSize == sizeof(SP_DRVINFO_DATA_V2_A))
1464  {
1465  /* Copy more fields */
1466  DriverInfoData->DriverDate = driverInfoData2W.DriverDate;
1467  DriverInfoData->DriverVersion = driverInfoData2W.DriverVersion;
1468  }
1469  }
1470  }
1471 
1472  return ret;
1473 }
1474 
1475 /***********************************************************************
1476  * SetupDiGetSelectedDriverW (SETUPAPI.@)
1477  */
1478 BOOL WINAPI
1482  OUT PSP_DRVINFO_DATA_W DriverInfoData)
1483 {
1484  BOOL ret = FALSE;
1485 
1486  TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DriverInfoData);
1487 
1488  if (!DeviceInfoSet || !DriverInfoData)
1494  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
1496  else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_W) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_W))
1498  else
1499  {
1500  SP_DEVINSTALL_PARAMS InstallParams;
1501 
1502  InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
1504  {
1505  struct DriverInfoElement *driverInfo;
1506  driverInfo = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
1507  if (driverInfo == NULL)
1509  else
1510  {
1511  memcpy(
1512  &DriverInfoData->DriverType,
1513  &driverInfo->Info.DriverType,
1514  DriverInfoData->cbSize - FIELD_OFFSET(SP_DRVINFO_DATA_W, DriverType));
1515  ret = TRUE;
1516  }
1517  }
1518  }
1519 
1520  TRACE("Returning %d\n", ret);
1521  return ret;
1522 }
1523 
1524 /***********************************************************************
1525  * SetupDiSetSelectedDriverA (SETUPAPI.@)
1526  */
1527 BOOL WINAPI
1531  IN OUT PSP_DRVINFO_DATA_A DriverInfoData OPTIONAL)
1532 {
1533  SP_DRVINFO_DATA_V1_W DriverInfoDataW;
1534  PSP_DRVINFO_DATA_W pDriverInfoDataW = NULL;
1535  BOOL ret = FALSE;
1536 
1537  if (DriverInfoData != NULL)
1538  {
1539  if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_A) &&
1540  DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_A))
1541  {
1543  return FALSE;
1544  }
1545 
1546  DriverInfoDataW.cbSize = sizeof(SP_DRVINFO_DATA_V1_W);
1547  DriverInfoDataW.Reserved = DriverInfoData->Reserved;
1548 
1549  if (DriverInfoDataW.Reserved == 0)
1550  {
1551  DriverInfoDataW.DriverType = DriverInfoData->DriverType;
1552 
1553  /* convert the strings to unicode */
1555  0,
1556  DriverInfoData->Description,
1557  LINE_LEN,
1558  DriverInfoDataW.Description,
1559  LINE_LEN) ||
1561  0,
1562  DriverInfoData->ProviderName,
1563  LINE_LEN,
1564  DriverInfoDataW.ProviderName,
1565  LINE_LEN))
1566  {
1567  return FALSE;
1568  }
1569  }
1570 
1571  pDriverInfoDataW = (PSP_DRVINFO_DATA_W)&DriverInfoDataW;
1572  }
1573 
1576  pDriverInfoDataW);
1577 
1578  if (ret && pDriverInfoDataW != NULL)
1579  {
1580  DriverInfoData->Reserved = DriverInfoDataW.Reserved;
1581  }
1582 
1583  return ret;
1584 }
1585 
1586 /***********************************************************************
1587  * SetupDiSetSelectedDriverW (SETUPAPI.@)
1588  */
1589 BOOL WINAPI
1593  IN OUT PSP_DRVINFO_DATA_W DriverInfoData OPTIONAL)
1594 {
1595  BOOL ret = FALSE;
1596 
1597  TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DriverInfoData);
1598 
1599  if (!DeviceInfoSet)
1605  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
1607  else if (DriverInfoData && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_W) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_W))
1609  else
1610  {
1611  struct DriverInfoElement **pDriverInfo;
1612  PLIST_ENTRY ListHead, ItemList;
1613 
1614  if (DeviceInfoData)
1615  {
1616  pDriverInfo = (struct DriverInfoElement **)&((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams.ClassInstallReserved;
1617  ListHead = &((struct DeviceInfo *)DeviceInfoData->Reserved)->DriverListHead;
1618  }
1619  else
1620  {
1621  pDriverInfo = (struct DriverInfoElement **)&((struct DeviceInfoSet *)DeviceInfoSet)->InstallParams.ClassInstallReserved;
1622  ListHead = &((struct DeviceInfoSet *)DeviceInfoSet)->DriverListHead;
1623  }
1624 
1625  if (!DriverInfoData)
1626  {
1627  *pDriverInfo = NULL;
1628  ret = TRUE;
1629  }
1630  else
1631  {
1632  /* Search selected driver in list */
1633  ItemList = ListHead->Flink;
1634  while (ItemList != ListHead)
1635  {
1636  if (DriverInfoData->Reserved != 0)
1637  {
1638  if (DriverInfoData->Reserved == (ULONG_PTR)ItemList)
1639  break;
1640  }
1641  else
1642  {
1643  /* The caller wants to compare only DriverType, Description and ProviderName fields */
1644  struct DriverInfoElement *driverInfo = CONTAINING_RECORD(ItemList, struct DriverInfoElement, ListEntry);
1645  if (driverInfo->Info.DriverType == DriverInfoData->DriverType
1646  && strcmpW(driverInfo->Info.Description, DriverInfoData->Description) == 0
1647  && strcmpW(driverInfo->Info.ProviderName, DriverInfoData->ProviderName) == 0)
1648  {
1649  break;
1650  }
1651  }
1652  ItemList = ItemList->Flink;
1653  }
1654  if (ItemList == ListHead)
1656  else
1657  {
1658  *pDriverInfo = CONTAINING_RECORD(ItemList, struct DriverInfoElement, ListEntry);
1659  DriverInfoData->Reserved = (ULONG_PTR)ItemList;
1660  ret = TRUE;
1661  TRACE("Choosing driver whose rank is 0x%lx\n",
1662  (*pDriverInfo)->Params.Rank);
1663  if (DeviceInfoData)
1664  memcpy(&DeviceInfoData->ClassGuid, &(*pDriverInfo)->ClassGuid, sizeof(GUID));
1665  }
1666  }
1667  }
1668 
1669  TRACE("Returning %d\n", ret);
1670  return ret;
1671 }
1672 
1673 /***********************************************************************
1674  * SetupDiGetDriverInfoDetailA (SETUPAPI.@)
1675  */
1676 BOOL WINAPI
1680  IN PSP_DRVINFO_DATA_A DriverInfoData,
1681  IN OUT PSP_DRVINFO_DETAIL_DATA_A DriverInfoDetailData OPTIONAL,
1682  IN DWORD DriverInfoDetailDataSize,
1684 {
1685  SP_DRVINFO_DATA_V2_W DriverInfoDataW;
1686  PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailDataW = NULL;
1687  DWORD BufSize = 0;
1688  DWORD HardwareIDLen = 0;
1689  BOOL ret = FALSE;
1690 
1691  /* do some sanity checks, the unicode version might do more thorough checks */
1692  if (DriverInfoData == NULL ||
1693  (DriverInfoDetailData == NULL && DriverInfoDetailDataSize != 0) ||
1694  (DriverInfoDetailData != NULL &&
1695  (DriverInfoDetailDataSize < FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_A, HardwareID) + sizeof(CHAR) ||
1696  DriverInfoDetailData->cbSize != sizeof(SP_DRVINFO_DETAIL_DATA_A))))
1697  {
1699  goto Cleanup;
1700  }
1701 
1702  /* make sure we support both versions of the SP_DRVINFO_DATA structure */
1703  if (DriverInfoData->cbSize == sizeof(SP_DRVINFO_DATA_V1_A))
1704  {
1705  DriverInfoDataW.cbSize = sizeof(SP_DRVINFO_DATA_V1_W);
1706  }
1707  else if (DriverInfoData->cbSize == sizeof(SP_DRVINFO_DATA_V2_A))
1708  {
1709  DriverInfoDataW.cbSize = sizeof(SP_DRVINFO_DATA_V2_W);
1710  }
1711  else
1712  {
1714  goto Cleanup;
1715  }
1716  DriverInfoDataW.DriverType = DriverInfoData->DriverType;
1717  DriverInfoDataW.Reserved = DriverInfoData->Reserved;
1718 
1719  /* convert the strings to unicode */
1721  0,
1722  DriverInfoData->Description,
1723  LINE_LEN,
1724  DriverInfoDataW.Description,
1725  LINE_LEN) &&
1727  0,
1728  DriverInfoData->MfgName,
1729  LINE_LEN,
1730  DriverInfoDataW.MfgName,
1731  LINE_LEN) &&
1733  0,
1734  DriverInfoData->ProviderName,
1735  LINE_LEN,
1736  DriverInfoDataW.ProviderName,
1737  LINE_LEN))
1738  {
1739  if (DriverInfoDataW.cbSize == sizeof(SP_DRVINFO_DATA_V2_W))
1740  {
1741  DriverInfoDataW.DriverDate = ((PSP_DRVINFO_DATA_V2_A)DriverInfoData)->DriverDate;
1742  DriverInfoDataW.DriverVersion = ((PSP_DRVINFO_DATA_V2_A)DriverInfoData)->DriverVersion;
1743  }
1744 
1745  if (DriverInfoDetailData != NULL)
1746  {
1747  /* calculate the unicode buffer size from the ansi buffer size */
1748  HardwareIDLen = DriverInfoDetailDataSize - FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_A, HardwareID);
1750  (HardwareIDLen * sizeof(WCHAR));
1751 
1752  DriverInfoDetailDataW = MyMalloc(BufSize);
1753  if (DriverInfoDetailDataW == NULL)
1754  {
1756  goto Cleanup;
1757  }
1758 
1759  /* initialize the buffer */
1760  ZeroMemory(DriverInfoDetailDataW,
1761  BufSize);
1762  DriverInfoDetailDataW->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_W);
1763  }
1764 
1765  /* call the unicode version */
1768  &DriverInfoDataW,
1769  DriverInfoDetailDataW,
1770  BufSize,
1771  RequiredSize);
1772 
1773  if (ret)
1774  {
1775  if (DriverInfoDetailDataW != NULL)
1776  {
1777  /* convert the SP_DRVINFO_DETAIL_DATA_W structure to ansi */
1778  DriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA_A);
1779  DriverInfoDetailData->InfDate = DriverInfoDetailDataW->InfDate;
1780  DriverInfoDetailData->Reserved = DriverInfoDetailDataW->Reserved;
1782  0,
1783  DriverInfoDetailDataW->SectionName,
1784  LINE_LEN,
1785  DriverInfoDetailData->SectionName,
1786  LINE_LEN,
1787  NULL,
1788  NULL) &&
1790  0,
1791  DriverInfoDetailDataW->InfFileName,
1792  MAX_PATH,
1793  DriverInfoDetailData->InfFileName,
1794  MAX_PATH,
1795  NULL,
1796  NULL) &&
1798  0,
1799  DriverInfoDetailDataW->DrvDescription,
1800  LINE_LEN,
1801  DriverInfoDetailData->DrvDescription,
1802  LINE_LEN,
1803  NULL,
1804  NULL) &&
1806  0,
1807  DriverInfoDetailDataW->HardwareID,
1808  HardwareIDLen,
1809  DriverInfoDetailData->HardwareID,
1810  HardwareIDLen,
1811  NULL,
1812  NULL))
1813  {
1814  DWORD len, cnt = 0;
1815  DWORD hwidlen = HardwareIDLen;
1816  CHAR *s = DriverInfoDetailData->HardwareID;
1817 
1818  /* count the strings in the list */
1819  while (*s != '\0')
1820  {
1821  len = lstrlenA(s) + 1;
1822  if (hwidlen > len)
1823  {
1824  cnt++;
1825  s += len;
1826  hwidlen -= len;
1827  }
1828  else
1829  {
1830  /* looks like the string list wasn't terminated... */
1832  ret = FALSE;
1833  break;
1834  }
1835  }
1836 
1837  /* make sure CompatIDsOffset points to the second string in the
1838  list, if present */
1839  if (cnt > 1)
1840  {
1841  DriverInfoDetailData->CompatIDsOffset = lstrlenA(DriverInfoDetailData->HardwareID) + 1;
1842  DriverInfoDetailData->CompatIDsLength = (DWORD)(s - DriverInfoDetailData->HardwareID) -
1843  DriverInfoDetailData->CompatIDsOffset + 1;
1844  }
1845  else
1846  {
1847  DriverInfoDetailData->CompatIDsOffset = 0;
1848  DriverInfoDetailData->CompatIDsLength = 0;
1849  }
1850  }
1851  else
1852  {
1853  ret = FALSE;
1854  }
1855  }
1856 
1857  if (RequiredSize != NULL)
1858  {
1860  (((*RequiredSize) - FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_W, HardwareID)) / sizeof(WCHAR));
1861  }
1862  }
1863  }
1864 
1865 Cleanup:
1866  if (DriverInfoDetailDataW != NULL)
1867  {
1868  MyFree(DriverInfoDetailDataW);
1869  }
1870 
1871  return ret;
1872 }
1873 
1874 /***********************************************************************
1875  * SetupDiGetDriverInfoDetailW (SETUPAPI.@)
1876  */
1877 BOOL WINAPI
1881  IN PSP_DRVINFO_DATA_W DriverInfoData,
1882  IN OUT PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailData OPTIONAL,
1883  IN DWORD DriverInfoDetailDataSize,
1885 {
1886  BOOL ret = FALSE;
1887 
1888  TRACE("%p %p %p %p %lu %p\n", DeviceInfoSet, DeviceInfoData,
1889  DriverInfoData, DriverInfoDetailData,
1890  DriverInfoDetailDataSize, RequiredSize);
1891 
1892  if (!DeviceInfoSet)
1898  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
1900  else if (!DriverInfoData)
1902  else if (!DriverInfoDetailData && DriverInfoDetailDataSize != 0)
1904  else if (DriverInfoDetailData && DriverInfoDetailDataSize < sizeof(SP_DRVINFO_DETAIL_DATA_W))
1906  else if (DriverInfoDetailData && DriverInfoDetailData->cbSize != sizeof(SP_DRVINFO_DETAIL_DATA_W))
1908  else if (DriverInfoData->Reserved == 0)
1910  else
1911  {
1912  struct DriverInfoElement *driverInfoElement;
1913  LPWSTR HardwareIDs = NULL;
1914  LPWSTR CompatibleIDs = NULL;
1915  LPWSTR pBuffer = NULL;
1916  LPCWSTR DeviceID = NULL;
1917  ULONG HardwareIDsSize, CompatibleIDsSize;
1918  ULONG sizeNeeded, sizeLeft, size;
1919  BOOL Result;
1920 
1921  driverInfoElement = (struct DriverInfoElement *)DriverInfoData->Reserved;
1922 
1923  /* Get hardware and compatible IDs lists */
1925  DeviceInfoSet,
1927  &HardwareIDs, &HardwareIDsSize,
1928  &CompatibleIDs, &CompatibleIDsSize);
1929  if (!Result)
1930  goto done;
1931 
1932  sizeNeeded = FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_W, HardwareID)
1933  + HardwareIDsSize + CompatibleIDsSize;
1934  if (RequiredSize)
1935  *RequiredSize = sizeNeeded;
1936 
1937  if (!DriverInfoDetailData)
1938  {
1939  ret = TRUE;
1940  goto done;
1941  }
1942 
1943  memcpy(
1944  DriverInfoDetailData,
1945  &driverInfoElement->Details,
1946  driverInfoElement->Details.cbSize);
1947  DriverInfoDetailData->CompatIDsOffset = 0;
1948  DriverInfoDetailData->CompatIDsLength = 0;
1949 
1950  sizeLeft = (DriverInfoDetailDataSize - FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_W, HardwareID)) / sizeof(WCHAR);
1951  pBuffer = DriverInfoDetailData->HardwareID;
1952  /* Add as many as possible HardwareIDs in the list */
1953  DeviceID = HardwareIDs;
1954  while (DeviceID && *DeviceID && (size = wcslen(DeviceID)) + 1 < sizeLeft)
1955  {
1956  TRACE("Adding %s to list\n", debugstr_w(DeviceID));
1958  DeviceID += size + 1;
1959  pBuffer += size + 1;
1960  sizeLeft -= size + 1;
1961  DriverInfoDetailData->CompatIDsOffset += size + 1;
1962  }
1963  if (sizeLeft > 0)
1964  {
1965  *pBuffer = UNICODE_NULL;
1966  sizeLeft--;
1967  DriverInfoDetailData->CompatIDsOffset++;
1968  }
1969  /* Add as many as possible CompatibleIDs in the list */
1970  DeviceID = CompatibleIDs;
1971  while (DeviceID && *DeviceID && (size = wcslen(DeviceID)) + 1 < sizeLeft)
1972  {
1973  TRACE("Adding %s to list\n", debugstr_w(DeviceID));
1975  DeviceID += size + 1;
1976  pBuffer += size + 1;
1977  sizeLeft -= size + 1;
1978  DriverInfoDetailData->CompatIDsLength += size + 1;
1979  }
1980  if (sizeLeft > 0)
1981  {
1982  *pBuffer = UNICODE_NULL;
1983  sizeLeft--;
1984  DriverInfoDetailData->CompatIDsLength++;
1985  }
1986 
1987  if (sizeNeeded > DriverInfoDetailDataSize)
1989  else
1990  ret = TRUE;
1991 
1992 done:
1993  MyFree(HardwareIDs);
1994  MyFree(CompatibleIDs);
1995  }
1996 
1997  TRACE("Returning %d\n", ret);
1998  return ret;
1999 }
2000 
2001 /***********************************************************************
2002  * SetupDiGetDriverInstallParamsW (SETUPAPI.@)
2003  */
2004 BOOL WINAPI
2008  IN PSP_DRVINFO_DATA_W DriverInfoData,
2009  OUT PSP_DRVINSTALL_PARAMS DriverInstallParams)
2010 {
2011  BOOL ret = FALSE;
2012 
2013  TRACE("%p %p %p %p\n", DeviceInfoSet, DeviceInfoData, DriverInfoData, DriverInstallParams);
2014 
2015  if (!DeviceInfoSet || !DriverInfoData || !DriverInstallParams)
2021  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
2023  else if (DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V1_W) && DriverInfoData->cbSize != sizeof(SP_DRVINFO_DATA_V2_W))
2025  else if (DriverInstallParams->cbSize != sizeof(SP_DRVINSTALL_PARAMS))
2027  else
2028  {
2029  SP_DEVINSTALL_PARAMS InstallParams;
2030 
2031  InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
2033  {
2034  struct DriverInfoElement *driverInfo;
2035  driverInfo = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
2036  if (driverInfo == NULL)
2038  else
2039  {
2040  memcpy(
2041  DriverInstallParams,
2042  &driverInfo->Params,
2043  DriverInstallParams->cbSize);
2044  ret = TRUE;
2045  }
2046  }
2047  }
2048 
2049  TRACE("Returning %d\n", ret);
2050  return ret;
2051 }
2052 
2053 /***********************************************************************
2054  * SetupDiSelectBestCompatDrv (SETUPAPI.@)
2055  */
2056 BOOL WINAPI
2060 {
2061  SP_DRVINFO_DATA_W drvInfoData;
2062  BOOL ret;
2063 
2064  TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
2065 
2066  /* Drivers are sorted by rank in the driver list, so
2067  * the first driver in the list is the best one.
2068  */
2069  drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA_W);
2071  DeviceInfoSet,
2074  0, /* Member index */
2075  &drvInfoData);
2076 
2077  if (ret)
2078  {
2080  DeviceInfoSet,
2082  &drvInfoData);
2083  }
2084 
2085  TRACE("Returning %d\n", ret);
2086  return ret;
2087 }
2088 
2089 /***********************************************************************
2090  * SetupDiInstallDriverFiles (SETUPAPI.@)
2091  */
2092 BOOL WINAPI
2096 {
2097  BOOL ret = FALSE;
2098 
2099  TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
2100 
2101  if (!DeviceInfoSet)
2107  else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
2109  else if (DeviceInfoData && ((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams.ClassInstallReserved == 0)
2111  else if (!DeviceInfoData && ((struct DeviceInfoSet *)DeviceInfoSet)->InstallParams.ClassInstallReserved == 0)
2113  else
2114  {
2115  SP_DEVINSTALL_PARAMS_W InstallParams;
2116  struct DriverInfoElement *SelectedDriver;
2117  WCHAR SectionName[MAX_PATH];
2118  DWORD SectionNameLength = 0;
2119  PVOID InstallMsgHandler;
2120  PVOID InstallMsgHandlerContext;
2121  PVOID Context = NULL;
2122 
2123  InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
2125  if (!ret)
2126  goto done;
2127 
2128  SelectedDriver = (struct DriverInfoElement *)InstallParams.ClassInstallReserved;
2129  if (!SelectedDriver)
2130  {
2132  goto done;
2133  }
2134 
2136  SelectedDriver->InfFileDetails->hInf,
2137  SelectedDriver->Details.SectionName,
2138  SectionName, MAX_PATH - strlenW(DotCoInstallers), &SectionNameLength, NULL);
2139  if (!ret)
2140  goto done;
2141 
2142  if (InstallParams.InstallMsgHandler)
2143  {
2144  InstallMsgHandler = InstallParams.InstallMsgHandler;
2145  InstallMsgHandlerContext = InstallParams.InstallMsgHandlerContext;
2146  }
2147  else
2148  {
2150  if (!Context)
2151  goto cleanup;
2152  InstallMsgHandler = SetupDefaultQueueCallbackW;
2153  InstallMsgHandlerContext = Context;
2154  }
2155  ret = SetupInstallFromInfSectionW(InstallParams.hwndParent,
2156  SelectedDriver->InfFileDetails->hInf, SectionName,
2157  SPINST_FILES, NULL, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
2158  InstallMsgHandler, InstallMsgHandlerContext,
2160  if (!ret)
2161  goto done;
2162 
2163  /* Install files from .CoInstallers section */
2164  lstrcatW(SectionName, DotCoInstallers);
2165  ret = SetupInstallFromInfSectionW(InstallParams.hwndParent,
2166  SelectedDriver->InfFileDetails->hInf, SectionName,
2167  SPINST_FILES, NULL, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
2168  InstallMsgHandler, InstallMsgHandlerContext,
2170  if (!ret)
2171  goto done;
2172 
2173  /* Set the DI_NOFILECOPY flag to prevent another
2174  * installation during SetupDiInstallDevice */
2175  InstallParams.Flags |= DI_NOFILECOPY;
2177 
2178 cleanup:
2179  if (Context)
2181  }
2182 
2183 done:
2184  TRACE("Returning %d\n", ret);
2185  return ret;
2186 }
struct _LARGE_INTEGER::@2220 u
SP_DRVINFO_DATA_V2_W * PSP_DRVINFO_DATA_W
Definition: setupapi.h:1048
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
_Out_opt_ PULONG Minor
Definition: cmfuncs.h:44
#define DICD_INHERIT_CLASSDRVS
Definition: setupapi.h:111
BOOL WINAPI SetupFindFirstLineW(IN HINF InfHandle, IN PCWSTR Section, IN PCWSTR Key, IN OUT PINFCONTEXT Context)
Definition: infsupp.c:54
WCHAR MfgName[LINE_LEN]
Definition: setupapi.h:1012
BOOL WINAPI SetupDiSelectBestCompatDrv(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
Definition: driver.c:2057
static BOOL GetVersionInformationFromInfFile(IN HINF hInf, OUT LPGUID ClassGuid, OUT LPWSTR *pProviderName, OUT FILETIME *DriverDate, OUT DWORDLONG *DriverVersion)
Definition: driver.c:311
#define IN
Definition: typedefs.h:38
static const WCHAR ClassGUID[]
Definition: driver.c:25
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2396
BOOL WINAPI SetupDiGetActualSectionToInstallW(HINF InfHandle, PCWSTR InfSectionName, PWSTR InfSectionWithExt, DWORD InfSectionWithExtSize, PDWORD RequiredSize, PWSTR *Extension)
Definition: devinst.c:1985
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CloseHandle
Definition: compat.h:406
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
SP_DRVINSTALL_PARAMS Params
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define INF_STYLE_WIN4
Definition: infsupp.h:41
struct _SP_DRVINFO_DATA_V2_W SP_DRVINFO_DATA_V2_W
#define ERROR_SUCCESS
Definition: deptool.c:10
LIST_ENTRY ListHead
#define WideCharToMultiByte
Definition: compat.h:101
static const WCHAR DotCoInstallers[]
Definition: driver.c:26
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
#define DI_MULTMFGS
Definition: setupapi.h:56
BOOL WINAPI SetupDiSetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4563
WORD wMonth
Definition: winbase.h:878
#define REG_BINARY
Definition: nt_native.h:1496
POINT last
Definition: font.c:46
BOOL WINAPI SetupDiEnumDriverInfoW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN DWORD DriverType, IN DWORD MemberIndex, OUT PSP_DRVINFO_DATA_W DriverInfoData)
Definition: driver.c:1355
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
#define CP_ACP
Definition: compat.h:99
char CHAR
Definition: xmlstorage.h:175
static const WCHAR szData[]
Definition: msipriv.h:1195
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
_In_ USHORT DeviceID
Definition: iotypes.h:860
#define ERROR_DATATYPE_MISMATCH
Definition: winerror.h:987
BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize)
Definition: devinst.c:3229
#define REGSTR_VAL_INFPATH
Definition: regstr.h:439
BOOL WINAPI SetupDiEnumDriverInfoA(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN DWORD DriverType, IN DWORD MemberIndex, OUT PSP_DRVINFO_DATA_A DriverInfoData)
Definition: driver.c:1291
u32_t magic(void)
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define RRF_RT_REG_EXPAND_SZ
Definition: driver.c:576
#define RRF_RT_REG_SZ
Definition: driver.c:575
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
static const WCHAR INF_PROVIDER[]
Definition: driver.c:31
SP_DEVINSTALL_PARAMS_W InstallParams
SP_DEVINSTALL_PARAMS_W InstallParams
uint16_t * PWCHAR
Definition: typedefs.h:54
#define DI_FLAGSEX_ALLOWEXCLUDEDDRVS
Definition: setupapi.h:87
static LONG WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: driver.c:627
#define InsertTailList(ListHead, Entry)
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
#define RRF_RT_REG_MULTI_SZ
Definition: driver.c:579
const char * filename
Definition: ioapi.h:135
static const WCHAR InfDirectory[]
Definition: driver.c:27
#define DWORD
Definition: nt_native.h:44
_In_ ULONG Revision
Definition: rtlfuncs.h:1104
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define SETUP_DEVICE_INFO_SET_MAGIC
#define FILE_SHARE_READ
Definition: compat.h:125
VOID WINAPI SetupCloseInfFile(IN HINF InfHandle)
Definition: infsupp.c:43
#define lstrcpynW
Definition: compat.h:405
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct InfFileDetails * InfFileDetails
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define DI_DIDCLASS
Definition: setupapi.h:51
#define RRF_RT_REG_NONE
Definition: driver.c:574
BOOL WINAPI SetupGetInfFileListW(IN PCWSTR DirectoryPath OPTIONAL, IN DWORD InfStyle, IN OUT PWSTR ReturnBuffer OPTIONAL, IN DWORD ReturnBufferSize OPTIONAL, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2139
DWORD dwHighDateTime
Definition: mapidefs.h:66
while(1)
Definition: macro.lex.yy.c:740
PSP_FILE_CALLBACK_W InstallMsgHandler
Definition: setupapi.h:890
WORD wYear
Definition: winbase.h:877
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
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
static const WCHAR BackSlash[]
Definition: driver.c:24
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define UNICODE_NULL
RPC_STATUS WINAPI UuidFromStringW(RPC_WSTR s, UUID *uuid)
Definition: rpcrt4_main.c:612
DWORDLONG DriverVersion
Definition: setupapi.h:1015
#define SP_COPY_NEWER
Definition: setupapi.h:473
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
#define DI_NOFILECOPY
Definition: setupapi.h:69
static VOID RegpApplyRestrictions(DWORD dwFlags, DWORD dwType, DWORD cbData, PLONG ret)
Definition: driver.c:587
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
SP_DRVINFO_DATA_V2_W Info
BOOL WINAPI SetupDiGetDeviceInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
Definition: devinst.c:4456
static BOOL AddKnownDriverToList(IN PLIST_ENTRY DriverListHead, IN DWORD DriverType, IN LPGUID ClassGuid, IN struct InfFileDetails *InfFileDetails, IN LPCWSTR InfFile, IN LPCWSTR SectionName, IN LPCWSTR DriverDescription, IN LPCWSTR ProviderName, IN LPCWSTR ManufacturerName, IN LPCWSTR MatchingId, IN FILETIME DriverDate, IN DWORDLONG DriverVersion, IN DWORD Rank)
Definition: driver.c:106
#define DI_DIDCOMPAT
Definition: setupapi.h:50
struct _SP_DRVINFO_DATA_V2_A * PSP_DRVINFO_DATA_V2_A
ULONG_PTR ClassInstallReserved
Definition: setupapi.h:893
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3748
smooth NULL
Definition: ftsmooth.c:416
PVOID pBuffer
PVOID InstallMsgHandlerContext
Definition: setupapi.h:891
_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:426
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
WCHAR Description[LINE_LEN]
Definition: setupapi.h:1011
Definition: bufpool.h:45
#define SPDIT_COMPATDRIVER
Definition: setupapi.h:501
#define BufSize
Definition: FsRtlTunnel.c:28
#define ERROR_UNSUPPORTED_TYPE
Definition: winerror.h:988
#define SPINST_FILES
Definition: setupapi.h:587
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define OPEN_EXISTING
Definition: compat.h:434
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG_PTR Reserved
Definition: setupapi.h:833
#define RRF_RT_DWORD
Definition: driver.c:581
static const WCHAR HKLM[]
Definition: reginf.c:58
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
ULONG_PTR ClassInstallReserved
Definition: setupapi.h:881
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
BOOL WINAPI SetupDiGetSelectedDriverA(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, OUT PSP_DRVINFO_DATA_A DriverInfoData)
Definition: driver.c:1420
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
struct _SP_DRVINFO_DATA_V1_W SP_DRVINFO_DATA_V1_W
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
BOOL DestroyDriverInfoElement(struct DriverInfoElement *driverInfo)
Definition: driver.c:94
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define RRF_ZEROONFAILURE
Definition: driver.c:584
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_GUID_STRING_LEN
Definition: apphelp.c:29
#define LINE_LEN
Definition: setupapi.h:20
#define RRF_RT_QWORD
Definition: driver.c:582
#define MAX_PATH
Definition: compat.h:26
WCHAR HardwareID[ANYSIZE_ARRAY]
Definition: setupapi.h:1074
#define WINAPI
Definition: msvc.h:6
BOOL WINAPI SetupDiGetDriverInfoDetailA(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_DRVINFO_DATA_A DriverInfoData, IN OUT PSP_DRVINFO_DETAIL_DATA_A DriverInfoDetailData OPTIONAL, IN DWORD DriverInfoDetailDataSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: driver.c:1677
#define CopyMemory
Definition: winbase.h:1640
_In_opt_ PSP_DEVINFO_DATA DeviceInfoData
Definition: setupapi.h:1523
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
static VOID ReferenceInfFile(struct InfFileDetails *infFile)
Definition: driver.c:39
#define SetLastError(x)
Definition: compat.h:417
#define SPDRP_HARDWAREID
Definition: setupapi.h:503
static const WCHAR INF_MANUFACTURER[]
Definition: driver.c:30
#define ERROR_NO_DRIVER_SELECTED
Definition: setupapi.h:294
BOOL WINAPI SetupInstallFromInfSectionW(HWND owner, HINF hinf, PCWSTR section, UINT flags, HKEY key_root, PCWSTR src_root, UINT copy_flags, PSP_FILE_CALLBACK_W callback, PVOID context, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data)
Definition: install.c:1327
WCHAR ProviderName[LINE_LEN]
Definition: setupapi.h:1013
int ret
ULONG WINAPI SetupGetFieldCount(IN PINFCONTEXT Context)
Definition: infsupp.c:91
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
WCHAR DriverPath[MAX_PATH]
Definition: setupapi.h:895
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
LIST_ENTRY DriverListHead
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
SP_DRVINFO_DATA_V2_W SP_DRVINFO_DATA_W
Definition: setupapi.h:1048
UINT WINAPI SetupDefaultQueueCallbackW(PVOID context, UINT notification, UINT_PTR param1, UINT_PTR param2)
Definition: queue.c:1777
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
void WINAPI SetupTermDefaultQueueCallback(PVOID context)
Definition: queue.c:1704
#define GUID_NULL
Definition: ks.h:106
GLdouble s
Definition: gl.h:2039
Definition: _list.h:228
#define GENERIC_READ
Definition: compat.h:124
Definition: typedefs.h:117
HKEY SETUPDI_OpenDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
Definition: devinst.c:5842
static const WCHAR Cleanup[]
Definition: register.c:80
BOOL WINAPI SetupDiSetSelectedDriverW(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN OUT PSP_DRVINFO_DATA_W DriverInfoData OPTIONAL)
Definition: driver.c:1590
_In_ HANDLE hFile
Definition: mswsock.h:90
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define DI_FLAGSEX_DIDINFOLIST
Definition: setupapi.h:80
struct _SP_DRVINFO_DETAIL_DATA_A SP_DRVINFO_DETAIL_DATA_A
ULARGE_INTEGER DriverDate
#define strcmpiW(s1, s2)
Definition: unicode.h:39
WINE_UNICODE_INLINE WCHAR * strrchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:254
BOOL WINAPI SetupDiDestroyDriverInfoList(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN DWORD DriverType)
Definition: driver.c:1208
WORD wDay
Definition: winbase.h:880
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
BOOL WINAPI SetupDiGetSelectedDriverW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, OUT PSP_DRVINFO_DATA_W DriverInfoData)
Definition: driver.c:1479
#define SPDRP_COMPATIBLEIDS
Definition: setupapi.h:504
static unsigned __int64 next
Definition: rand_nt.c:6
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define InterlockedIncrement
Definition: armddk.h:53
#define REGSTR_VAL_INFSECTION
Definition: regstr.h:440
#define DI_FLAGSEX_DIDCOMPATINFO
Definition: setupapi.h:81
#define RRF_NOEXPAND
Definition: driver.c:583
PVOID WINAPI SetupInitDefaultQueueCallback(HWND owner)
Definition: queue.c:1677
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
BOOL WINAPI SetupDiSetSelectedDriverA(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN OUT PSP_DRVINFO_DATA_A DriverInfoData OPTIONAL)
Definition: driver.c:1528
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define list
Definition: rosglue.h:35
WCHAR ProviderName[LINE_LEN]
Definition: setupapi.h:1031
static BOOL AddDriverToList(IN PLIST_ENTRY DriverListHead, IN DWORD DriverType, IN LPGUID ClassGuid, IN INFCONTEXT ContextDevice, IN struct InfFileDetails *InfFileDetails, IN LPCWSTR InfFile, IN LPCWSTR ProviderName, IN LPCWSTR ManufacturerName, IN LPCWSTR MatchingId, IN FILETIME DriverDate, IN DWORDLONG DriverVersion, IN DWORD Rank)
Definition: driver.c:238
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
DWORD * PDWORD
Definition: pedump.c:68
BOOL WINAPI SetupFindNextLine(IN PINFCONTEXT ContextIn, OUT PINFCONTEXT ContextOut)
Definition: infsupp.c:80
WCHAR SectionName[LINE_LEN]
Definition: setupapi.h:1071
struct _SP_DRVINFO_DETAIL_DATA_W SP_DRVINFO_DETAIL_DATA_W
static const WCHAR INF_DRIVER_VER[]
Definition: driver.c:32
#define MultiByteToWideChar
Definition: compat.h:100
#define DI_ENUMSINGLEINF
Definition: setupapi.h:62
#define CreateFileW
Definition: compat.h:408
struct _SP_DEVINSTALL_PARAMS_W SP_DEVINSTALL_PARAMS_W
LIST_ENTRY ListEntry
unsigned long long DWORDLONG
Definition: intsafe.h:99
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
#define OUT
Definition: typedefs.h:39
BOOL WINAPI SetupDiBuildDriverInfoList(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN DWORD DriverType)
Definition: driver.c:718
SP_DRVINFO_DETAIL_DATA_W Details
uint32_t * LPDWORD
Definition: typedefs.h:57
struct tagContext Context
Definition: acpixf.h:1030
VOID DereferenceInfFile(struct InfFileDetails *infFile)
Definition: driver.c:45
#define REG_QWORD
Definition: sdbapi.c:597
unsigned int ULONG
Definition: retypes.h:1
#define SPDIT_CLASSDRIVER
Definition: setupapi.h:500
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
int details
Definition: msacm.c:1365
#define ULONG_PTR
Definition: config.h:101
struct InfFileDetails * CreateInfFileDetails(IN LPCWSTR FullInfFileName)
Definition: driver.c:55
char * cleanup(char *str)
Definition: wpickclick.c:99
WCHAR DrvDescription[LINE_LEN]
Definition: setupapi.h:1073
BOOL WINAPI SetupDiGetDriverInstallParamsW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_DRVINFO_DATA_W DriverInfoData, OUT PSP_DRVINSTALL_PARAMS DriverInstallParams)
Definition: driver.c:2005
LPVOID WINAPI MyMalloc(DWORD dwSize)
Definition: misc.c:147
static BOOL GetHardwareAndCompatibleIDsLists(IN HDEVINFO DeviceInfoSet, IN OUT PSP_DEVINFO_DATA DeviceInfoData, OUT LPWSTR *pHardwareIDs OPTIONAL, OUT LPDWORD pHardwareIDsRequiredSize OPTIONAL, OUT LPWSTR *pCompatibleIDs OPTIONAL, OUT LPDWORD pCompatibleIDsRequiredSize OPTIONAL)
Definition: driver.c:466
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
#define REG_NONE
Definition: nt_native.h:1492
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI SetupDiInstallDriverFiles(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData)
Definition: driver.c:2093
WCHAR Description[LINE_LEN]
Definition: setupapi.h:1029
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:596
signed int * PLONG
Definition: retypes.h:5
VOID WINAPI MyFree(LPVOID lpMem)
Definition: misc.c:128
#define RRF_RT_REG_DWORD
Definition: driver.c:578
BOOL WINAPI SetupDiGetDriverInfoDetailW(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL, IN PSP_DRVINFO_DATA_W DriverInfoData, IN OUT PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailData OPTIONAL, IN DWORD DriverInfoDetailDataSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: driver.c:1878
BYTE * PBYTE
Definition: pedump.c:66
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:1046
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:402
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
DWORD dwLowDateTime
Definition: mapidefs.h:65
WCHAR InfFileName[MAX_PATH]
Definition: setupapi.h:1072
#define RPC_S_OK
Definition: rpcnterr.h:22
struct _SP_DRVINSTALL_PARAMS SP_DRVINSTALL_PARAMS
WINE_UNICODE_INLINE int atoiW(const WCHAR *str)
Definition: unicode.h:315
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4953
#define RRF_RT_REG_QWORD
Definition: driver.c:580
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RRF_RT_REG_BINARY
Definition: driver.c:577
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1756
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOL WINAPI SetupGetStringFieldW(IN PINFCONTEXT Context, IN ULONG FieldIndex, OUT PWSTR ReturnBuffer, IN ULONG ReturnBufferSize, OUT PULONG RequiredSize)
Definition: infsupp.c:184