ReactOS  0.4.15-dev-1033-gd7d716a
cfgmgr.c
Go to the documentation of this file.
1 /*
2  * Configuration manager functions
3  *
4  * Copyright 2000 James Hatheway
5  * Copyright 2005, 2006 Eric Kohl
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 <dbt.h>
25 #include <pnp_c.h>
26 #include <winsvc.h>
27 
28 #include "rpc_private.h"
29 
30 DWORD
31 WINAPI
33  OUT LPWSTR lpServiceName,
34  IN DWORD cchServiceName);
35 
36 
37 /* Registry key and value names */
38 static const WCHAR Backslash[] = {'\\', 0};
39 static const WCHAR Class[] = {'C','l','a','s','s',0};
40 
41 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
42  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
43  'C','o','n','t','r','o','l','\\',
44  'C','l','a','s','s',0};
45 
46 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
47  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
48  'C','o','n','t','r','o','l','\\',
49  'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
50 
51 typedef struct _MACHINE_INFO
52 {
58 
59 
60 typedef struct _LOG_CONF_INFO
61 {
67 
68 #define LOG_CONF_MAGIC 0x464E434C /* "LCNF" */
69 
70 
71 typedef struct _NOTIFY_DATA
72 {
76 
77 #define NOTIFY_MAGIC 0x44556677
78 
79 
80 typedef struct _INTERNAL_RANGE
81 {
87 
88 typedef struct _INTERNAL_RANGE_LIST
89 {
94 
95 #define RANGE_LIST_MAGIC 0x33445566
96 
97 typedef struct _CONFLICT_DATA
98 {
102 
103 #define CONFLICT_MAGIC 0x11225588
104 
105 
106 /* FUNCTIONS ****************************************************************/
107 
108 static
109 BOOL
111  _In_ LPGUID Guid,
113 {
114  LPWSTR lpString;
115 
116  if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
117  return FALSE;
118 
119  lstrcpyW(&String[1], lpString);
120 
121  String[0] = '{';
122  String[MAX_GUID_STRING_LEN - 2] = '}';
124 
125  RpcStringFreeW(&lpString);
126 
127  return TRUE;
128 }
129 
130 
131 static
132 CONFIGRET
135 {
136  return CR_FAILURE;
137 }
138 
139 
140 static
141 ULONG
143  _In_ ULONG ulProperty)
144 {
145  switch (ulProperty)
146  {
147  case CM_DRP_DEVICEDESC:
148  case CM_DRP_SERVICE:
149  case CM_DRP_CLASS:
150  case CM_DRP_CLASSGUID:
151  case CM_DRP_DRIVER:
152  case CM_DRP_MFG:
153  case CM_DRP_FRIENDLYNAME:
157  case CM_DRP_SECURITY_SDS:
159  return REG_SZ;
160 
161  case CM_DRP_HARDWAREID:
163  case CM_DRP_UPPERFILTERS:
164  case CM_DRP_LOWERFILTERS:
165  return REG_MULTI_SZ;
166 
167  case CM_DRP_CONFIGFLAGS:
168  case CM_DRP_CAPABILITIES:
169  case CM_DRP_UI_NUMBER:
171  case CM_DRP_BUSNUMBER:
172  case CM_DRP_DEVTYPE:
173  case CM_DRP_EXCLUSIVE:
175  case CM_DRP_ADDRESS:
180  return REG_DWORD;
181 
182  case CM_DRP_BUSTYPEGUID:
183  case CM_DRP_SECURITY:
185  default:
186  return REG_BINARY;
187  }
188 
189  return REG_NONE;
190 }
191 
192 
193 static
194 VOID
196  _In_ PWSTR pszDeviceInstanceId,
197  _Out_ PWSTR pszDeviceId,
198  _Out_ PWSTR pszInstanceId)
199 {
200  PWCHAR ptr;
201 
202  wcscpy(pszDeviceId, pszDeviceInstanceId);
203 
204  ptr = wcschr(pszDeviceId, L'\\');
205  if (ptr != NULL)
206  {
207  *ptr = UNICODE_NULL;
208  ptr++;
209 
210  wcscpy(pszInstanceId, ptr);
211  }
212  else
213  {
214  *pszInstanceId = UNICODE_NULL;
215  }
216 }
217 
218 
219 static
220 CONFIGRET
223  _In_ PWSTR pszDeviceInst,
224  _Out_ PWSTR pszKeyPath,
225  _Out_ PWSTR pszInstancePath,
226  _In_ ULONG ulHardwareProfile,
227  _In_ ULONG ulFlags)
228 {
229  PWSTR pszBuffer = NULL;
230  ULONG ulType = 0;
231  ULONG ulTransferLength, ulLength;
233 
234  TRACE("GetDeviceInstanceKeyPath()\n");
235 
236  /* Allocate a buffer for the device id */
237  pszBuffer = MyMalloc(300 * sizeof(WCHAR));
238  if (pszBuffer == NULL)
239  {
240  ERR("MyMalloc() failed\n");
241  return CR_OUT_OF_MEMORY;
242  }
243 
244  if (ulFlags & CM_REGISTRY_SOFTWARE)
245  {
246  /* Software Key Path */
247 
248  ulTransferLength = 300 * sizeof(WCHAR);
249  ulLength = 300 * sizeof(WCHAR);
250 
252  {
254  pszDeviceInst,
256  &ulType,
257  (PVOID)pszBuffer,
258  &ulTransferLength,
259  &ulLength,
260  0);
261  }
263  {
265  }
266  RpcEndExcept;
267 
268  if (ret != CR_SUCCESS)
269  {
271  {
273  pszDeviceInst,
274  (PVOID)pszBuffer,
275  300);
276  }
278  {
280  }
281  RpcEndExcept;
282 
283  if (ret != CR_SUCCESS)
284  {
285  goto done;
286  }
287  }
288 
289  TRACE("szBuffer: %S\n", pszBuffer);
290 
291  SplitDeviceInstanceId(pszBuffer,
292  pszBuffer,
293  pszInstancePath);
294 
295  TRACE("szBuffer: %S\n", pszBuffer);
296 
297  if (ulFlags & CM_REGISTRY_CONFIG)
298  {
299  if (ulHardwareProfile == 0)
300  {
301  wsprintfW(pszKeyPath,
302  L"%s\\%s\\%s\\%s",
303  L"System\\CurrentControlSet\\Hardware Profiles",
304  L"Current",
305  L"System\\CurrentControlSet\\Control\\Class",
306  pszBuffer);
307  }
308  else
309  {
310  wsprintfW(pszKeyPath,
311  L"%s\\%04lu\\%s\\%s",
312  L"System\\CurrentControlSet\\Hardware Profiles",
313  ulHardwareProfile,
314  L"System\\CurrentControlSet\\Control\\Class",
315  pszBuffer);
316  }
317  }
318  else
319  {
320  wsprintfW(pszKeyPath,
321  L"%s\\%s",
322  L"System\\CurrentControlSet\\Control\\Class",
323  pszBuffer);
324  }
325  }
326  else
327  {
328  /* Hardware Key Path */
329 
330  if (ulFlags & CM_REGISTRY_CONFIG)
331  {
332  SplitDeviceInstanceId(pszDeviceInst,
333  pszBuffer,
334  pszInstancePath);
335 
336  if (ulHardwareProfile == 0)
337  {
338  wsprintfW(pszKeyPath,
339  L"%s\\%s\\%s\\%s",
340  L"System\\CurrentControlSet\\Hardware Profiles",
341  L"Current",
342  L"System\\CurrentControlSet\\Enum",
343  pszBuffer);
344  }
345  else
346  {
347  wsprintfW(pszKeyPath,
348  L"%s\\%04lu\\%s\\%s",
349  L"System\\CurrentControlSet\\Hardware Profiles",
350  ulHardwareProfile,
351  L"System\\CurrentControlSet\\Enum",
352  pszBuffer);
353  }
354  }
355  else if (ulFlags & CM_REGISTRY_USER)
356  {
357  wsprintfW(pszKeyPath,
358  L"%s\\%s",
359  L"System\\CurrentControlSet\\Enum",
360  pszDeviceInst);
361 
362  wcscpy(pszInstancePath,
363  L"Device Parameters");
364  }
365  else
366  {
367  SplitDeviceInstanceId(pszDeviceInst,
368  pszBuffer,
369  pszInstancePath);
370 
371  wsprintfW(pszKeyPath,
372  L"%s\\%s",
373  L"System\\CurrentControlSet\\Enum",
374  pszBuffer);
375  }
376  }
377 
378 done:
379  if (pszBuffer != NULL)
380  MyFree(pszBuffer);
381 
382  return ret;
383 }
384 
385 
386 BOOL
388  _In_opt_ PINTERNAL_RANGE_LIST pRangeList)
389 {
390  BOOL bValid = TRUE;
391 
392  if (pRangeList == NULL)
393  return FALSE;
394 
395  _SEH2_TRY
396  {
397  if (pRangeList->ulMagic != RANGE_LIST_MAGIC)
398  bValid = FALSE;
399  }
401  {
402  bValid = FALSE;
403  }
404  _SEH2_END;
405 
406  return bValid;
407 }
408 
409 
410 BOOL
412  _In_opt_ PLOG_CONF_INFO pLogConfInfo)
413 {
414  BOOL bValid = TRUE;
415 
416  if (pLogConfInfo == NULL)
417  return FALSE;
418 
419  _SEH2_TRY
420  {
421  if (pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
422  bValid = FALSE;
423  }
425  {
426  bValid = FALSE;
427  }
428  _SEH2_END;
429 
430  return bValid;
431 }
432 
433 
434 BOOL
436  _In_opt_ PCONFLICT_DATA pConflictData)
437 {
438  BOOL bValid = TRUE;
439 
440  if (pConflictData == NULL)
441  return FALSE;
442 
443  _SEH2_TRY
444  {
445  if (pConflictData->ulMagic != CONFLICT_MAGIC)
446  bValid = FALSE;
447  }
449  {
450  bValid = FALSE;
451  }
452  _SEH2_END;
453 
454  return bValid;
455 }
456 
457 
458 /***********************************************************************
459  * CMP_GetBlockedDriverInfo [SETUPAPI.@]
460  */
461 CONFIGRET
462 WINAPI
464  _Out_opt_ LPWSTR pszNames,
465  _Inout_ PULONG pulLength,
466  _In_ ULONG ulFlags,
467  _In_opt_ HMACHINE hMachine)
468 {
470  ULONG ulTransferLength;
471  CONFIGRET ret;
472 
473  TRACE("CMP_GetBlockedDriverInfo(%p %p %lx %p)\n",
474  pszNames, pulLength, ulFlags, hMachine);
475 
476  if (hMachine != NULL)
477  {
478  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
479  if (BindingHandle == NULL)
480  return CR_FAILURE;
481  }
482  else
483  {
485  return CR_FAILURE;
486  }
487 
488  ulTransferLength = *pulLength;
489 
491  {
493  (PBYTE)pszNames,
494  &ulTransferLength,
495  pulLength,
496  ulFlags);
497  }
499  {
501  }
502  RpcEndExcept;
503 
504  return ret;
505 }
506 
507 
508 /***********************************************************************
509  * CMP_GetServerSideDeviceInstallFlags [SETUPAPI.@]
510  */
511 CONFIGRET
512 WINAPI
514  _Out_ PULONG pulSSDIFlags,
515  _In_ ULONG ulFlags,
516  _In_opt_ HMACHINE hMachine)
517 {
519  CONFIGRET ret;
520 
521  TRACE("CMP_GetServerSideDeviceInstallFlags(%p %lx %p)\n",
522  pulSSDIFlags, ulFlags, hMachine);
523 
524  if (pulSSDIFlags == NULL)
525  return CR_INVALID_POINTER;
526 
527  if (ulFlags != 0)
528  return CR_INVALID_FLAG;
529 
530  if (hMachine != NULL)
531  {
532  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
533  if (BindingHandle == NULL)
534  return CR_FAILURE;
535  }
536  else
537  {
539  return CR_FAILURE;
540  }
541 
543  {
545  pulSSDIFlags,
546  ulFlags);
547  }
549  {
551  }
552  RpcEndExcept;
553 
554  return ret;
555 }
556 
557 
558 /***********************************************************************
559  * CMP_Init_Detection [SETUPAPI.@]
560  */
561 CONFIGRET
562 WINAPI
564  _In_ ULONG ulMagic)
565 {
567  CONFIGRET ret;
568 
569  TRACE("CMP_Init_Detection(%lu)\n", ulMagic);
570 
571  if (ulMagic != CMP_MAGIC)
572  return CR_INVALID_DATA;
573 
575  return CR_FAILURE;
576 
578  {
580  }
582  {
584  }
585  RpcEndExcept;
586 
587  return ret;
588 }
589 
590 
591 /***********************************************************************
592  * CMP_RegisterNotification [SETUPAPI.@]
593  */
594 CONFIGRET
595 WINAPI
597  _In_ HANDLE hRecipient,
598  _In_ LPVOID lpvNotificationFilter,
599  _In_ ULONG ulFlags,
600  _Out_ PHDEVNOTIFY phDevNotify)
601 {
603  PNOTIFY_DATA pNotifyData = NULL;
604  WCHAR szNameBuffer[256];
605  INT nLength;
606  DWORD ulUnknown9 = 0;
607  DWORD dwError;
609 
610  FIXME("CMP_RegisterNotification(%p %p %lu %p)\n",
611  hRecipient, lpvNotificationFilter, ulFlags, phDevNotify);
612 
613  if ((hRecipient == NULL) ||
614  (lpvNotificationFilter == NULL) ||
615  (phDevNotify == NULL))
616  return CR_INVALID_POINTER;
617 
618  if (ulFlags & ~0x7)
619  return CR_INVALID_FLAG;
620 
621  if (((PDEV_BROADCAST_HDR)lpvNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR))
622  return CR_INVALID_DATA;
623 
625  return CR_FAILURE;
626 
627  pNotifyData = HeapAlloc(GetProcessHeap(),
629  sizeof(NOTIFY_DATA));
630  if (pNotifyData == NULL)
631  return CR_OUT_OF_MEMORY;
632 
633  pNotifyData->ulMagic = NOTIFY_MAGIC;
634 
635  if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
636  {
637  FIXME("Register a window\n");
638 
639  nLength = GetWindowTextW((HWND)hRecipient,
640  szNameBuffer,
641  ARRAYSIZE(szNameBuffer));
642  if (nLength == 0)
643  {
644  HeapFree(GetProcessHeap(), 0, pNotifyData);
645  return CR_INVALID_DATA;
646  }
647 
648  FIXME("Register window: %S\n", szNameBuffer);
649  }
650  else if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_SERVICE_HANDLE)
651  {
652  FIXME("Register a service\n");
653 
654  dwError = I_ScPnPGetServiceName((SERVICE_STATUS_HANDLE)hRecipient,
655  szNameBuffer,
656  ARRAYSIZE(szNameBuffer));
657  if (dwError != ERROR_SUCCESS)
658  {
659  HeapFree(GetProcessHeap(), 0, pNotifyData);
660  return CR_INVALID_DATA;
661  }
662 
663  FIXME("Register service: %S\n", szNameBuffer);
664  }
665 
667  {
669  0, /* ??? */
670  szNameBuffer,
671  (BYTE*)lpvNotificationFilter,
672  ((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size,
673  ulFlags,
674  &pNotifyData->ulNotifyData,
675  0, /* ??? */
676  &ulUnknown9); /* ??? */
677  }
679  {
681  }
682  RpcEndExcept;
683 
684  if (ret == CR_SUCCESS)
685  {
686  *phDevNotify = (HDEVNOTIFY)pNotifyData;
687  }
688  else
689  {
690  if (pNotifyData != NULL)
691  HeapFree(GetProcessHeap(), 0, pNotifyData);
692 
693  *phDevNotify = (HDEVNOTIFY)NULL;
694  }
695 
696  return ret;
697 }
698 
699 
700 /***********************************************************************
701  * CMP_Report_LogOn [SETUPAPI.@]
702  */
703 CONFIGRET
704 WINAPI
706  _In_ DWORD dwMagic,
707  _In_ DWORD dwProcessId)
708 {
711  BOOL bAdmin;
712  DWORD i;
713 
714  TRACE("CMP_Report_LogOn(%lu %lu)\n", dwMagic, dwProcessId);
715 
716  if (dwMagic != CMP_MAGIC)
717  return CR_INVALID_DATA;
718 
720  return CR_FAILURE;
721 
722  bAdmin = pSetupIsUserAdmin();
723 
724  for (i = 0; i < 30; i++)
725  {
727  {
729  bAdmin,
730  dwProcessId);
731  }
733  {
735  }
736  RpcEndExcept;
737 
738  if (ret == CR_SUCCESS)
739  break;
740 
741  Sleep(5000);
742  }
743 
744  return ret;
745 }
746 
747 
748 /***********************************************************************
749  * CMP_UnregisterNotification [SETUPAPI.@]
750  */
751 CONFIGRET
752 WINAPI
754  _In_ HDEVNOTIFY hDevNotify)
755 {
757  PNOTIFY_DATA pNotifyData;
759 
760  TRACE("CMP_UnregisterNotification(%p)\n", hDevNotify);
761 
762  pNotifyData = (PNOTIFY_DATA)hDevNotify;
763 
764  if ((pNotifyData == NULL) ||
765  (pNotifyData->ulMagic != NOTIFY_MAGIC))
766  return CR_INVALID_POINTER;
767 
769  return CR_FAILURE;
770 
772  {
774  pNotifyData->ulNotifyData);
775  }
777  {
779  }
780  RpcEndExcept;
781 
782  if (ret == CR_SUCCESS)
783  HeapFree(GetProcessHeap(), 0, pNotifyData);
784 
785  return ret;
786 }
787 
788 
789 /***********************************************************************
790  * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
791  */
792 DWORD
793 WINAPI
796 {
797  HANDLE hEvent;
798  DWORD ret;
799 
800  TRACE("CMP_WaitNoPendingInstallEvents(%lu)\n", dwTimeout);
801 
802  hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
803  if (hEvent == NULL)
804  return WAIT_FAILED;
805 
808  return ret;
809 }
810 
811 
812 /***********************************************************************
813  * CMP_WaitServicesAvailable [SETUPAPI.@]
814  */
815 CONFIGRET
816 WINAPI
818  _In_opt_ HMACHINE hMachine)
819 {
822  WORD Version;
823 
824  TRACE("CMP_WaitServicesAvailable(%p)\n", hMachine);
825 
826  if (hMachine != NULL)
827  {
828  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
829  if (BindingHandle == NULL)
830  return CR_FAILURE;
831  }
832  else
833  {
835  return CR_FAILURE;
836  }
837 
839  {
841  }
843  {
845  }
846  RpcEndExcept;
847 
848  return ret;
849 }
850 
851 
852 /***********************************************************************
853  * CM_Add_Empty_Log_Conf [SETUPAPI.@]
854  */
855 CONFIGRET
856 WINAPI
858  _Out_ PLOG_CONF plcLogConf,
859  _In_ DEVINST dnDevInst,
861  _In_ ULONG ulFlags)
862 {
863  TRACE("CM_Add_Empty_Log_Conf(%p %p %lu %lx)\n",
864  plcLogConf, dnDevInst, Priority, ulFlags);
865 
866  return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
867  ulFlags, NULL);
868 }
869 
870 
871 /***********************************************************************
872  * CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
873  */
874 CONFIGRET
875 WINAPI
877  _Out_ PLOG_CONF plcLogConf,
878  _In_ DEVINST dnDevInst,
880  _In_ ULONG ulFlags,
881  _In_opt_ HMACHINE hMachine)
882 {
884  HSTRING_TABLE StringTable = NULL;
885  ULONG ulLogConfTag = 0;
886  LPWSTR lpDevInst;
887  PLOG_CONF_INFO pLogConfInfo;
889 
890  FIXME("CM_Add_Empty_Log_Conf_Ex(%p %p %lu %lx %p)\n",
891  plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
892 
893  if (!pSetupIsUserAdmin())
894  return CR_ACCESS_DENIED;
895 
896  if (plcLogConf == NULL)
897  return CR_INVALID_POINTER;
898 
899  if (dnDevInst == 0)
900  return CR_INVALID_DEVINST;
901 
902  if (Priority > 0xFFFF)
903  return CR_INVALID_PRIORITY;
904 
905  if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
906  return CR_INVALID_FLAG;
907 
908  if (hMachine != NULL)
909  {
910  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
911  if (BindingHandle == NULL)
912  return CR_FAILURE;
913 
914  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
915  if (StringTable == 0)
916  return CR_FAILURE;
917  }
918  else
919  {
920  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
921  return CR_FAILURE;
922  }
923 
924  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
925  if (lpDevInst == NULL)
926  return CR_INVALID_DEVNODE;
927 
929  {
931  &ulLogConfTag, ulFlags);
932  }
934  {
936  }
937  RpcEndExcept;
938 
939  if (ret == CR_SUCCESS)
940  {
941  pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
942  if (pLogConfInfo == NULL)
943  {
945  }
946  else
947  {
948  pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
949  pLogConfInfo->dnDevInst = dnDevInst;
950  pLogConfInfo->ulType = ulFlags;
951  pLogConfInfo->ulTag = ulLogConfTag;
952 
953  *plcLogConf = (LOG_CONF)pLogConfInfo;
954 
955  ret = CR_SUCCESS;
956  }
957  }
958 
959  return ret;
960 }
961 
962 
963 /***********************************************************************
964  * CM_Add_IDA [SETUPAPI.@]
965  */
966 CONFIGRET
967 WINAPI
969  _In_ DEVINST dnDevInst,
970  _In_ PSTR pszID,
971  _In_ ULONG ulFlags)
972 {
973  TRACE("CM_Add_IDA(%p %s %lx)\n",
974  dnDevInst, debugstr_a(pszID), ulFlags);
975 
976  return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
977 }
978 
979 
980 /***********************************************************************
981  * CM_Add_IDW [SETUPAPI.@]
982  */
983 CONFIGRET
984 WINAPI
986  _In_ DEVINST dnDevInst,
987  _In_ PWSTR pszID,
988  _In_ ULONG ulFlags)
989 {
990  TRACE("CM_Add_IDW(%p %s %lx)\n",
991  dnDevInst, debugstr_w(pszID), ulFlags);
992 
993  return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
994 }
995 
996 
997 /***********************************************************************
998  * CM_Add_ID_ExA [SETUPAPI.@]
999  */
1000 CONFIGRET
1001 WINAPI
1003  _In_ DEVINST dnDevInst,
1004  _In_ PSTR pszID,
1005  _In_ ULONG ulFlags,
1006  _In_opt_ HMACHINE hMachine)
1007 {
1008  PWSTR pszIDW;
1009  CONFIGRET ret;
1010 
1011  TRACE("CM_Add_ID_ExA(%p %s %lx %p)\n",
1012  dnDevInst, debugstr_a(pszID), ulFlags, hMachine);
1013 
1014  if (pSetupCaptureAndConvertAnsiArg(pszID, &pszIDW))
1015  return CR_INVALID_DATA;
1016 
1017  ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);
1018 
1019  MyFree(pszIDW);
1020 
1021  return ret;
1022 }
1023 
1024 
1025 /***********************************************************************
1026  * CM_Add_ID_ExW [SETUPAPI.@]
1027  */
1028 CONFIGRET
1029 WINAPI
1031  _In_ DEVINST dnDevInst,
1032  _In_ PWSTR pszID,
1033  _In_ ULONG ulFlags,
1034  _In_opt_ HMACHINE hMachine)
1035 {
1037  HSTRING_TABLE StringTable = NULL;
1038  LPWSTR lpDevInst;
1039  CONFIGRET ret;
1040 
1041  TRACE("CM_Add_ID_ExW(%p %s %lx %p)\n",
1042  dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
1043 
1044  if (!pSetupIsUserAdmin())
1045  return CR_ACCESS_DENIED;
1046 
1047  if (dnDevInst == 0)
1048  return CR_INVALID_DEVINST;
1049 
1050  if (pszID == NULL)
1051  return CR_INVALID_POINTER;
1052 
1053  if (ulFlags & ~CM_ADD_ID_BITS)
1054  return CR_INVALID_FLAG;
1055 
1056  if (hMachine != NULL)
1057  {
1058  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1059  if (BindingHandle == NULL)
1060  return CR_FAILURE;
1061 
1062  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1063  if (StringTable == 0)
1064  return CR_FAILURE;
1065  }
1066  else
1067  {
1068  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1069  return CR_FAILURE;
1070  }
1071 
1072  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1073  if (lpDevInst == NULL)
1074  return CR_INVALID_DEVNODE;
1075 
1076  RpcTryExcept
1077  {
1079  lpDevInst,
1080  pszID,
1081  ulFlags);
1082  }
1084  {
1086  }
1087  RpcEndExcept;
1088 
1089  return ret;
1090 }
1091 
1092 
1093 /***********************************************************************
1094  * CM_Add_Range [SETUPAPI.@]
1095  */
1096 CONFIGRET
1097 WINAPI
1099  _In_ DWORDLONG ullStartValue,
1100  _In_ DWORDLONG ullEndValue,
1101  _In_ RANGE_LIST rlh,
1102  _In_ ULONG ulFlags)
1103 {
1104  PINTERNAL_RANGE_LIST pRangeList;
1105  PINTERNAL_RANGE pRange;
1107 
1108  FIXME("CM_Add_Range(%I64u %I64u %p %lx)\n",
1109  ullStartValue, ullEndValue, rlh, ulFlags);
1110 
1111  pRangeList = (PINTERNAL_RANGE_LIST)rlh;
1112 
1113  if (!IsValidRangeList(pRangeList))
1114  return CR_INVALID_RANGE_LIST;
1115 
1116  if (ulFlags & ~CM_ADD_RANGE_BITS)
1117  return CR_INVALID_FLAG;
1118 
1119  if (ullEndValue < ullStartValue)
1120  return CR_INVALID_RANGE;
1121 
1122  /* Lock the range list */
1123  WaitForSingleObject(pRangeList->hMutex, INFINITE);
1124 
1125  /* Allocate the new range */
1126  pRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
1127  if (pRange == NULL)
1128  {
1130  goto done;
1131  }
1132 
1133  pRange->pRangeList = pRangeList;
1134  pRange->ullStart = ullStartValue;
1135  pRange->ullEnd = ullEndValue;
1136 
1137  /* Insert the range */
1138  if (IsListEmpty(&pRangeList->ListHead))
1139  {
1140  InsertTailList(&pRangeList->ListHead, &pRange->ListEntry);
1141  }
1142  else
1143  {
1144  HeapFree(GetProcessHeap(), 0, pRange);
1145  UNIMPLEMENTED;
1146  }
1147 
1148 done:
1149  /* Unlock the range list */
1150  ReleaseMutex(pRangeList->hMutex);
1151 
1152  return ret;
1153 }
1154 
1155 
1156 /***********************************************************************
1157  * CM_Add_Res_Des [SETUPAPI.@]
1158  */
1159 CONFIGRET
1160 WINAPI
1162  _Out_opt_ PRES_DES prdResDes,
1163  _In_ LOG_CONF lcLogConf,
1164  _In_ RESOURCEID ResourceID,
1165  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1166  _In_ ULONG ResourceLen,
1167  _In_ ULONG ulFlags)
1168 {
1169  TRACE("CM_Add_Res_Des(%p %p %lu %p %lu %lx)\n",
1170  prdResDes, lcLogConf, ResourceID, ResourceData, ResourceLen, ulFlags);
1171 
1172  return CM_Add_Res_Des_Ex(prdResDes, lcLogConf, ResourceID, ResourceData,
1173  ResourceLen, ulFlags, NULL);
1174 }
1175 
1176 
1177 /***********************************************************************
1178  * CM_Add_Res_Des_Ex [SETUPAPI.@]
1179  */
1180 CONFIGRET
1181 WINAPI
1183  _Out_opt_ PRES_DES prdResDes,
1184  _In_ LOG_CONF lcLogConf,
1185  _In_ RESOURCEID ResourceID,
1186  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1187  _In_ ULONG ResourceLen,
1188  _In_ ULONG ulFlags,
1189  _In_opt_ HMACHINE hMachine)
1190 {
1191  FIXME("CM_Add_Res_Des_Ex(%p %p %lu %p %lu %lx %p)\n",
1192  prdResDes, lcLogConf, ResourceID,
1193  ResourceData, ResourceLen, ulFlags, hMachine);
1194 
1195  return CR_CALL_NOT_IMPLEMENTED;
1196 }
1197 
1198 
1199 /***********************************************************************
1200  * CM_Connect_MachineA [SETUPAPI.@]
1201  */
1202 CONFIGRET
1203 WINAPI
1205  _In_opt_ PCSTR UNCServerName,
1206  _Out_ PHMACHINE phMachine)
1207 {
1208  PWSTR pServerNameW;
1209  CONFIGRET ret;
1210 
1211  TRACE("CM_Connect_MachineA(%s %p)\n",
1212  debugstr_a(UNCServerName), phMachine);
1213 
1214  if (UNCServerName == NULL || *UNCServerName == 0)
1215  return CM_Connect_MachineW(NULL, phMachine);
1216 
1217  if (pSetupCaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
1218  return CR_INVALID_DATA;
1219 
1220  ret = CM_Connect_MachineW(pServerNameW, phMachine);
1221 
1222  MyFree(pServerNameW);
1223 
1224  return ret;
1225 }
1226 
1227 
1228 /***********************************************************************
1229  * CM_Connect_MachineW [SETUPAPI.@]
1230  */
1231 CONFIGRET
1232 WINAPI
1234  _In_opt_ PCWSTR UNCServerName,
1235  _Out_ PHMACHINE phMachine)
1236 {
1237  PMACHINE_INFO pMachine;
1238 
1239  TRACE("CM_Connect_MachineW(%s %p)\n",
1240  debugstr_w(UNCServerName), phMachine);
1241 
1242  if (phMachine == NULL)
1243  return CR_INVALID_POINTER;
1244 
1245  *phMachine = NULL;
1246 
1247  pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
1248  if (pMachine == NULL)
1249  return CR_OUT_OF_MEMORY;
1250 
1251  if (UNCServerName == NULL || *UNCServerName == 0)
1252  {
1253  pMachine->bLocal = TRUE;
1254 
1255  /* FIXME: store the computers name in pMachine->szMachineName */
1256 
1257  if (!PnpGetLocalHandles(&pMachine->BindingHandle,
1258  &pMachine->StringTable))
1259  {
1260  HeapFree(GetProcessHeap(), 0, pMachine);
1261  return CR_FAILURE;
1262  }
1263  }
1264  else
1265  {
1266  pMachine->bLocal = FALSE;
1267  if (wcslen(UNCServerName) >= SP_MAX_MACHINENAME_LENGTH - 1)
1268  {
1269  HeapFree(GetProcessHeap(), 0, pMachine);
1270  return CR_INVALID_MACHINENAME;
1271  }
1272  lstrcpyW(pMachine->szMachineName, UNCServerName);
1273 
1275  if (pMachine->StringTable == NULL)
1276  {
1277  HeapFree(GetProcessHeap(), 0, pMachine);
1278  return CR_FAILURE;
1279  }
1280 
1281  pSetupStringTableAddString(pMachine->StringTable, L"PLT", 1);
1282 
1283  if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
1284  {
1286  HeapFree(GetProcessHeap(), 0, pMachine);
1287  return CR_INVALID_MACHINENAME;
1288  }
1289  }
1290 
1291  *phMachine = (PHMACHINE)pMachine;
1292 
1293  return CR_SUCCESS;
1294 }
1295 
1296 
1297 /***********************************************************************
1298  * CM_Create_DevNodeA [SETUPAPI.@]
1299  */
1300 CONFIGRET
1301 WINAPI
1303  _Out_ PDEVINST pdnDevInst,
1304  _In_ DEVINSTID_A pDeviceID,
1305  _In_ DEVINST dnParent,
1306  _In_ ULONG ulFlags)
1307 {
1308  TRACE("CM_Create_DevNodeA(%p %s %p %lx)\n",
1309  pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
1310 
1311  return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
1312  ulFlags, NULL);
1313 }
1314 
1315 
1316 /***********************************************************************
1317  * CM_Create_DevNodeW [SETUPAPI.@]
1318  */
1319 CONFIGRET
1320 WINAPI
1322  _Out_ PDEVINST pdnDevInst,
1323  _In_ DEVINSTID_W pDeviceID,
1324  _In_ DEVINST dnParent,
1325  _In_ ULONG ulFlags)
1326 {
1327  TRACE("CM_Create_DevNodeW(%p %s %p %lx)\n",
1328  pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
1329 
1330  return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
1331  ulFlags, NULL);
1332 }
1333 
1334 
1335 /***********************************************************************
1336  * CM_Create_DevNode_ExA [SETUPAPI.@]
1337  */
1338 CONFIGRET
1339 WINAPI
1341  _Out_ PDEVINST pdnDevInst,
1342  _In_ DEVINSTID_A pDeviceID,
1343  _In_ DEVINST dnParent,
1344  _In_ ULONG ulFlags,
1345  _In_opt_ HANDLE hMachine)
1346 {
1347  DEVINSTID_W pDeviceIDW;
1348  CONFIGRET ret;
1349 
1350  TRACE("CM_Create_DevNode_ExA(%p %s %p %lx %p)\n",
1351  pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
1352 
1353  if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
1354  return CR_INVALID_DATA;
1355 
1356  ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
1357  hMachine);
1358 
1359  MyFree(pDeviceIDW);
1360 
1361  return ret;
1362 }
1363 
1364 
1365 /***********************************************************************
1366  * CM_Create_DevNode_ExW [SETUPAPI.@]
1367  */
1368 CONFIGRET
1369 WINAPI
1371  _Out_ PDEVINST pdnDevInst,
1372  _In_ DEVINSTID_W pDeviceID,
1373  _In_ DEVINST dnParent,
1374  _In_ ULONG ulFlags,
1375  _In_opt_ HANDLE hMachine)
1376 {
1378  HSTRING_TABLE StringTable = NULL;
1379  LPWSTR lpParentDevInst;
1381  WCHAR szLocalDeviceID[MAX_DEVICE_ID_LEN];
1382 
1383  TRACE("CM_Create_DevNode_ExW(%p %s %p %lx %p)\n",
1384  pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
1385 
1386  if (!pSetupIsUserAdmin())
1387  return CR_ACCESS_DENIED;
1388 
1389  if (pdnDevInst == NULL)
1390  return CR_INVALID_POINTER;
1391 
1392  if (pDeviceID == NULL || wcslen(pDeviceID) == 0 || wcslen(pDeviceID) >= MAX_DEVICE_ID_LEN)
1393  return CR_INVALID_DEVICE_ID;
1394 
1395  if (dnParent == 0)
1396  return CR_INVALID_DEVNODE;
1397 
1398  if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
1399  return CR_INVALID_FLAG;
1400 
1401  if (hMachine != NULL)
1402  {
1403  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1404  if (BindingHandle == NULL)
1405  return CR_FAILURE;
1406 
1407  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1408  if (StringTable == 0)
1409  return CR_FAILURE;
1410  }
1411  else
1412  {
1413  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1414  return CR_FAILURE;
1415  }
1416 
1417  lpParentDevInst = pSetupStringTableStringFromId(StringTable, dnParent);
1418  if (lpParentDevInst == NULL)
1419  return CR_INVALID_DEVNODE;
1420 
1421  wcscpy(szLocalDeviceID, pDeviceID);
1422 
1423  RpcTryExcept
1424  {
1426  szLocalDeviceID,
1427  lpParentDevInst,
1429  ulFlags);
1430  }
1432  {
1434  }
1435  RpcEndExcept;
1436 
1437  if (ret == CR_SUCCESS)
1438  {
1439  /* If CM_CREATE_DEVINST_GENERATE_ID was passed in, PNP_CreateDevInst
1440  * will return the generated device ID in szLocalDeviceID */
1441  *pdnDevInst = pSetupStringTableAddString(StringTable, szLocalDeviceID, 1);
1442  if (*pdnDevInst == 0)
1444  }
1445 
1446  return ret;
1447 }
1448 
1449 
1450 /***********************************************************************
1451  * CM_Create_Range_List [SETUPAPI.@]
1452  */
1453 CONFIGRET
1454 WINAPI
1456  _Out_ PRANGE_LIST prlh,
1457  _In_ ULONG ulFlags)
1458 {
1459  PINTERNAL_RANGE_LIST pRangeList = NULL;
1460 
1461  FIXME("CM_Create_Range_List(%p %lx)\n",
1462  prlh, ulFlags);
1463 
1464  if (ulFlags != 0)
1465  return CR_INVALID_FLAG;
1466 
1467  if (prlh == NULL)
1468  return CR_INVALID_POINTER;
1469 
1470  /* Allocate the range list */
1472  if (pRangeList == NULL)
1473  return CR_OUT_OF_MEMORY;
1474 
1475  /* Set the magic value */
1476  pRangeList->ulMagic = RANGE_LIST_MAGIC;
1477 
1478  /* Initialize the mutex for synchonized access */
1479  pRangeList->hMutex = CreateMutex(NULL, FALSE, NULL);
1480  if (pRangeList->hMutex == NULL)
1481  {
1482  HeapFree(GetProcessHeap(), 0, pRangeList);
1483  return CR_FAILURE;
1484  }
1485 
1486  InitializeListHead(&pRangeList->ListHead);
1487 
1488  *prlh = (RANGE_LIST)pRangeList;
1489 
1490  return CR_SUCCESS;
1491 }
1492 
1493 
1494 /***********************************************************************
1495  * CM_Delete_Class_Key [SETUPAPI.@]
1496  */
1497 CONFIGRET
1498 WINAPI
1500  _In_ LPGUID ClassGuid,
1501  _In_ ULONG ulFlags)
1502 {
1503  TRACE("CM_Delete_Class_Key(%p %lx)\n",
1504  ClassGuid, ulFlags);
1505 
1506  return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
1507 }
1508 
1509 
1510 /***********************************************************************
1511  * CM_Delete_Class_Key_Ex [SETUPAPI.@]
1512  */
1513 CONFIGRET
1514 WINAPI
1516  _In_ LPGUID ClassGuid,
1517  _In_ ULONG ulFlags,
1518  _In_opt_ HANDLE hMachine)
1519 {
1520  WCHAR szGuidString[MAX_GUID_STRING_LEN];
1522  CONFIGRET ret;
1523 
1524  TRACE("CM_Delete_Class_Key_Ex(%p %lx %p)\n",
1525  ClassGuid, ulFlags, hMachine);
1526 
1527  if (ClassGuid == NULL)
1528  return CR_INVALID_POINTER;
1529 
1530  if (ulFlags & ~CM_DELETE_CLASS_BITS)
1531  return CR_INVALID_FLAG;
1532 
1533  if (!GuidToString(ClassGuid, szGuidString))
1534  return CR_INVALID_DATA;
1535 
1536  if (hMachine != NULL)
1537  {
1538  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1539  if (BindingHandle == NULL)
1540  return CR_FAILURE;
1541  }
1542  else
1543  {
1545  return CR_FAILURE;
1546  }
1547 
1548  RpcTryExcept
1549  {
1551  szGuidString,
1552  ulFlags);
1553  }
1555  {
1557  }
1558  RpcEndExcept;
1559 
1560  return ret;
1561 }
1562 
1563 
1564 /***********************************************************************
1565  * CM_Delete_DevNode_Key [SETUPAPI.@]
1566  */
1567 CONFIGRET
1568 WINAPI
1570  _In_ DEVINST dnDevInst,
1571  _In_ ULONG ulHardwareProfile,
1572  _In_ ULONG ulFlags)
1573 {
1574  TRACE("CM_Delete_DevNode_Key(%p %lu %lx)\n",
1575  dnDevInst, ulHardwareProfile, ulFlags);
1576 
1577  return CM_Delete_DevNode_Key_Ex(dnDevInst, ulHardwareProfile, ulFlags,
1578  NULL);
1579 }
1580 
1581 
1582 /***********************************************************************
1583  * CM_Delete_DevNode_Key_Ex [SETUPAPI.@]
1584  */
1585 CONFIGRET
1586 WINAPI
1588  _In_ DEVINST dnDevInst,
1589  _In_ ULONG ulHardwareProfile,
1590  _In_ ULONG ulFlags,
1591  _In_opt_ HANDLE hMachine)
1592 {
1594  HSTRING_TABLE StringTable = NULL;
1595  PWSTR pszDevInst, pszKeyPath = NULL, pszInstancePath = NULL;
1596  CONFIGRET ret;
1597 
1598  FIXME("CM_Delete_DevNode_Key_Ex(%p %lu %lx %p)\n",
1599  dnDevInst, ulHardwareProfile, ulFlags, hMachine);
1600 
1601  if (dnDevInst == 0)
1602  return CR_INVALID_DEVINST;
1603 
1604  if (ulFlags & ~CM_REGISTRY_BITS)
1605  return CR_INVALID_FLAG;
1606 
1607  if ((ulFlags & CM_REGISTRY_USER) && (ulFlags & CM_REGISTRY_CONFIG))
1608  return CR_INVALID_FLAG;
1609 
1610  if (hMachine != NULL)
1611  {
1612  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1613  if (BindingHandle == NULL)
1614  return CR_FAILURE;
1615 
1616  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1617  if (StringTable == 0)
1618  return CR_FAILURE;
1619  }
1620  else
1621  {
1622  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1623  return CR_FAILURE;
1624  }
1625 
1626  pszDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1627  if (pszDevInst == NULL)
1628  return CR_INVALID_DEVNODE;
1629 
1630  TRACE("pszDevInst: %S\n", pszDevInst);
1631 
1632  pszKeyPath = MyMalloc(512 * sizeof(WCHAR));
1633  if (pszKeyPath == NULL)
1634  {
1636  goto done;
1637  }
1638 
1639  pszInstancePath = MyMalloc(512 * sizeof(WCHAR));
1640  if (pszInstancePath == NULL)
1641  {
1643  goto done;
1644  }
1645 
1647  pszDevInst,
1648  pszKeyPath,
1649  pszInstancePath,
1650  ulHardwareProfile,
1651  ulFlags);
1652  if (ret != CR_SUCCESS)
1653  goto done;
1654 
1655  TRACE("pszKeyPath: %S\n", pszKeyPath);
1656  TRACE("pszInstancePath: %S\n", pszInstancePath);
1657 
1658  if (ulFlags & CM_REGISTRY_USER)
1659  {
1660  FIXME("The CM_REGISTRY_USER flag is not supported yet!\n");
1661  }
1662  else
1663  {
1664 #if 0
1665  if (!pSetupIsUserAdmin())
1666  {
1668  goto done;
1669  }
1670 #endif
1671 
1672  if (!(ulFlags & CM_REGISTRY_CONFIG))
1673  ulHardwareProfile = 0;
1674 
1675  RpcTryExcept
1676  {
1678  pszDevInst,
1679  pszKeyPath,
1680  pszInstancePath,
1681  ulHardwareProfile);
1682  }
1684  {
1686  }
1687  RpcEndExcept;
1688  }
1689 
1690 done:
1691  if (pszInstancePath != NULL)
1692  MyFree(pszInstancePath);
1693 
1694  if (pszKeyPath != NULL)
1695  MyFree(pszKeyPath);
1696 
1697  return ret;
1698 }
1699 
1700 
1701 /***********************************************************************
1702  * CM_Delete_Range [SETUPAPI.@]
1703  */
1704 CONFIGRET
1705 WINAPI
1707  _In_ DWORDLONG ullStartValue,
1708  _In_ DWORDLONG ullEndValue,
1709  _In_ RANGE_LIST rlh,
1710  _In_ ULONG ulFlags)
1711 {
1712  FIXME("CM_Delete_Range(%I64u %I64u %p %lx)\n",
1713  ullStartValue, ullEndValue, rlh, ulFlags);
1714 
1715  return CR_CALL_NOT_IMPLEMENTED;
1716 }
1717 
1718 
1719 /***********************************************************************
1720  * CM_Detect_Resource_Conflict [SETUPAPI.@]
1721  */
1722 CONFIGRET
1723 WINAPI
1725  _In_ DEVINST dnDevInst,
1726  _In_ RESOURCEID ResourceID,
1727  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1728  _In_ ULONG ResourceLen,
1729  _Out_ PBOOL pbConflictDetected,
1730  _In_ ULONG ulFlags)
1731 {
1732  TRACE("CM_Detect_Resource_Conflict(%p %lu %p %lu %p 0x%lx)\n",
1733  dnDevInst, ResourceID, ResourceData, ResourceLen,
1734  pbConflictDetected, ulFlags);
1735 
1736  return CM_Detect_Resource_Conflict_Ex(dnDevInst,
1737  ResourceID,
1738  ResourceData,
1739  ResourceLen,
1740  pbConflictDetected,
1741  ulFlags,
1742  NULL);
1743 }
1744 
1745 
1746 /***********************************************************************
1747  * CM_Detect_Resource_Conflict_Ex [SETUPAPI.@]
1748  */
1749 CONFIGRET
1750 WINAPI
1752  _In_ DEVINST dnDevInst,
1753  _In_ RESOURCEID ResourceID,
1754  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1755  _In_ ULONG ResourceLen,
1756  _Out_ PBOOL pbConflictDetected,
1757  _In_ ULONG ulFlags,
1758  _In_opt_ HMACHINE hMachine)
1759 {
1760  FIXME("CM_Detect_Resource_Conflict_Ex(%p %lu %p %lu %p 0x%lx %p)\n",
1761  dnDevInst, ResourceID, ResourceData, ResourceLen,
1762  pbConflictDetected, ulFlags, hMachine);
1763 
1764  return CR_CALL_NOT_IMPLEMENTED;
1765 }
1766 
1767 
1768 /***********************************************************************
1769  * CM_Disable_DevNode [SETUPAPI.@]
1770  */
1771 CONFIGRET
1772 WINAPI
1774  _In_ DEVINST dnDevInst,
1775  _In_ ULONG ulFlags)
1776 {
1777  TRACE("CM_Disable_DevNode(%p %lx)\n",
1778  dnDevInst, ulFlags);
1779 
1780  return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1781 }
1782 
1783 
1784 /***********************************************************************
1785  * CM_Disable_DevNode_Ex [SETUPAPI.@]
1786  */
1787 CONFIGRET
1788 WINAPI
1790  _In_ DEVINST dnDevInst,
1791  _In_ ULONG ulFlags,
1792  _In_opt_ HMACHINE hMachine)
1793 {
1795  HSTRING_TABLE StringTable = NULL;
1796  LPWSTR lpDevInst;
1797  CONFIGRET ret;
1798 
1799  TRACE("CM_Disable_DevNode_Ex(%p %lx %p)\n",
1800  dnDevInst, ulFlags, hMachine);
1801 
1802  if (!pSetupIsUserAdmin())
1803  return CR_ACCESS_DENIED;
1804 
1805  if (dnDevInst == 0)
1806  return CR_INVALID_DEVINST;
1807 
1808  if (ulFlags != 0)
1809  return CR_INVALID_FLAG;
1810 
1811  if (hMachine != NULL)
1812  {
1813  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1814  if (BindingHandle == NULL)
1815  return CR_FAILURE;
1816 
1817  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1818  if (StringTable == 0)
1819  return CR_FAILURE;
1820  }
1821  else
1822  {
1823  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1824  return CR_FAILURE;
1825  }
1826 
1827  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1828  if (lpDevInst == NULL)
1829  return CR_INVALID_DEVNODE;
1830 
1831  RpcTryExcept
1832  {
1834  lpDevInst,
1835  NULL,
1836  NULL,
1837  0,
1838  ulFlags);
1839  }
1841  {
1843  }
1844  RpcEndExcept;
1845 
1846  return ret;
1847 }
1848 
1849 
1850 /***********************************************************************
1851  * CM_Disconnect_Machine [SETUPAPI.@]
1852  */
1853 CONFIGRET
1854 WINAPI
1856  _In_opt_ HMACHINE hMachine)
1857 {
1858  PMACHINE_INFO pMachine;
1859 
1860  TRACE("CM_Disconnect_Machine(%p)\n", hMachine);
1861 
1862  pMachine = (PMACHINE_INFO)hMachine;
1863  if (pMachine == NULL)
1864  return CR_SUCCESS;
1865 
1866  if (pMachine->bLocal == FALSE)
1867  {
1868  if (pMachine->StringTable != NULL)
1870 
1871  if (!PnpUnbindRpc(pMachine->BindingHandle))
1872  return CR_ACCESS_DENIED;
1873  }
1874 
1875  HeapFree(GetProcessHeap(), 0, pMachine);
1876 
1877  return CR_SUCCESS;
1878 }
1879 
1880 
1881 /***********************************************************************
1882  * CM_Dup_Range_List [SETUPAPI.@]
1883  */
1884 CONFIGRET
1885 WINAPI
1887  _In_ RANGE_LIST rlhOld,
1888  _In_ RANGE_LIST rlhNew,
1889  _In_ ULONG ulFlags)
1890 {
1891  FIXME("CM_Dup_Range_List(%p %p %lx)\n",
1892  rlhOld, rlhNew, ulFlags);
1893 
1894  return CR_CALL_NOT_IMPLEMENTED;
1895 }
1896 
1897 
1898 /***********************************************************************
1899  * CM_Enable_DevNode [SETUPAPI.@]
1900  */
1901 CONFIGRET
1902 WINAPI
1904  _In_ DEVINST dnDevInst,
1905  _In_ ULONG ulFlags)
1906 {
1907  TRACE("CM_Enable_DevNode(%p %lx)\n",
1908  dnDevInst, ulFlags);
1909 
1910  return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1911 }
1912 
1913 
1914 /***********************************************************************
1915  * CM_Enable_DevNode_Ex [SETUPAPI.@]
1916  */
1917 CONFIGRET
1918 WINAPI
1920  _In_ DEVINST dnDevInst,
1921  _In_ ULONG ulFlags,
1922  _In_opt_ HMACHINE hMachine)
1923 {
1925  HSTRING_TABLE StringTable = NULL;
1926  LPWSTR lpDevInst;
1927  CONFIGRET ret;
1928 
1929  TRACE("CM_Enable_DevNode_Ex(%p %lx %p)\n",
1930  dnDevInst, ulFlags, hMachine);
1931 
1932  if (!pSetupIsUserAdmin())
1933  return CR_ACCESS_DENIED;
1934 
1935  if (dnDevInst == 0)
1936  return CR_INVALID_DEVINST;
1937 
1938  if (ulFlags != 0)
1939  return CR_INVALID_FLAG;
1940 
1941  if (hMachine != NULL)
1942  {
1943  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1944  if (BindingHandle == NULL)
1945  return CR_FAILURE;
1946 
1947  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1948  if (StringTable == 0)
1949  return CR_FAILURE;
1950  }
1951  else
1952  {
1953  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1954  return CR_FAILURE;
1955  }
1956 
1957  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1958  if (lpDevInst == NULL)
1959  return CR_INVALID_DEVNODE;
1960 
1961  RpcTryExcept
1962  {
1964  PNP_DEVINST_ENABLE,
1965  ulFlags,
1966  lpDevInst,
1967  NULL);
1968  }
1970  {
1972  }
1973  RpcEndExcept;
1974 
1975  return ret;
1976 }
1977 
1978 
1979 /***********************************************************************
1980  * CM_Enumerate_Classes [SETUPAPI.@]
1981  */
1982 CONFIGRET
1983 WINAPI
1985  _In_ ULONG ulClassIndex,
1986  _Out_ LPGUID ClassGuid,
1987  _In_ ULONG ulFlags)
1988 {
1989  TRACE("CM_Enumerate_Classes(%lx %p %lx)\n",
1990  ulClassIndex, ClassGuid, ulFlags);
1991 
1992  return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
1993 }
1994 
1995 
1996 /***********************************************************************
1997  * CM_Enumerate_Classes_Ex [SETUPAPI.@]
1998  */
1999 CONFIGRET
2000 WINAPI
2002  _In_ ULONG ulClassIndex,
2003  _Out_ LPGUID ClassGuid,
2004  _In_ ULONG ulFlags,
2005  _In_opt_ HMACHINE hMachine)
2006 {
2007  WCHAR szBuffer[MAX_GUID_STRING_LEN];
2010  ULONG ulLength = MAX_GUID_STRING_LEN;
2011 
2012  TRACE("CM_Enumerate_Classes_Ex(%lx %p %lx %p)\n",
2013  ulClassIndex, ClassGuid, ulFlags, hMachine);
2014 
2015  if (ClassGuid == NULL)
2016  return CR_INVALID_POINTER;
2017 
2018  if (ulFlags != 0)
2019  return CR_INVALID_FLAG;
2020 
2021  if (hMachine != NULL)
2022  {
2023  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2024  if (BindingHandle == NULL)
2025  return CR_FAILURE;
2026  }
2027  else
2028  {
2030  return CR_FAILURE;
2031  }
2032 
2033  RpcTryExcept
2034  {
2036  PNP_CLASS_SUBKEYS,
2037  ulClassIndex,
2038  szBuffer,
2040  &ulLength,
2041  ulFlags);
2042  }
2044  {
2046  }
2047  RpcEndExcept;
2048 
2049  if (ret == CR_SUCCESS)
2050  {
2051  /* Remove the {} */
2052  szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
2053 
2054  /* Convert the buffer to a GUID */
2055  if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
2056  return CR_FAILURE;
2057  }
2058 
2059  return ret;
2060 }
2061 
2062 
2063 /***********************************************************************
2064  * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
2065  */
2066 CONFIGRET
2067 WINAPI
2069  _In_ ULONG ulEnumIndex,
2070  _Out_writes_(*pulLength) PCHAR Buffer,
2071  _Inout_ PULONG pulLength,
2072  _In_ ULONG ulFlags)
2073 {
2074  TRACE("CM_Enumerate_EnumeratorsA(%lu %p %p %lx)\n",
2075  ulEnumIndex, Buffer, pulLength, ulFlags);
2076 
2077  return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
2078  ulFlags, NULL);
2079 }
2080 
2081 
2082 /***********************************************************************
2083  * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
2084  */
2085 CONFIGRET
2086 WINAPI
2088  _In_ ULONG ulEnumIndex,
2089  _Out_writes_(*pulLength) PWCHAR Buffer,
2090  _Inout_ PULONG pulLength,
2091  _In_ ULONG ulFlags)
2092 {
2093  TRACE("CM_Enumerate_EnumeratorsW(%lu %p %p %lx)\n",
2094  ulEnumIndex, Buffer, pulLength, ulFlags);
2095 
2096  return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
2097  ulFlags, NULL);
2098 }
2099 
2100 
2101 /***********************************************************************
2102  * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
2103  */
2104 CONFIGRET
2105 WINAPI
2107  _In_ ULONG ulEnumIndex,
2108  _Out_writes_(*pulLength) PCHAR Buffer,
2109  _Inout_ PULONG pulLength,
2110  _In_ ULONG ulFlags,
2111  _In_opt_ HMACHINE hMachine)
2112 {
2113  WCHAR szBuffer[MAX_DEVICE_ID_LEN];
2114  ULONG ulOrigLength;
2115  ULONG ulLength;
2117 
2118  TRACE("CM_Enumerate_Enumerators_ExA(%lu %p %p %lx %p)\n",
2119  ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2120 
2121  if (Buffer == NULL || pulLength == NULL)
2122  return CR_INVALID_POINTER;
2123 
2124  if (ulFlags != 0)
2125  return CR_INVALID_FLAG;
2126 
2127  ulOrigLength = *pulLength;
2128  *pulLength = 0;
2129 
2130  ulLength = MAX_DEVICE_ID_LEN;
2131  ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
2132  ulFlags, hMachine);
2133  if (ret == CR_SUCCESS)
2134  {
2136  0,
2137  szBuffer,
2138  ulLength,
2139  Buffer,
2140  ulOrigLength,
2141  NULL,
2142  NULL) == 0)
2143  ret = CR_FAILURE;
2144  else
2145  *pulLength = lstrlenA(Buffer) + 1;
2146  }
2147 
2148  return ret;
2149 }
2150 
2151 
2152 /***********************************************************************
2153  * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
2154  */
2155 CONFIGRET
2156 WINAPI
2158  _In_ ULONG ulEnumIndex,
2159  _Out_writes_(*pulLength) PWCHAR Buffer,
2160  _Inout_ PULONG pulLength,
2161  _In_ ULONG ulFlags,
2162  _In_opt_ HMACHINE hMachine)
2163 {
2165  CONFIGRET ret;
2166 
2167  TRACE("CM_Enumerate_Enumerators_ExW(%lu %p %p %lx %p)\n",
2168  ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2169 
2170  if (Buffer == NULL || pulLength == NULL)
2171  return CR_INVALID_POINTER;
2172 
2173  if (ulFlags != 0)
2174  return CR_INVALID_FLAG;
2175 
2176  *Buffer = UNICODE_NULL;
2177 
2178  if (hMachine != NULL)
2179  {
2180  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2181  if (BindingHandle == NULL)
2182  return CR_FAILURE;
2183  }
2184  else
2185  {
2187  return CR_FAILURE;
2188  }
2189 
2190  RpcTryExcept
2191  {
2193  PNP_ENUMERATOR_SUBKEYS,
2194  ulEnumIndex,
2195  Buffer,
2196  *pulLength,
2197  pulLength,
2198  ulFlags);
2199  }
2201  {
2203  }
2204  RpcEndExcept;
2205 
2206  return ret;
2207 }
2208 
2209 
2210 /***********************************************************************
2211  * CM_Find_Range [SETUPAPI.@]
2212  */
2213 CONFIGRET
2214 WINAPI
2216  _Out_ PDWORDLONG pullStart,
2217  _In_ DWORDLONG ullStart,
2218  _In_ ULONG ulLength,
2219  _In_ DWORDLONG ullAlignment,
2220  _In_ DWORDLONG ullEnd,
2221  _In_ RANGE_LIST rlh,
2222  _In_ ULONG ulFlags)
2223 {
2224  FIXME("CM_Find_Range(%p %I64u %lu %I64u %I64u %p %lx)\n",
2225  pullStart, ullStart, ulLength, ullAlignment, ullEnd, rlh, ulFlags);
2226 
2227  return CR_CALL_NOT_IMPLEMENTED;
2228 }
2229 
2230 
2231 /***********************************************************************
2232  * CM_First_Range [SETUPAPI.@]
2233  */
2234 CONFIGRET
2235 WINAPI
2237  _In_ RANGE_LIST rlh,
2238  _Out_ PDWORDLONG pullStart,
2239  _Out_ PDWORDLONG pullEnd,
2240  _Out_ PRANGE_ELEMENT preElement,
2241  _In_ ULONG ulFlags)
2242 {
2243  PINTERNAL_RANGE_LIST pRangeList;
2244  PINTERNAL_RANGE pRange;
2245  PLIST_ENTRY ListEntry;
2247 
2248  FIXME("CM_First_Range(%p %p %p %p %lx)\n",
2249  rlh, pullStart, pullEnd, preElement, ulFlags);
2250 
2251  pRangeList = (PINTERNAL_RANGE_LIST)rlh;
2252 
2253  if (!IsValidRangeList(pRangeList))
2254  return CR_INVALID_RANGE_LIST;
2255 
2256  if (pullStart == NULL || pullEnd == NULL || preElement == NULL)
2257  return CR_INVALID_POINTER;
2258 
2259  if (ulFlags != 0)
2260  return CR_INVALID_FLAG;
2261 
2262  /* Lock the range list */
2263  WaitForSingleObject(pRangeList->hMutex, INFINITE);
2264 
2265  /* Fail, if the list is empty */
2266  if (IsListEmpty(&pRangeList->ListHead))
2267  {
2268  ret = CR_FAILURE;
2269  goto done;
2270  }
2271 
2272  /* Get the first range */
2273  ListEntry = pRangeList->ListHead.Flink;
2274  pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2275 
2276  /* Return the range data */
2277  *pullStart = pRange->ullStart;
2278  *pullEnd = pRange->ullEnd;
2279  *preElement = (RANGE_ELEMENT)pRange;
2280 
2281 done:
2282  /* Unlock the range list */
2283  ReleaseMutex(pRangeList->hMutex);
2284 
2285  return ret;
2286 }
2287 
2288 
2289 /***********************************************************************
2290  * CM_Free_Log_Conf [SETUPAPI.@]
2291  */
2292 CONFIGRET
2293 WINAPI
2295  _In_ LOG_CONF lcLogConfToBeFreed,
2296  _In_ ULONG ulFlags)
2297 {
2298  TRACE("CM_Free_Log_Conf(%lx %lx)\n",
2299  lcLogConfToBeFreed, ulFlags);
2300 
2301  return CM_Free_Log_Conf_Ex(lcLogConfToBeFreed, ulFlags, NULL);
2302 }
2303 
2304 
2305 /***********************************************************************
2306  * CM_Free_Log_Conf_Ex [SETUPAPI.@]
2307  */
2308 CONFIGRET
2309 WINAPI
2311  _In_ LOG_CONF lcLogConfToBeFreed,
2312  _In_ ULONG ulFlags,
2313  _In_opt_ HMACHINE hMachine)
2314 {
2316  HSTRING_TABLE StringTable = NULL;
2317  LPWSTR lpDevInst;
2318  PLOG_CONF_INFO pLogConfInfo;
2319  CONFIGRET ret;
2320 
2321  TRACE("CM_Free_Log_Conf_Ex(%lx %lx %p)\n",
2322  lcLogConfToBeFreed, ulFlags, hMachine);
2323 
2324  if (!pSetupIsUserAdmin())
2325  return CR_ACCESS_DENIED;
2326 
2327  pLogConfInfo = (PLOG_CONF_INFO)lcLogConfToBeFreed;
2328  if (!IsValidLogConf(pLogConfInfo))
2329  return CR_INVALID_LOG_CONF;
2330 
2331  if (ulFlags != 0)
2332  return CR_INVALID_FLAG;
2333 
2334  if (hMachine != NULL)
2335  {
2336  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2337  if (BindingHandle == NULL)
2338  return CR_FAILURE;
2339 
2340  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2341  if (StringTable == 0)
2342  return CR_FAILURE;
2343  }
2344  else
2345  {
2346  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2347  return CR_FAILURE;
2348  }
2349 
2350  lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
2351  if (lpDevInst == NULL)
2352  return CR_INVALID_DEVNODE;
2353 
2354  RpcTryExcept
2355  {
2357  lpDevInst,
2358  pLogConfInfo->ulType,
2359  pLogConfInfo->ulTag,
2360  0);
2361  }
2363  {
2365  }
2366  RpcEndExcept;
2367 
2368  return ret;
2369 }
2370 
2371 
2372 /***********************************************************************
2373  * CM_Free_Log_Conf_Handle [SETUPAPI.@]
2374  */
2375 CONFIGRET
2376 WINAPI
2378  _In_ LOG_CONF lcLogConf)
2379 {
2380  PLOG_CONF_INFO pLogConfInfo;
2381 
2382  TRACE("CM_Free_Log_Conf_Handle(%lx)\n", lcLogConf);
2383 
2384  pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
2385  if (!IsValidLogConf(pLogConfInfo))
2386  return CR_INVALID_LOG_CONF;
2387 
2388  HeapFree(GetProcessHeap(), 0, pLogConfInfo);
2389 
2390  return CR_SUCCESS;
2391 }
2392 
2393 
2394 /***********************************************************************
2395  * CM_Free_Range_List [SETUPAPI.@]
2396  */
2397 CONFIGRET
2398 WINAPI
2400  _In_ RANGE_LIST RangeList,
2401  _In_ ULONG ulFlags)
2402 {
2403  PINTERNAL_RANGE_LIST pRangeList;
2404  PINTERNAL_RANGE pRange;
2405  PLIST_ENTRY ListEntry;
2406 
2407  FIXME("CM_Free_Range_List(%p %lx)\n",
2408  RangeList, ulFlags);
2409 
2410  pRangeList = (PINTERNAL_RANGE_LIST)RangeList;
2411 
2412  if (!IsValidRangeList(pRangeList))
2413  return CR_INVALID_RANGE_LIST;
2414 
2415  if (ulFlags != 0)
2416  return CR_INVALID_FLAG;
2417 
2418  /* Lock the range list */
2419  WaitForSingleObject(pRangeList->hMutex, INFINITE);
2420 
2421  /* Free the list of ranges */
2422  while (!IsListEmpty(&pRangeList->ListHead))
2423  {
2424  ListEntry = RemoveHeadList(&pRangeList->ListHead);
2425  pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2426  HeapFree(GetProcessHeap(), 0, pRange);
2427  }
2428 
2429  /* Unlock the range list */
2430  ReleaseMutex(pRangeList->hMutex);
2431 
2432  /* Close the mutex */
2433  CloseHandle(pRangeList->hMutex);
2434 
2435  /* Free the range list */
2436  HeapFree(GetProcessHeap(), 0, pRangeList);
2437 
2438  return CR_SUCCESS;
2439 }
2440 
2441 
2442 /***********************************************************************
2443  * CM_Free_Res_Des [SETUPAPI.@]
2444  */
2445 CONFIGRET
2446 WINAPI
2448  _Out_ PRES_DES prdResDes,
2449  _In_ RES_DES rdResDes,
2450  _In_ ULONG ulFlags)
2451 {
2452  TRACE("CM_Free_Res_Des(%p %p %lx)\n",
2453  prdResDes, rdResDes, ulFlags);
2454 
2455  return CM_Free_Res_Des_Ex(prdResDes, rdResDes, ulFlags, NULL);
2456 }
2457 
2458 
2459 /***********************************************************************
2460  * CM_Free_Res_Des_Ex [SETUPAPI.@]
2461  */
2462 CONFIGRET
2463 WINAPI
2465  _Out_ PRES_DES prdResDes,
2466  _In_ RES_DES rdResDes,
2467  _In_ ULONG ulFlags,
2468  _In_opt_ HMACHINE hMachine)
2469 {
2470  FIXME("CM_Free_Res_Des_Ex(%p %p %lx %p)\n",
2471  prdResDes, rdResDes, ulFlags, hMachine);
2472 
2473  return CR_CALL_NOT_IMPLEMENTED;
2474 }
2475 
2476 
2477 /***********************************************************************
2478  * CM_Free_Res_Des_Handle [SETUPAPI.@]
2479  */
2480 CONFIGRET
2481 WINAPI
2483  _In_ RES_DES rdResDes)
2484 {
2485  FIXME("CM_Free_Res_Des_Handle(%p)\n", rdResDes);
2486 
2487  return CR_CALL_NOT_IMPLEMENTED;
2488 }
2489 
2490 
2491 /***********************************************************************
2492  * CM_Free_Resource_Conflict_Handle [SETUPAPI.@]
2493  */
2494 CONFIGRET
2495 WINAPI
2497  _In_ CONFLICT_LIST clConflictList)
2498 {
2499  PCONFLICT_DATA pConflictData;
2500 
2501  FIXME("CM_Free_Resource_Conflict_Handle(%p)\n",
2502  clConflictList);
2503 
2504  pConflictData = (PCONFLICT_DATA)clConflictList;
2505  if (!IsValidConflictData(pConflictData))
2506  return CR_INVALID_CONFLICT_LIST;
2507 
2508  if (pConflictData->pConflictList != NULL)
2509  MyFree(pConflictData->pConflictList);
2510 
2511  MyFree(pConflictData);
2512 
2513  return CR_SUCCESS;
2514 }
2515 
2516 
2517 /***********************************************************************
2518  * CM_Get_Child [SETUPAPI.@]
2519  */
2520 CONFIGRET
2521 WINAPI
2523  _Out_ PDEVINST pdnDevInst,
2524  _In_ DEVINST dnDevInst,
2525  _In_ ULONG ulFlags)
2526 {
2527  TRACE("CM_Get_Child(%p %p %lx)\n",
2528  pdnDevInst, dnDevInst, ulFlags);
2529 
2530  return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
2531 }
2532 
2533 
2534 /***********************************************************************
2535  * CM_Get_Child_Ex [SETUPAPI.@]
2536  */
2537 CONFIGRET
2538 WINAPI
2540  _Out_ PDEVINST pdnDevInst,
2541  _In_ DEVINST dnDevInst,
2542  _In_ ULONG ulFlags,
2543  _In_opt_ HMACHINE hMachine)
2544 {
2545  WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
2547  HSTRING_TABLE StringTable = NULL;
2548  LPWSTR lpDevInst;
2549  DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
2550  CONFIGRET ret;
2551 
2552  TRACE("CM_Get_Child_Ex(%p %lx %lx %p)\n",
2553  pdnDevInst, dnDevInst, ulFlags, hMachine);
2554 
2555  if (pdnDevInst == NULL)
2556  return CR_INVALID_POINTER;
2557 
2558  if (dnDevInst == 0)
2559  return CR_INVALID_DEVINST;
2560 
2561  if (ulFlags != 0)
2562  return CR_INVALID_FLAG;
2563 
2564  *pdnDevInst = -1;
2565 
2566  if (hMachine != NULL)
2567  {
2568  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2569  if (BindingHandle == NULL)
2570  return CR_FAILURE;
2571 
2572  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2573  if (StringTable == 0)
2574  return CR_FAILURE;
2575  }
2576  else
2577  {
2578  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2579  return CR_FAILURE;
2580  }
2581 
2582  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2583  if (lpDevInst == NULL)
2584  return CR_INVALID_DEVNODE;
2585 
2586  RpcTryExcept
2587  {
2589  PNP_GET_CHILD_DEVICE_INSTANCE,
2590  lpDevInst,
2591  szRelatedDevInst,
2592  &dwLength,
2593  0);
2594  }
2596  {
2598  }
2599  RpcEndExcept;
2600 
2601  if (ret != CR_SUCCESS)
2602  return ret;
2603 
2604  TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
2605 
2606  dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
2607  if (dwIndex == -1)
2608  return CR_FAILURE;
2609 
2610  *pdnDevInst = dwIndex;
2611 
2612  return CR_SUCCESS;
2613 }
2614 
2615 
2616 /***********************************************************************
2617  * CM_Get_Class_Key_NameA [SETUPAPI.@]
2618  */
2619 CONFIGRET
2620 WINAPI
2622  _In_ LPGUID ClassGuid,
2623  _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2624  _Inout_ PULONG pulLength,
2625  _In_ ULONG ulFlags)
2626 {
2627  TRACE("CM_Get_Class_Key_NameA(%p %p %p %lx)\n",
2628  ClassGuid, pszKeyName, pulLength, ulFlags);
2629 
2630  return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
2631  ulFlags, NULL);
2632 }
2633 
2634 
2635 /***********************************************************************
2636  * CM_Get_Class_Key_NameW [SETUPAPI.@]
2637  */
2638 CONFIGRET
2639 WINAPI
2641  _In_ LPGUID ClassGuid,
2642  _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2643  _Inout_ PULONG pulLength,
2644  _In_ ULONG ulFlags)
2645 {
2646  TRACE("CM_Get_Class_Key_NameW(%p %p %p %lx)\n",
2647  ClassGuid, pszKeyName, pulLength, ulFlags);
2648 
2649  return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
2650  ulFlags, NULL);
2651 }
2652 
2653 
2654 /***********************************************************************
2655  * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
2656  */
2657 CONFIGRET
2658 WINAPI
2660  _In_ LPGUID ClassGuid,
2661  _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2662  _Inout_ PULONG pulLength,
2663  _In_ ULONG ulFlags,
2664  _In_opt_ HMACHINE hMachine)
2665 {
2666  WCHAR szBuffer[MAX_GUID_STRING_LEN];
2668  ULONG ulLength;
2669  ULONG ulOrigLength;
2670 
2671  TRACE("CM_Get_Class_Key_Name_ExA(%p %p %p %lx %p)\n",
2672  ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2673 
2674  if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2675  return CR_INVALID_POINTER;
2676 
2677  ulOrigLength = *pulLength;
2678  *pulLength = 0;
2679 
2680  ulLength = MAX_GUID_STRING_LEN;
2681  ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
2682  ulFlags, hMachine);
2683  if (ret == CR_SUCCESS)
2684  {
2686  0,
2687  szBuffer,
2688  ulLength,
2689  pszKeyName,
2690  ulOrigLength,
2691  NULL,
2692  NULL) == 0)
2693  ret = CR_FAILURE;
2694  else
2695  *pulLength = lstrlenA(pszKeyName) + 1;
2696  }
2697 
2698  return CR_SUCCESS;
2699 }
2700 
2701 
2702 /***********************************************************************
2703  * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
2704  */
2705 CONFIGRET
2706 WINAPI
2708  _In_ LPGUID ClassGuid,
2709  _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2710  _Inout_ PULONG pulLength,
2711  _In_ ULONG ulFlags,
2712  _In_opt_ HMACHINE hMachine)
2713 {
2714  TRACE("CM_Get_Class_Key_Name_ExW(%p %p %p %lx %p)\n",
2715  ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2716 
2717  if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2718  return CR_INVALID_POINTER;
2719 
2720  if (ulFlags != 0)
2721  return CR_INVALID_FLAG;
2722 
2723  if (*pulLength < MAX_GUID_STRING_LEN)
2724  {
2725  *pulLength = 0;
2726  return CR_BUFFER_SMALL;
2727  }
2728 
2729  if (!GuidToString(ClassGuid, pszKeyName))
2730  return CR_INVALID_DATA;
2731 
2732  *pulLength = MAX_GUID_STRING_LEN;
2733 
2734  return CR_SUCCESS;
2735 }
2736 
2737 
2738 /***********************************************************************
2739  * CM_Get_Class_NameA [SETUPAPI.@]
2740  */
2741 CONFIGRET
2742 WINAPI
2744  _In_ LPGUID ClassGuid,
2745  _Out_writes_opt_(*pulLength) PCHAR Buffer,
2746  _Inout_ PULONG pulLength,
2747  _In_ ULONG ulFlags)
2748 {
2749  TRACE("CM_Get_Class_NameA(%p %p %p %lx)\n",
2750  ClassGuid, Buffer, pulLength, ulFlags);
2751 
2752  return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
2753  NULL);
2754 }
2755 
2756 
2757 /***********************************************************************
2758  * CM_Get_Class_NameW [SETUPAPI.@]
2759  */
2760 CONFIGRET
2761 WINAPI
2763  _In_ LPGUID ClassGuid,
2764  _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2765  _Inout_ PULONG pulLength,
2766  _In_ ULONG ulFlags)
2767 {
2768  TRACE("CM_Get_Class_NameW(%p %p %p %lx)\n",
2769  ClassGuid, Buffer, pulLength, ulFlags);
2770 
2771  return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
2772  NULL);
2773 }
2774 
2775 
2776 /***********************************************************************
2777  * CM_Get_Class_Name_ExA [SETUPAPI.@]
2778  */
2779 CONFIGRET
2780 WINAPI
2782  _In_ LPGUID ClassGuid,
2783  _Out_writes_opt_(*pulLength) PCHAR Buffer,
2784  _Inout_ PULONG pulLength,
2785  _In_ ULONG ulFlags,
2786  _In_opt_ HMACHINE hMachine)
2787 {
2788  WCHAR szBuffer[MAX_CLASS_NAME_LEN];
2790  ULONG ulLength;
2791  ULONG ulOrigLength;
2792 
2793  TRACE("CM_Get_Class_Name_ExA(%p %p %p %lx %p)\n",
2794  ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2795 
2796  if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2797  return CR_INVALID_POINTER;
2798 
2799  ulOrigLength = *pulLength;
2800  *pulLength = 0;
2801 
2802  ulLength = MAX_CLASS_NAME_LEN;
2803  ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
2804  ulFlags, hMachine);
2805  if (ret == CR_SUCCESS)
2806  {
2808  0,
2809  szBuffer,
2810  ulLength,
2811  Buffer,
2812  ulOrigLength,
2813  NULL,
2814  NULL) == 0)
2815  ret = CR_FAILURE;
2816  else
2817  *pulLength = lstrlenA(Buffer) + 1;
2818  }
2819 
2820  return ret;
2821 }
2822 
2823 
2824 /***********************************************************************
2825  * CM_Get_Class_Name_ExW [SETUPAPI.@]
2826  */
2827 CONFIGRET
2828 WINAPI
2830  _In_ LPGUID ClassGuid,
2831  _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2832  _Inout_ PULONG pulLength,
2833  _In_ ULONG ulFlags,
2834  _In_opt_ HMACHINE hMachine)
2835 {
2836  WCHAR szGuidString[MAX_GUID_STRING_LEN];
2838  CONFIGRET ret;
2839 
2840  TRACE("CM_Get_Class_Name_ExW(%p %p %p %lx %p\n",
2841  ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2842 
2843  if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2844  return CR_INVALID_POINTER;
2845 
2846  if (ulFlags != 0)
2847  return CR_INVALID_FLAG;
2848 
2849  if (!GuidToString(ClassGuid, szGuidString))
2850  return CR_INVALID_DATA;
2851 
2852  TRACE("Guid %s\n", debugstr_w(szGuidString));
2853 
2854  if (hMachine != NULL)
2855  {
2856  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2857  if (BindingHandle == NULL)
2858  return CR_FAILURE;
2859  }
2860  else
2861  {
2863  return CR_FAILURE;
2864  }
2865 
2866  RpcTryExcept
2867  {
2869  szGuidString,
2870  Buffer,
2871  pulLength,
2872  ulFlags);
2873  }
2875  {
2877  }
2878  RpcEndExcept;
2879 
2880  return ret;
2881 }
2882 
2883 
2884 /***********************************************************************
2885  * CM_Get_Class_Registry_PropertyA [SETUPAPI.@]
2886  */
2887 CONFIGRET
2888 WINAPI
2890  LPGUID ClassGuid,
2891  ULONG ulProperty,
2892  PULONG pulRegDataType,
2893  PVOID Buffer,
2894  PULONG pulLength,
2895  ULONG ulFlags,
2896  HMACHINE hMachine)
2897 {
2898  PWSTR BufferW = NULL;
2899  ULONG ulLength = 0;
2900  ULONG ulType;
2901  CONFIGRET ret;
2902 
2903  TRACE("CM_Get_Class_Registry_PropertyA(%p %lu %p %p %p %lx %p)\n",
2904  ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
2905  ulFlags, hMachine);
2906 
2907  if (pulLength == NULL)
2908  return CR_INVALID_POINTER;
2909 
2910  if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
2911  return CR_INVALID_PROPERTY;
2912 
2913  ulType = GetRegistryPropertyType(ulProperty);
2914  if (ulType == REG_SZ || ulType == REG_MULTI_SZ)
2915  {
2916  /* Get the required buffer size */
2917  ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2918  NULL, &ulLength, ulFlags, hMachine);
2919  if (ret != CR_BUFFER_SMALL)
2920  return ret;
2921 
2922  /* Allocate the unicode buffer */
2923  BufferW = HeapAlloc(GetProcessHeap(), 0, ulLength);
2924  if (BufferW == NULL)
2925  return CR_OUT_OF_MEMORY;
2926 
2927  /* Get the property */
2928  ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2929  BufferW, &ulLength, ulFlags, hMachine);
2930  if (ret != CR_SUCCESS)
2931  {
2932  HeapFree(GetProcessHeap(), 0, BufferW);
2933  return ret;
2934  }
2935 
2936  /* Do W->A conversion */
2937  *pulLength = WideCharToMultiByte(CP_ACP,
2938  0,
2939  BufferW,
2940  lstrlenW(BufferW) + 1,
2941  Buffer,
2942  *pulLength,
2943  NULL,
2944  NULL);
2945 
2946  /* Release the unicode buffer */
2947  HeapFree(GetProcessHeap(), 0, BufferW);
2948 
2949  if (*pulLength == 0)
2950  ret = CR_FAILURE;
2951  }
2952  else
2953  {
2954  /* Get the property */
2955  ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2956  Buffer, pulLength, ulFlags, hMachine);
2957  }
2958 
2959  return ret;
2960 }
2961 
2962 
2963 /***********************************************************************
2964  * CM_Get_Class_Registry_PropertyW [SETUPAPI.@]
2965  */
2966 CONFIGRET
2967 WINAPI
2969  LPGUID ClassGuid,
2970  ULONG ulProperty,
2971  PULONG pulRegDataType,
2972  PVOID Buffer,
2973  PULONG pulLength,
2974  ULONG ulFlags,
2975  HMACHINE hMachine)
2976 {
2978  WCHAR szGuidString[PNP_MAX_GUID_STRING_LEN + 1];
2979  ULONG ulType = 0;
2980  ULONG ulTransferLength = 0;
2981  CONFIGRET ret;
2982 
2983  TRACE("CM_Get_Class_Registry_PropertyW(%p %lu %p %p %p %lx %p)\n",
2984  ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
2985  ulFlags, hMachine);
2986 
2987  if (ClassGuid == NULL || pulLength == NULL)
2988  return CR_INVALID_POINTER;
2989 
2990  if (ulFlags != 0)
2991  return CR_INVALID_FLAG;
2992 
2993  if (pSetupStringFromGuid(ClassGuid,
2994  szGuidString,
2996  return CR_INVALID_DATA;
2997 
2998  if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
2999  return CR_INVALID_PROPERTY;
3000 
3001  if (hMachine != NULL)
3002  {
3003  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3004  if (BindingHandle == NULL)
3005  return CR_FAILURE;
3006  }
3007  else
3008  {
3010  return CR_FAILURE;
3011  }
3012 
3013  ulTransferLength = *pulLength;
3014 
3015  RpcTryExcept
3016  {
3018  szGuidString,
3019  ulProperty,
3020  &ulType,
3021  Buffer,
3022  &ulTransferLength,
3023  pulLength,
3024  ulFlags);
3025  }
3027  {
3029  }
3030  RpcEndExcept;
3031 
3032  if (ret == CR_SUCCESS)
3033  {
3034  if (pulRegDataType != NULL)
3035  *pulRegDataType = ulType;
3036  }
3037 
3038  return ret;
3039 }
3040 
3041 
3042 /***********************************************************************
3043  * CM_Get_Depth [SETUPAPI.@]
3044  */
3045 CONFIGRET
3046 WINAPI
3048  _Out_ PULONG pulDepth,
3049  _In_ DEVINST dnDevInst,
3050  _In_ ULONG ulFlags)
3051 {
3052  TRACE("CM_Get_Depth(%p %lx %lx)\n",
3053  pulDepth, dnDevInst, ulFlags);
3054 
3055  return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
3056 }
3057 
3058 
3059 /***********************************************************************
3060  * CM_Get_Depth_Ex [SETUPAPI.@]
3061  */
3062 CONFIGRET
3063 WINAPI
3065  _Out_ PULONG pulDepth,
3066  _In_ DEVINST dnDevInst,
3067  _In_ ULONG ulFlags,
3068  _In_opt_ HMACHINE hMachine)
3069 {
3071  HSTRING_TABLE StringTable = NULL;
3072  LPWSTR lpDevInst;
3073  CONFIGRET ret;
3074 
3075  TRACE("CM_Get_Depth_Ex(%p %lx %lx %p)\n",
3076  pulDepth, dnDevInst, ulFlags, hMachine);
3077 
3078  if (pulDepth == NULL)
3079  return CR_INVALID_POINTER;
3080 
3081  if (dnDevInst == 0)
3082  return CR_INVALID_DEVINST;
3083 
3084  if (ulFlags != 0)
3085  return CR_INVALID_FLAG;
3086 
3087  if (hMachine != NULL)
3088  {
3089  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3090  if (BindingHandle == NULL)
3091  return CR_FAILURE;
3092 
3093  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3094  if (StringTable == 0)
3095  return CR_FAILURE;
3096  }
3097  else
3098  {
3099  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3100  return CR_FAILURE;
3101  }
3102 
3103  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3104  if (lpDevInst == NULL)
3105  return CR_INVALID_DEVNODE;
3106 
3107  RpcTryExcept
3108  {
3110  lpDevInst,
3111  pulDepth,
3112  ulFlags);
3113  }
3115  {
3117  }
3118  RpcEndExcept;
3119 
3120  return ret;
3121 }
3122 
3123 
3124 /***********************************************************************
3125  * CM_Get_DevNode_Custom_PropertyA [SETUPAPI.@]
3126  */
3127 CONFIGRET
3128 WINAPI
3130  _In_ DEVINST dnDevInst,
3131  _In_ PCSTR pszCustomPropertyName,
3132  _Out_opt_ PULONG pulRegDataType,
3133  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3134  _Inout_ PULONG pulLength,
3135  _In_ ULONG ulFlags)
3136 {
3137  TRACE("CM_Get_DevNode_Custom_PropertyA(%lx %s %p %p %p %lx)\n",
3138  dnDevInst, pszCustomPropertyName, pulRegDataType,
3139  Buffer, pulLength, ulFlags);
3140 
3141  return CM_Get_DevNode_Custom_Property_ExA(dnDevInst, pszCustomPropertyName,
3142  pulRegDataType, Buffer,
3143  pulLength, ulFlags, NULL);
3144 }
3145 
3146 
3147 /***********************************************************************
3148  * CM_Get_DevNode_Custom_PropertyW [SETUPAPI.@]
3149  */
3150 CONFIGRET
3151 WINAPI
3153  _In_ DEVINST dnDevInst,
3154  _In_ PCWSTR pszCustomPropertyName,
3155  _Out_opt_ PULONG pulRegDataType,
3156  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3157  _Inout_ PULONG pulLength,
3158  _In_ ULONG ulFlags)
3159 {
3160  TRACE("CM_Get_DevNode_Custom_PropertyW(%lx %s %p %p %p %lx)\n",
3161  dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3162  Buffer, pulLength, ulFlags);
3163 
3164  return CM_Get_DevNode_Custom_Property_ExW(dnDevInst, pszCustomPropertyName,
3165  pulRegDataType, Buffer,
3166  pulLength, ulFlags, NULL);
3167 }
3168 
3169 
3170 /***********************************************************************
3171  * CM_Get_DevNode_Custom_Property_ExA [SETUPAPI.@]
3172  */
3173 CONFIGRET
3174 WINAPI
3176  _In_ DEVINST dnDevInst,
3177  _In_ PCSTR pszCustomPropertyName,
3178  _Out_opt_ PULONG pulRegDataType,
3179  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3180  _Inout_ PULONG pulLength,
3181  _In_ ULONG ulFlags,
3182  _In_opt_ HMACHINE hMachine)
3183 {
3184  LPWSTR pszPropertyNameW = NULL;
3185  PVOID BufferW;
3186  ULONG ulLengthW;
3187  ULONG ulDataType = REG_NONE;
3188  CONFIGRET ret;
3189 
3190  TRACE("CM_Get_DevNode_Custom_Property_ExA(%lx %s %p %p %p %lx %p)\n",
3191  dnDevInst, pszCustomPropertyName, pulRegDataType,
3192  Buffer, pulLength, ulFlags, hMachine);
3193 
3194  if (!pulLength)
3195  return CR_INVALID_POINTER;
3196 
3197  ulLengthW = *pulLength * sizeof(WCHAR);
3198  BufferW = HeapAlloc(GetProcessHeap(), 0, ulLengthW);
3199  if (!BufferW)
3200  return CR_OUT_OF_MEMORY;
3201 
3202  pszPropertyNameW = pSetupMultiByteToUnicode(pszCustomPropertyName,
3203  CP_ACP);
3204  if (pszPropertyNameW == NULL)
3205  {
3206  HeapFree(GetProcessHeap(), 0, BufferW);
3207  return CR_OUT_OF_MEMORY;
3208  }
3209 
3211  pszPropertyNameW,
3212  &ulDataType,
3213  BufferW,
3214  &ulLengthW,
3215  ulFlags,
3216  hMachine);
3217  if (ret == CR_SUCCESS)
3218  {
3219  if (ulDataType == REG_SZ ||
3220  ulDataType == REG_EXPAND_SZ ||
3221  ulDataType == REG_MULTI_SZ)
3222  {
3223  /* Do W->A conversion */
3224  *pulLength = WideCharToMultiByte(CP_ACP,
3225  0,
3226  BufferW,
3227  lstrlenW(BufferW) + 1,
3228  Buffer,
3229  *pulLength,
3230  NULL,
3231  NULL);
3232  if (*pulLength == 0)
3233  ret = CR_FAILURE;
3234  }
3235  else
3236  {
3237  /* Directly copy the value */
3238  if (ulLengthW <= *pulLength)
3239  memcpy(Buffer, BufferW, ulLengthW);
3240  else
3241  {
3242  *pulLength = ulLengthW;
3243  ret = CR_BUFFER_SMALL;
3244  }
3245  }
3246  }
3247 
3248  if (pulRegDataType)
3249  *pulRegDataType = ulDataType;
3250 
3251  HeapFree(GetProcessHeap(), 0, BufferW);
3252  MyFree(pszPropertyNameW);
3253 
3254  return ret;
3255 }
3256 
3257 
3258 /***********************************************************************
3259  * CM_Get_DevNode_Custom_Property_ExW [SETUPAPI.@]
3260  */
3261 CONFIGRET
3262 WINAPI
3264  _In_ DEVINST dnDevInst,
3265  _In_ PCWSTR pszCustomPropertyName,
3266  _Out_opt_ PULONG pulRegDataType,
3267  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3268  _Inout_ PULONG pulLength,
3269  _In_ ULONG ulFlags,
3270  _In_opt_ HMACHINE hMachine)
3271 {
3273  HSTRING_TABLE StringTable = NULL;
3274  LPWSTR lpDevInst;
3275  ULONG ulDataType = REG_NONE;
3276  ULONG ulTransferLength;
3278 
3279  TRACE("CM_Get_DevNode_Custom_Property_ExW(%lx %s %p %p %p %lx %p)\n",
3280  dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3281  Buffer, pulLength, ulFlags, hMachine);
3282 
3283  if (dnDevInst == 0)
3284  return CR_INVALID_DEVNODE;
3285 
3286  if (pszCustomPropertyName == NULL ||
3287  pulLength == NULL ||
3288  *pulLength == 0)
3289  return CR_INVALID_POINTER;
3290 
3291  if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
3292  return CR_INVALID_FLAG;
3293 
3294  if (hMachine != NULL)
3295  {
3296  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3297  if (BindingHandle == NULL)
3298  return CR_FAILURE;
3299 
3300  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3301  if (StringTable == 0)
3302  return CR_FAILURE;
3303  }
3304  else
3305  {
3306  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3307  return CR_FAILURE;
3308  }
3309 
3310  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3311  if (lpDevInst == NULL)
3312  return CR_INVALID_DEVNODE;
3313 
3314  ulTransferLength = *pulLength;
3315 
3316  RpcTryExcept
3317  {
3319  lpDevInst,
3320  (LPWSTR)pszCustomPropertyName,
3321  &ulDataType,
3322  Buffer,
3323  &ulTransferLength,
3324  pulLength,
3325  ulFlags);
3326  }
3328  {
3330  }
3331  RpcEndExcept;
3332 
3333  if (ret == CR_SUCCESS)
3334  {
3335  if (pulRegDataType != NULL)
3336  *pulRegDataType = ulDataType;
3337  }
3338 
3339  return ret;
3340 }
3341 
3342 
3343 /***********************************************************************
3344  * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
3345  */
3346 CONFIGRET
3347 WINAPI
3349  _In_ DEVINST dnDevInst,
3350  _In_ ULONG ulProperty,
3351  _Out_opt_ PULONG pulRegDataType,
3352  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3353  _Inout_ PULONG pulLength,
3354  _In_ ULONG ulFlags)
3355 {
3356  TRACE("CM_Get_DevNode_Registry_PropertyA(%lx %lu %p %p %p %lx)\n",
3357  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3358 
3359  return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
3360  pulRegDataType, Buffer,
3361  pulLength, ulFlags, NULL);
3362 }
3363 
3364 
3365 /***********************************************************************
3366  * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
3367  */
3368 CONFIGRET
3369 WINAPI
3371  _In_ DEVINST dnDevInst,
3372  _In_ ULONG ulProperty,
3373  _Out_opt_ PULONG pulRegDataType,
3374  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3375  _Inout_ PULONG pulLength,
3376  _In_ ULONG ulFlags)
3377 {
3378  TRACE("CM_Get_DevNode_Registry_PropertyW(%lx %lu %p %p %p %lx)\n",
3379  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3380 
3381  return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
3382  pulRegDataType, Buffer,
3383  pulLength, ulFlags, NULL);
3384 }
3385 
3386 
3387 /***********************************************************************
3388  * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
3389  */
3390 CONFIGRET
3391 WINAPI
3393  _In_ DEVINST dnDevInst,
3394  _In_ ULONG ulProperty,
3395  _Out_opt_ PULONG pulRegDataType,
3396  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3397  _Inout_ PULONG pulLength,
3398  _In_ ULONG ulFlags,
3399  _In_opt_ HMACHINE hMachine)
3400 {
3401  PVOID BufferW;
3402  ULONG LengthW;
3403  ULONG ulDataType = REG_NONE;
3404  CONFIGRET ret;
3405 
3406  TRACE("CM_Get_DevNode_Registry_Property_ExA(%lx %lu %p %p %p %lx %p)\n",
3407  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3408  ulFlags, hMachine);
3409 
3410  if (!pulLength)
3411  return CR_INVALID_POINTER;
3412 
3413  LengthW = *pulLength * sizeof(WCHAR);
3414  BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
3415 
3416  if (!BufferW)
3417  return CR_OUT_OF_MEMORY;
3418 
3420  ulProperty,
3421  &ulDataType,
3422  BufferW,
3423  &LengthW,
3424  ulFlags,
3425  hMachine);
3426 
3427  if (ret == CR_SUCCESS)
3428  {
3429  if (ulDataType == REG_SZ ||
3430  ulDataType == REG_EXPAND_SZ ||
3431  ulDataType == REG_MULTI_SZ)
3432  {
3433  /* Do W->A conversion */
3434  *pulLength = WideCharToMultiByte(CP_ACP,
3435  0,
3436  BufferW,
3437  lstrlenW(BufferW) + 1,
3438  Buffer,
3439  *pulLength,
3440  NULL,
3441  NULL);
3442  if (*pulLength == 0)
3443  ret = CR_FAILURE;
3444  }
3445  else
3446  {
3447  /* Directly copy the value */
3448  if (LengthW <= *pulLength)
3449  memcpy(Buffer, BufferW, LengthW);
3450  else
3451  {
3452  *pulLength = LengthW;
3453  ret = CR_BUFFER_SMALL;
3454  }
3455  }
3456  }
3457 
3458  if (pulRegDataType)
3459  *pulRegDataType = ulDataType;
3460 
3461  HeapFree(GetProcessHeap(), 0, BufferW);
3462 
3463  return ret;
3464 }
3465 
3466 
3467 /***********************************************************************
3468  * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
3469  */
3470 CONFIGRET
3471 WINAPI
3473  _In_ DEVINST dnDevInst,
3474  _In_ ULONG ulProperty,
3475  _Out_opt_ PULONG pulRegDataType,
3476  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3477  _Inout_ PULONG pulLength,
3478  _In_ ULONG ulFlags,
3479  _In_opt_ HMACHINE hMachine)
3480 {
3482  HSTRING_TABLE StringTable = NULL;
3484  LPWSTR lpDevInst;
3485  ULONG ulDataType = REG_NONE;
3486  ULONG ulTransferLength = 0;
3487 
3488  TRACE("CM_Get_DevNode_Registry_Property_ExW(%lx %lu %p %p %p %lx %p)\n",
3489  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3490  ulFlags, hMachine);
3491 
3492  if (dnDevInst == 0)
3493  return CR_INVALID_DEVNODE;
3494 
3495  if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
3496  return CR_INVALID_PROPERTY;
3497 
3498  /* pulRegDataType is optional */
3499 
3500  /* Buffer is optional */
3501 
3502  if (pulLength == NULL)
3503  return CR_INVALID_POINTER;
3504 
3505  if (*pulLength == 0)
3506  return CR_INVALID_POINTER;
3507 
3508  if (ulFlags != 0)
3509  return CR_INVALID_FLAG;
3510 
3511  if (hMachine != NULL)
3512  {
3513  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3514  if (BindingHandle == NULL)
3515  return CR_FAILURE;
3516 
3517  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3518  if (StringTable == 0)
3519  return CR_FAILURE;
3520  }
3521  else
3522  {
3523  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3524  return CR_FAILURE;
3525  }
3526 
3527  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3528  if (lpDevInst == NULL)
3529  return CR_INVALID_DEVNODE;
3530 
3531  ulTransferLength = *pulLength;
3532 
3533  RpcTryExcept
3534  {
3536  lpDevInst,
3537  ulProperty,
3538  &ulDataType,
3539  Buffer,
3540  &ulTransferLength,
3541  pulLength,
3542  ulFlags);
3543  }
3545  {
3547  }
3548  RpcEndExcept;
3549 
3550  if (ret == CR_SUCCESS)
3551  {
3552  if (pulRegDataType != NULL)
3553  *pulRegDataType = ulDataType;
3554  }
3555 
3556  return ret;
3557 }
3558 
3559 
3560 /***********************************************************************
3561  * CM_Get_DevNode_Status [SETUPAPI.@]
3562  */
3563 CONFIGRET
3564 WINAPI
3566  _Out_ PULONG pulStatus,
3567  _Out_ PULONG pulProblemNumber,
3568  _In_ DEVINST dnDevInst,
3569  _In_ ULONG ulFlags)
3570 {
3571  TRACE("CM_Get_DevNode_Status(%p %p %lx %lx)\n",
3572  pulStatus, pulProblemNumber, dnDevInst, ulFlags);
3573 
3574  return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
3575  ulFlags, NULL);
3576 }
3577 
3578 
3579 /***********************************************************************
3580  * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
3581  */
3582 CONFIGRET
3583 WINAPI
3585  _Out_ PULONG pulStatus,
3586  _Out_ PULONG pulProblemNumber,
3587  _In_ DEVINST dnDevInst,
3588  _In_ ULONG ulFlags,
3589  _In_opt_ HMACHINE hMachine)
3590 {
3592  HSTRING_TABLE StringTable = NULL;
3593  LPWSTR lpDevInst;
3594  CONFIGRET ret;
3595 
3596  TRACE("CM_Get_DevNode_Status_Ex(%p %p %lx %lx %p)\n",
3597  pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
3598 
3599  if (pulStatus == NULL || pulProblemNumber == NULL)
3600  return CR_INVALID_POINTER;
3601 
3602  if (dnDevInst == 0)
3603  return CR_INVALID_DEVINST;
3604 
3605  if (ulFlags != 0)
3606  return CR_INVALID_FLAG;
3607 
3608  if (hMachine != NULL)
3609  {
3610  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3611  if (BindingHandle == NULL)
3612  return CR_FAILURE;
3613 
3614  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3615  if (StringTable == 0)
3616  return CR_FAILURE;
3617  }
3618  else
3619  {
3620  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3621  return CR_FAILURE;
3622  }
3623 
3624  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3625  if (lpDevInst == NULL)
3626  return CR_INVALID_DEVNODE;
3627 
3628  RpcTryExcept
3629  {
3631  lpDevInst,
3632  pulStatus,
3633  pulProblemNumber,
3634  ulFlags);
3635  }
3637  {
3639  }
3640  RpcEndExcept;
3641 
3642  return ret;
3643 }
3644 
3645 
3646 /***********************************************************************
3647  * CM_Get_Device_IDA [SETUPAPI.@]
3648  */
3649 CONFIGRET
3650 WINAPI
3652  _In_ DEVINST dnDevInst,
3653  _Out_writes_(BufferLen) PCHAR Buffer,
3654  _In_ ULONG BufferLen,
3655  _In_ ULONG ulFlags)
3656 {
3657  TRACE("CM_Get_Device_IDA(%lx %p %lu %lx)\n",
3658  dnDevInst, Buffer, BufferLen, ulFlags);
3659 
3660  return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3661 }
3662 
3663 
3664 /***********************************************************************
3665  * CM_Get_Device_IDW [SETUPAPI.@]
3666  */
3667 CONFIGRET
3668 WINAPI
3670  _In_ DEVINST dnDevInst,
3671  _Out_writes_(BufferLen) PWCHAR Buffer,
3672  _In_ ULONG BufferLen,
3673  _In_ ULONG ulFlags)
3674 {
3675  TRACE("CM_Get_Device_IDW(%lx %p %lu %lx)\n",
3676  dnDevInst, Buffer, BufferLen, ulFlags);
3677 
3678  return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3679 }
3680 
3681 
3682 /***********************************************************************
3683  * CM_Get_Device_ID_ExA [SETUPAPI.@]
3684  */
3685 CONFIGRET
3686 WINAPI
3688  _In_ DEVINST dnDevInst,
3689  _Out_writes_(BufferLen) PCHAR Buffer,
3690  _In_ ULONG BufferLen,
3691  _In_ ULONG ulFlags,
3692  _In_opt_ HMACHINE hMachine)
3693 {
3694  WCHAR szBufferW[MAX_DEVICE_ID_LEN];
3696 
3697  TRACE("CM_Get_Device_ID_ExA(%lx %p %lu %lx %p)\n",
3698  dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3699 
3700  if (Buffer == NULL)
3701  return CR_INVALID_POINTER;
3702 
3703  ret = CM_Get_Device_ID_ExW(dnDevInst,
3704  szBufferW,
3706  ulFlags,
3707  hMachine);
3708  if (ret == CR_SUCCESS)
3709  {
3711  0,
3712  szBufferW,
3713  lstrlenW(szBufferW) + 1,
3714  Buffer,
3715  BufferLen,
3716  NULL,
3717  NULL) == 0)
3718  ret = CR_FAILURE;
3719  }
3720 
3721  return ret;
3722 }
3723 
3724 
3725 /***********************************************************************
3726  * CM_Get_Device_ID_ExW [SETUPAPI.@]
3727  */
3728 CONFIGRET
3729 WINAPI
3731  _In_ DEVINST dnDevInst,
3732  _Out_writes_(BufferLen) PWCHAR Buffer,
3733  _In_ ULONG BufferLen,
3734  _In_ ULONG ulFlags,
3735  _In_opt_ HMACHINE hMachine)
3736 {
3737  HSTRING_TABLE StringTable = NULL;
3738 
3739  TRACE("CM_Get_Device_ID_ExW(%lx %p %lu %lx %p)\n",
3740  dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3741 
3742  if (dnDevInst == 0)
3743  return CR_INVALID_DEVINST;
3744 
3745  if (Buffer == NULL)
3746  return CR_INVALID_POINTER;
3747 
3748  if (ulFlags != 0)
3749  return CR_INVALID_FLAG;
3750 
3751  if (hMachine != NULL)
3752  {
3753  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3754  if (StringTable == NULL)
3755  return CR_FAILURE;
3756  }
3757  else
3758  {
3759  if (!PnpGetLocalHandles(NULL, &StringTable))
3760  return CR_FAILURE;
3761  }
3762 
3763  if (!pSetupStringTableStringFromIdEx(StringTable,
3764  dnDevInst,
3765  Buffer,
3766  &BufferLen))
3767  return CR_FAILURE;
3768 
3769  return CR_SUCCESS;
3770 }
3771 
3772 
3773 /***********************************************************************
3774  * CM_Get_Device_ID_ListA [SETUPAPI.@]
3775  */
3776 CONFIGRET
3777 WINAPI
3779  _In_ PCSTR pszFilter,
3780  _Out_writes_(BufferLen) PCHAR Buffer,
3781  _In_ ULONG BufferLen,
3782  _In_ ULONG ulFlags)
3783 {
3784  TRACE("CM_Get_Device_ID_ListA(%p %p %lu %lx)\n",
3785  pszFilter, Buffer, BufferLen, ulFlags);
3786 
3787  return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
3788  ulFlags, NULL);
3789 }
3790 
3791 
3792 /***********************************************************************
3793  * CM_Get_Device_ID_ListW [SETUPAPI.@]
3794  */
3795 CONFIGRET
3796 WINAPI
3798  _In_ PCWSTR pszFilter,
3799  _Out_writes_(BufferLen) PWCHAR Buffer,
3800  _In_ ULONG BufferLen,
3801  _In_ ULONG ulFlags)
3802 {
3803  TRACE("CM_Get_Device_ID_ListW(%p %p %lu %lx)\n",
3804  pszFilter, Buffer, BufferLen, ulFlags);
3805 
3806  return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
3807  ulFlags, NULL);
3808 }
3809 
3810 
3811 /***********************************************************************
3812  * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
3813  */
3814 CONFIGRET
3815 WINAPI
3817  _In_ PCSTR pszFilter,
3818  _Out_writes_(BufferLen) PCHAR Buffer,
3819  _In_ ULONG BufferLen,
3820  _In_ ULONG ulFlags,
3821  _In_opt_ HMACHINE hMachine)
3822 {
3823  LPWSTR BufferW = NULL;
3824  LPWSTR pszFilterW = NULL;
3826 
3827  TRACE("CM_Get_Device_ID_List_ExA(%p %p %lu %lx %p)\n",
3828  pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3829 
3830  BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
3831  if (BufferW == NULL)
3832  return CR_OUT_OF_MEMORY;
3833 
3834  if (pszFilter == NULL)
3835  {
3837  BufferW,
3838  BufferLen,
3839  ulFlags,
3840  hMachine);
3841  }
3842  else
3843  {
3844  if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3845  {
3847  goto Done;
3848  }
3849 
3850  ret = CM_Get_Device_ID_List_ExW(pszFilterW,
3851  BufferW,
3852  BufferLen,
3853  ulFlags,
3854  hMachine);
3855 
3856  MyFree(pszFilterW);
3857  }
3858 
3860  0,
3861  BufferW,
3862  lstrlenW(BufferW) + 1,
3863  Buffer,
3864  BufferLen,
3865  NULL,
3866  NULL) == 0)
3867  ret = CR_FAILURE;
3868 
3869 Done:
3870  MyFree(BufferW);
3871 
3872  return ret;
3873 }
3874 
3875 
3876 /***********************************************************************
3877  * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
3878  */
3879 CONFIGRET
3880 WINAPI
3882  _In_ PCWSTR pszFilter,
3883  _Out_writes_(BufferLen) PWCHAR Buffer,
3884  _In_ ULONG BufferLen,
3885  _In_ ULONG ulFlags,
3886  _In_opt_ HMACHINE hMachine)
3887 {
3889  CONFIGRET ret;
3890 
3891  TRACE("CM_Get_Device_ID_List_ExW(%p %p %lu %lx %p)\n",
3892  pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3893 
3894  if (Buffer == NULL || BufferLen == 0)
3895  return CR_INVALID_POINTER;
3896 
3897  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
3898  return CR_INVALID_FLAG;
3899 
3900  if (hMachine != NULL)
3901  {
3902  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3903  if (BindingHandle == NULL)
3904  return CR_FAILURE;
3905  }
3906  else
3907  {
3909  return CR_FAILURE;
3910  }
3911 
3912  *Buffer = 0;
3913 
3914  RpcTryExcept
3915  {
3917  (LPWSTR)pszFilter,
3918  Buffer,
3919  &BufferLen,
3920  ulFlags);
3921  }
3923  {
3925  }
3926  RpcEndExcept;
3927 
3928  return ret;
3929 }
3930 
3931 
3932 /***********************************************************************
3933  * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
3934  */
3935 CONFIGRET
3936 WINAPI
3938  _Out_ PULONG pulLen,
3939  _In_opt_ PCSTR pszFilter,
3940  _In_ ULONG ulFlags)
3941 {
3942  TRACE("CM_Get_Device_ID_List_SizeA(%p %s %lx)\n",
3943  pulLen, debugstr_a(pszFilter), ulFlags);
3944 
3945  return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
3946 }
3947 
3948 
3949 /***********************************************************************
3950  * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
3951  */
3952 CONFIGRET
3953 WINAPI
3955  _Out_ PULONG pulLen,
3956  _In_opt_ PCWSTR pszFilter,
3957  _In_ ULONG ulFlags)
3958 {
3959  TRACE("CM_Get_Device_ID_List_SizeW(%p %s %lx)\n",
3960  pulLen, debugstr_w(pszFilter), ulFlags);
3961 
3962  return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
3963 }
3964 
3965 
3966 /***********************************************************************
3967  * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
3968  */
3969 CONFIGRET
3970 WINAPI
3972  _Out_ PULONG pulLen,
3973  _In_opt_ PCSTR pszFilter,
3974  _In_ ULONG ulFlags,
3975  _In_opt_ HMACHINE hMachine)
3976 {
3977  LPWSTR pszFilterW = NULL;
3979 
3980  FIXME("CM_Get_Device_ID_List_Size_ExA(%p %s %lx %p)\n",
3981  pulLen, debugstr_a(pszFilter), ulFlags, hMachine);
3982 
3983  if (pszFilter == NULL)
3984  {
3986  NULL,
3987  ulFlags,
3988  hMachine);
3989  }
3990  else
3991  {
3992  if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3993  return CR_INVALID_DEVICE_ID;
3994 
3996  pszFilterW,
3997  ulFlags,
3998  hMachine);
3999 
4000  MyFree(pszFilterW);
4001  }
4002 
4003  return ret;
4004 }
4005 
4006 
4007 /***********************************************************************
4008  * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
4009  */
4010 CONFIGRET
4011 WINAPI
4013  _Out_ PULONG pulLen,
4014  _In_opt_ PCWSTR pszFilter,
4015  _In_ ULONG ulFlags,
4016  _In_opt_ HMACHINE hMachine)
4017 {
4019  CONFIGRET ret;
4020 
4021  FIXME("CM_Get_Device_ID_List_Size_ExW(%p %s %lx %p)\n",
4022  pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
4023 
4024  if (pulLen == NULL)
4025  return CR_INVALID_POINTER;
4026 
4027  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
4028  return CR_INVALID_FLAG;
4029 
4030  if (hMachine != NULL)
4031  {
4032  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4033  if (BindingHandle == NULL)
4034  return CR_FAILURE;
4035  }
4036  else
4037  {
4039  return CR_FAILURE;
4040  }
4041 
4042  *pulLen = 0;
4043 
4044  RpcTryExcept
4045  {
4047  (LPWSTR)pszFilter,
4048  pulLen,
4049  ulFlags);
4050  }
4052  {
4054  }
4055  RpcEndExcept;
4056 
4057  return ret;
4058 }
4059 
4060 
4061 /***********************************************************************
4062  * CM_Get_Device_ID_Size [SETUPAPI.@]
4063  */
4064 CONFIGRET
4065 WINAPI
4067  _Out_ PULONG pulLen,
4068  _In_ DEVINST dnDevInst,
4069  _In_ ULONG ulFlags)
4070 {
4071  TRACE("CM_Get_Device_ID_Size(%p %lx %lx)\n",
4072  pulLen, dnDevInst, ulFlags);
4073 
4074  return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
4075 }
4076 
4077 
4078 /***********************************************************************
4079  * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
4080  */
4081 CONFIGRET
4082 WINAPI
4084  _Out_ PULONG pulLen,
4085  _In_ DEVINST dnDevInst,
4086  _In_ ULONG ulFlags,
4087  _In_opt_ HMACHINE hMachine)
4088 {
4089  HSTRING_TABLE StringTable = NULL;
4090  LPWSTR DeviceId;
4091 
4092  TRACE("CM_Get_Device_ID_Size_Ex(%p %lx %lx %p)\n",
4093  pulLen, dnDevInst, ulFlags, hMachine);
4094 
4095  if (pulLen == NULL)
4096  return CR_INVALID_POINTER;
4097 
4098  if (dnDevInst == 0)
4099  return CR_INVALID_DEVINST;
4100 
4101  if (ulFlags != 0)
4102  return CR_INVALID_FLAG;
4103 
4104  if (hMachine != NULL)
4105  {
4106  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4107  if (StringTable == NULL)
4108  return CR_FAILURE;
4109  }
4110  else
4111  {
4112  if (!PnpGetLocalHandles(NULL, &StringTable))
4113  return CR_FAILURE;
4114  }
4115 
4116  DeviceId = pSetupStringTableStringFromId(StringTable, dnDevInst);
4117  if (DeviceId == NULL)
4118  {
4119  *pulLen = 0;
4120  return CR_SUCCESS;
4121  }
4122 
4123  *pulLen = lstrlenW(DeviceId);
4124 
4125  return CR_SUCCESS;
4126 }
4127 
4128 
4129 /***********************************************************************
4130  * CM_Get_Device_Interface_AliasA [SETUPAPI.@]
4131  */
4132 CONFIGRET
4133 WINAPI
4135  _In_ LPCSTR pszDeviceInterface,
4136  _In_ LPGUID AliasInterfaceGuid,
4137  _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4138  _Inout_ PULONG pulLength,
4139  _In_ ULONG ulFlags)
4140 {
4141  TRACE("CM_Get_Device_Interface_AliasA(%p %p %p %p %lx)\n",
4142  pszDeviceInterface, AliasInterfaceGuid,
4143  pszAliasDeviceInterface, pulLength, ulFlags);
4144 
4145  return CM_Get_Device_Interface_Alias_ExA(pszDeviceInterface,
4146  AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4147  ulFlags, NULL);
4148 }
4149 
4150 
4151 /***********************************************************************
4152  * CM_Get_Device_Interface_AliasW [SETUPAPI.@]
4153  */
4154 CONFIGRET
4155 WINAPI
4157  _In_ LPCWSTR pszDeviceInterface,
4158  _In_ LPGUID AliasInterfaceGuid,
4159  _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4160  _Inout_ PULONG pulLength,
4161  _In_ ULONG ulFlags)
4162 {
4163  TRACE("CM_Get_Device_Interface_AliasW(%p %p %p %p %lx)\n",
4164  pszDeviceInterface, AliasInterfaceGuid,
4165  pszAliasDeviceInterface, pulLength, ulFlags);
4166 
4167  return CM_Get_Device_Interface_Alias_ExW(pszDeviceInterface,
4168  AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4169  ulFlags, NULL);
4170 }
4171 
4172 
4173 /***********************************************************************
4174  * CM_Get_Device_Interface_Alias_ExA [SETUPAPI.@]
4175  */
4176 CONFIGRET
4177 WINAPI
4179  _In_ LPCSTR pszDeviceInterface,
4180  _In_ LPGUID AliasInterfaceGuid,
4181  _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4182  _Inout_ PULONG pulLength,
4183  _In_ ULONG ulFlags,
4184  _In_opt_ HMACHINE hMachine)
4185 {
4186  FIXME("CM_Get_Device_Interface_Alias_ExA(%p %p %p %p %lx %p)\n",
4187  pszDeviceInterface, AliasInterfaceGuid,
4188  pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4189 
4190  return CR_CALL_NOT_IMPLEMENTED;
4191 }
4192 
4193 
4194 /***********************************************************************
4195  * CM_Get_Device_Interface_Alias_ExW [SETUPAPI.@]
4196  */
4197 CONFIGRET
4198 WINAPI
4200  _In_ LPCWSTR pszDeviceInterface,
4201  _In_ LPGUID AliasInterfaceGuid,
4202  _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4203  _Inout_ PULONG pulLength,
4204  _In_ ULONG ulFlags,
4205  _In_opt_ HMACHINE hMachine)
4206 {
4208  ULONG ulTransferLength;
4210 
4211  TRACE("CM_Get_Device_Interface_Alias_ExW(%p %p %p %p %lx %p)\n",
4212  pszDeviceInterface, AliasInterfaceGuid,
4213  pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4214 
4215  if (pszDeviceInterface == NULL ||
4216  AliasInterfaceGuid == NULL ||
4217  pszAliasDeviceInterface == NULL ||
4218  pulLength == NULL)
4219  return CR_INVALID_POINTER;
4220 
4221  if (ulFlags != 0)
4222  return CR_INVALID_FLAG;
4223 
4224  if (hMachine != NULL)
4225  {
4226  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4227  if (BindingHandle == NULL)
4228  return CR_FAILURE;
4229  }
4230  else
4231  {
4233  return CR_FAILURE;
4234  }
4235 
4236  ulTransferLength = *pulLength;
4237 
4238  RpcTryExcept
4239  {
4241  (LPWSTR)pszDeviceInterface,
4242  AliasInterfaceGuid,
4243  pszAliasDeviceInterface,
4244  pulLength,
4245  &ulTransferLength,
4246  0);
4247  }
4249  {
4251  }
4252  RpcEndExcept;
4253 
4254  return ret;
4255 }
4256 
4257 
4258 /***********************************************************************
4259  * CM_Get_Device_Interface_ListA (SETUPAPI.@)
4260  */
4261 CONFIGRET
4262 WINAPI
4265  _In_opt_ DEVINSTID_A pDeviceID,
4266  _Out_writes_(BufferLen) PCHAR Buffer,
4267  _In_ ULONG BufferLen,
4268  _In_ ULONG ulFlags)
4269 {
4270  TRACE("CM_Get_Device_Interface_ListA(%s %s %p %lu 0x%08lx)\n",
4272  Buffer, BufferLen, ulFlags);
4273 
4275  Buffer, BufferLen, ulFlags, NULL);
4276 }
4277 
4278 
4279 /***********************************************************************
4280  * CM_Get_Device_Interface_ListW (SETUPAPI.@)
4281  */
4282 CONFIGRET
4283 WINAPI
4286  _In_opt_ DEVINSTID_W pDeviceID,
4287  _Out_writes_(BufferLen) PWCHAR Buffer,
4288  _In_ ULONG BufferLen,
4289  _In_ ULONG ulFlags)
4290 {
4291  TRACE("CM_Get_Device_Interface_ListW(%s %s %p %lu 0x%08lx)\n",
4293  Buffer, BufferLen, ulFlags);
4294 
4296  Buffer, BufferLen, ulFlags, NULL);
4297 }
4298 
4299 
4300 /***********************************************************************
4301  * CM_Get_Device_Interface_List_ExA (SETUPAPI.@)
4302  */
4303 CONFIGRET
4304 WINAPI
4307  _In_opt_ DEVINSTID_A pDeviceID,
4308  _Out_writes_(BufferLen) PCHAR Buffer,
4309  _In_ ULONG BufferLen,
4310  _In_ ULONG ulFlags,
4311  _In_opt_ HMACHINE hMachine)
4312 {
4313  DEVINSTID_W pDeviceIdW = NULL;
4314  PWCHAR BufferW = NULL;
4316 
4317  TRACE("CM_Get_Device_Interface_List_ExA(%s %s %p %lu 0x%08lx %p)\n",
4319  Buffer, BufferLen, ulFlags, hMachine);
4320 
4321  if (Buffer == NULL ||
4322  BufferLen == 0)
4323  return CR_INVALID_POINTER;
4324 
4325  if (pDeviceID != NULL)
4326  {
4327  if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4328  return CR_INVALID_DEVICE_ID;
4329  }
4330 
4331  BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
4332  if (BufferW == NULL)
4333  {
4335  goto Done;
4336  }
4337 
4339  BufferW, BufferLen, ulFlags,
4340  hMachine);
4341  if (ret != CR_SUCCESS)
4342  goto Done;
4343 
4345  0,
4346  BufferW,
4347  lstrlenW(BufferW) + 1,
4348  Buffer,
4349  BufferLen,
4350  NULL,
4351  NULL) == 0)
4352  ret = CR_FAILURE;
4353 
4354 Done:
4355  if (BufferW != NULL)
4356  MyFree(BufferW);
4357 
4358  if (pDeviceIdW != NULL)
4359  MyFree(pDeviceIdW);
4360 
4361  return ret;
4362 }
4363 
4364 
4365 /***********************************************************************
4366  * CM_Get_Device_Interface_List_ExW (SETUPAPI.@)
4367  */
4368 CONFIGRET
4369 WINAPI
4372  _In_opt_ DEVINSTID_W pDeviceID,
4373  _Out_writes_(BufferLen) PWCHAR Buffer,
4374  _In_ ULONG BufferLen,
4375  _In_ ULONG ulFlags,
4376  _In_opt_ HMACHINE hMachine)
4377 {
4381 
4382  TRACE("CM_Get_Device_Interface_List_ExW(%s %s %p %lu 0x%08lx %p)\n",
4384  Buffer, BufferLen, ulFlags, hMachine);
4385 
4386  if (Buffer == NULL ||
4387  BufferLen == 0)
4388  return CR_INVALID_POINTER;
4389 
4390  if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4391  return CR_INVALID_FLAG;
4392 
4393  if (hMachine != NULL)
4394  {
4395  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4396  if (BindingHandle == NULL)
4397  return CR_FAILURE;
4398  }
4399  else
4400  {
4402  return CR_FAILURE;
4403  }
4404 
4405  *Buffer = 0;
4406  BufferSize = BufferLen;
4407 
4408  RpcTryExcept
4409  {
4412  pDeviceID,
4413  (LPBYTE)Buffer,
4414  &BufferSize,
4415  ulFlags);
4416  }
4418  {
4420  }
4421  RpcEndExcept;
4422 
4423  return ret;
4424 }
4425 
4426 
4427 /***********************************************************************
4428  * CM_Get_Device_Interface_List_SizeA (SETUPAPI.@)
4429  */
4430 CONFIGRET
4431 WINAPI
4433  _Out_ PULONG pulLen,
4435  _In_opt_ DEVINSTID_A pDeviceID,
4436  _In_ ULONG ulFlags)
4437 {
4438  TRACE("CM_Get_Device_Interface_List_SizeA(%p %p %s 0x%08lx)\n",
4439  pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags);
4440 
4442  pDeviceID, ulFlags, NULL);
4443 }
4444 
4445 
4446 /***********************************************************************
4447  * CM_Get_Device_Interface_List_SizeW (SETUPAPI.@)
4448  */
4449 CONFIGRET
4450 WINAPI
4452  _Out_ PULONG pulLen,
4454  _In_opt_ DEVINSTID_W pDeviceID,
4455  _In_ ULONG ulFlags)
4456 {
4457  TRACE("CM_Get_Device_Interface_List_SizeW(%p %p %s 0x%08lx)\n",
4458  pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags);
4459 
4461  pDeviceID, ulFlags, NULL);
4462 }
4463 
4464 
4465 /***********************************************************************
4466  * CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@)
4467  */
4468 CONFIGRET
4469 WINAPI
4471  _Out_ PULONG pulLen,
4473  _In_opt_ DEVINSTID_A pDeviceID,
4474  _In_ ULONG ulFlags,
4475  _In_opt_ HMACHINE hMachine)
4476 {
4477  DEVINSTID_W pDeviceIdW = NULL;
4479 
4480  TRACE("CM_Get_Device_Interface_List_Size_ExA(%p %p %s 0x%08lx %p)\n",
4481  pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags, hMachine);
4482 
4483  if (pulLen == NULL)
4484  return CR_INVALID_POINTER;
4485 
4486  if (pDeviceID != NULL)
4487  {
4488  if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4489  return CR_INVALID_DEVICE_ID;
4490  }
4491 
4492  *pulLen = 0;
4493 
4495  pDeviceIdW, ulFlags, hMachine);
4496 
4497  if (pDeviceIdW != NULL)
4498  MyFree(pDeviceIdW);
4499 
4500  return ret;
4501 }
4502 
4503 
4504 /***********************************************************************
4505  * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@)
4506  */
4507 CONFIGRET
4508 WINAPI
4510  _Out_ PULONG pulLen,
4512  _In_opt_ DEVINSTID_W pDeviceID,
4513  _In_ ULONG ulFlags,
4514  _In_opt_ HMACHINE hMachine)
4515 {
4518 
4519  TRACE("CM_Get_Device_Interface_List_Size_ExW(%p %p %s 0x%08lx %p)\n",
4520  pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags, hMachine);
4521 
4522  if (pulLen == NULL)
4523  return CR_INVALID_POINTER;
4524 
4525  if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4526  return CR_INVALID_FLAG;
4527 
4528  if (hMachine != NULL)
4529  {
4530  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4531  if (BindingHandle == NULL)
4532  return CR_FAILURE;
4533  }
4534  else
4535  {
4537  return CR_FAILURE;
4538  }
4539 
4540  *pulLen = 0;
4541 
4542  RpcTryExcept
4543  {
4545  pulLen,
4547  pDeviceID,
4548  ulFlags);
4549  }
4551  {
4553  }
4554  RpcEndExcept;
4555 
4556  return ret;
4557 }
4558 
4559 
4560 /***********************************************************************
4561  * CM_Get_First_Log_Conf [SETUPAPI.@]
4562  */
4563 CONFIGRET
4564 WINAPI
4566  _Out_opt_ PLOG_CONF plcLogConf,
4567  _In_ DEVINST dnDevInst,
4568  _In_ ULONG ulFlags)
4569 {
4570  TRACE("CM_Get_First_Log_Conf(%p %lx %lx)\n",
4571  plcLogConf, dnDevInst, ulFlags);
4572 
4573  return CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, NULL);
4574 }
4575 
4576 
4577 /***********************************************************************
4578  * CM_Get_First_Log_Conf_Ex [SETUPAPI.@]
4579  */
4580 CONFIGRET
4581 WINAPI
4583  _Out_opt_ PLOG_CONF plcLogConf,
4584  _In_ DEVINST dnDevInst,
4585  _In_ ULONG ulFlags,
4586  _In_opt_ HMACHINE hMachine)
4587 {
4589  HSTRING_TABLE StringTable = NULL;
4590  LPWSTR lpDevInst = NULL;
4592  ULONG ulTag;
4593  PLOG_CONF_INFO pLogConfInfo;
4594 
4595  FIXME("CM_Get_First_Log_Conf_Ex(%p %lx %lx %p)\n",
4596  plcLogConf, dnDevInst, ulFlags, hMachine);
4597 
4598  if (dnDevInst == 0)
4599  return CR_INVALID_DEVINST;
4600 
4601  if (ulFlags & ~LOG_CONF_BITS)
4602  return CR_INVALID_FLAG;
4603 
4604  if (plcLogConf)
4605  *plcLogConf = 0;
4606 
4607  if (hMachine != NULL)
4608  {
4609  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4610  if (BindingHandle == NULL)
4611  return CR_FAILURE;
4612 
4613  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4614  if (StringTable == 0)
4615  return CR_FAILURE;
4616  }
4617  else
4618  {
4619  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
4620  return CR_FAILURE;
4621  }
4622 
4623  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
4624  if (lpDevInst == NULL)
4625  return CR_INVALID_DEVNODE;
4626 
4627  RpcTryExcept
4628  {
4630  lpDevInst,
4631  ulFlags,
4632  &ulTag,
4633  ulFlags);
4634  }
4636  {
4638  }
4639  RpcEndExcept;
4640 
4641  if (ret != CR_SUCCESS)
4642  return ret;
4643 
4644  if (plcLogConf)
4645  {
4646  pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
4647  if (pLogConfInfo == NULL)
4648  return CR_OUT_OF_MEMORY;
4649 
4650  pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
4651  pLogConfInfo->dnDevInst = dnDevInst;
4652  pLogConfInfo->ulType = ulFlags;
4653  pLogConfInfo->ulTag = ulTag;
4654 
4655  *plcLogConf = (LOG_CONF)pLogConfInfo;
4656  }
4657 
4658  return CR_SUCCESS;
4659 }
4660 
4661 
4662 /***********************************************************************
4663  * CM_Get_Global_State [SETUPAPI.@]
4664  */
4665 CONFIGRET
4666 WINAPI
4668  _Out_ PULONG pulState,
4669  _In_ ULONG ulFlags)
4670 {
4671  TRACE("CM_Get_Global_State(%p %lx)\n",
4672  pulState, ulFlags);
4673 
4674  return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
4675 }
4676 
4677 
4678 /***********************************************************************
4679  * CM_Get_Global_State_Ex [SETUPAPI.@]
4680  */
4681 CONFIGRET
4682 WINAPI
4684  _Out_ PULONG pulState,
4685  _In_ ULONG ulFlags,
4686  _In_opt_ HMACHINE hMachine)
4687 {
4689  CONFIGRET ret;
4690 
4691  TRACE("CM_Get_Global_State_Ex(%p %lx %p)\n",
4692  pulState, ulFlags, hMachine);
4693 
4694  if (pulState == NULL)
4695  return CR_INVALID_POINTER;
4696 
4697  if (ulFlags != 0)
4698  return CR_INVALID_FLAG;
4699 
4700  if (hMachine != NULL)
4701  {
4702  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4703  if (BindingHandle == NULL)
4704  return CR_FAILURE;
4705  }
4706  else
4707  {
4709  return CR_FAILURE;
4710  }
4711 
4712  RpcTryExcept
4713  {
4714  ret = PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
4715  }
4717  {
4719  }
4720  RpcEndExcept;
4721 
4722  return ret;
4723 }
4724 
4725 
4726 /***********************************************************************
4727  * CM_Get_HW_Prof_FlagsA [SETUPAPI.@]
4728  */
4729 CONFIGRET
4730 WINAPI
4732  _In_ DEVINSTID_A szDevInstName,
4733  _In_ ULONG ulHardwareProfile,
4734  _Out_ PULONG pulValue,
4735  _In_ ULONG ulFlags)
4736 {
4737  TRACE("CM_Get_HW_Prof_FlagsA(%s %lu %p %lx)\n",
4738  debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4739 
4740  return CM_Get_HW_Prof_Flags_ExA(szDevInstName, ulHardwareProfile,
4741  pulValue, ulFlags, NULL);
4742 }
4743 
4744 
4745 /***********************************************************************
4746  * CM_Get_HW_Prof_FlagsW [SETUPAPI.@]
4747  */
4748 CONFIGRET
4749 WINAPI
4751  _In_ DEVINSTID_W szDevInstName,
4752  _In_ ULONG ulHardwareProfile,
4753  _Out_ PULONG pulValue,
4754  _In_ ULONG ulFlags)
4755 {
4756  TRACE("CM_Get_HW_Prof_FlagsW(%s %lu %p %lx)\n",
4757  debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4758 
4759  return CM_Get_HW_Prof_Flags_ExW(szDevInstName, ulHardwareProfile,
4760  pulValue, ulFlags, NULL);
4761 }
4762 
4763 
4764 /***********************************************************************
4765  * CM_Get_HW_Prof_Flags_ExA [SETUPAPI.@]
4766  */
4767 CONFIGRET
4768 WINAPI
4770  _In_ DEVINSTID_A szDevInstName,
4771  _In_ ULONG ulHardwareProfile,
4772  _Out_ PULONG pulValue,
4773  _In_ ULONG ulFlags,
4774  _In_opt_ HMACHINE hMachine)
4775 {
4776  DEVINSTID_W pszDevIdW = NULL;
4778 
4779  TRACE("CM_Get_HW_Prof_Flags_ExA(%s %lu %p %lx %p)\n",
4780  debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4781 
4782  if (szDevInstName != NULL)
4783  {
4784  if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
4785  return CR_INVALID_DEVICE_ID;
4786  }
4787 
4788  ret = CM_Get_HW_Prof_Flags_ExW(pszDevIdW, ulHardwareProfile,
4789  pulValue, ulFlags, hMachine);
4790 
4791  if (pszDevIdW != NULL)
4792  MyFree(pszDevIdW);
4793 
4794  return ret;
4795 }
4796 
4797 
4798 /***********************************************************************
4799  * CM_Get_HW_Prof_Flags_ExW [SETUPAPI.@]
4800  */
4801 CONFIGRET
4802 WINAPI
4804  _In_ DEVINSTID_W szDevInstName,
4805  _In_ ULONG ulHardwareProfile,
4806  _Out_ PULONG pulValue,
4807  _In_ ULONG ulFlags,
4808  _In_opt_ HMACHINE hMachine)
4809 {
4811  CONFIGRET ret;
4812 
4813  FIXME("CM_Get_HW_Prof_Flags_ExW(%s %lu %p %lx %p)\n",
4814  debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4815 
4816  if ((szDevInstName == NULL) || (pulValue == NULL))
4817  return CR_INVALID_POINTER;
4818 
4819  if (ulFlags != 0)
4820  return CR_INVALID_FLAG;
4821 
4822  /* FIXME: Check whether szDevInstName is valid */
4823 
4824  if (hMachine != NULL)
4825  {
4826  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4827  if (BindingHandle == NULL)
4828  return CR_FAILURE;
4829  }
4830  else
4831  {
4833  return CR_FAILURE;
4834  }
4835 
4836  RpcTryExcept
4837  {
4838  ret = PNP_HwProfFlags(BindingHandle, PNP_GET_HWPROFFLAGS, szDevInstName,
4839  ulHardwareProfile, pulValue, NULL, NULL, 0, 0);
4840  }
4842  {
4844  }
4845  RpcEndExcept;
4846 
4847  return ret;
4848 }
4849 
4850 
4851 /***********************************************************************
4852  * CM_Get_Hardware_Profile_InfoA [SETUPAPI.@]
4853  */
4854 CONFIGRET
4855 WINAPI
4857  _In_ ULONG ulIndex,
4858  _Out_ PHWPROFILEINFO_A pHWProfileInfo,
4859  _In_ ULONG ulFlags)
4860 {
4861  TRACE("CM_Get_Hardware_Profile_InfoA(%lu %p %lx)\n",
4862  ulIndex, pHWProfileInfo, ulFlags);
4863 
4864  return CM_Get_Hardware_Profile_Info_ExA(ulIndex, pHWProfileInfo,
4865  ulFlags, NULL);
4866 }
4867 
4868 
4869 /***********************************************************************
4870  * CM_Get_Hardware_Profile_InfoW [SETUPAPI.@]
4871  */
4872 CONFIGRET
4873 WINAPI
4875  _In_ ULONG ulIndex,
4876  _Out_ PHWPROFILEINFO_W pHWProfileInfo,
4877  _In_ ULONG ulFlags)
4878 {
4879  TRACE("CM_Get_Hardware_Profile_InfoW(%lu %p %lx)\n",
4880  ulIndex, pHWProfileInfo, ulFlags);
4881 
4882  return CM_Get_Hardware_Profile_Info_ExW(ulIndex, pHWProfileInfo,
4883  ulFlags, NULL);
4884 }
4885 
4886 
4887 /***********************************************************************
4888  * CM_Get_Hardware_Profile_Info_ExA [SETUPAPI.@]
4889  */
4890 CONFIGRET
4891 WINAPI
4893  _In_ ULONG ulIndex,
4894  _Out_ PHWPROFILEINFO_A pHWProfileInfo,
4895  _In_ ULONG ulFlags,
4896  _In_opt_ HMACHINE hMachine)
4897 {
4898  HWPROFILEINFO_W LocalProfileInfo;
4899  CONFIGRET ret;
4900 
4901  TRACE("CM_Get_Hardware_Profile_Info_ExA(%lu %p %lx %p)\n",
4902  ulIndex, pHWProfileInfo, ulFlags, hMachine);
4903 
4904  if (pHWProfileInfo == NULL)
4905  return CR_INVALID_POINTER;
4906 
4907  ret = CM_Get_Hardware_Profile_Info_ExW(ulIndex, &LocalProfileInfo,
4908  ulFlags, hMachine);
4909  if (ret == CR_SUCCESS)
4910  {
4911  pHWProfileInfo->HWPI_ulHWProfile = LocalProfileInfo.HWPI_ulHWProfile;
4912  pHWProfileInfo->HWPI_dwFlags = LocalProfileInfo.HWPI_dwFlags;
4913 
4915  0,
4916  LocalProfileInfo.HWPI_szFriendlyName,
4917  lstrlenW(LocalProfileInfo.HWPI_szFriendlyName) + 1,
4918  pHWProfileInfo->HWPI_szFriendlyName,
4920  NULL,
4921  NULL) == 0)
4922  ret = CR_FAILURE;
4923  }
4924 
4925  return ret;
4926 }
4927 
4928 
4929 /***********************************************************************
4930  * CM_Get_Hardware_Profile_Info_ExW [SETUPAPI.@]
4931  */
4932 CONFIGRET
4933 WINAPI
4935  _In_ ULONG ulIndex,
4936  _Out_ PHWPROFILEINFO_W pHWProfileInfo,
4937  _In_ ULONG ulFlags,
4938  _In_opt_ HMACHINE hMachine)
4939 {
4941  CONFIGRET ret;
4942 
4943  TRACE("CM_Get_Hardware_Profile_Info_ExW(%lu %p %lx %p)\n",
4944  ulIndex, pHWProfileInfo, ulFlags, hMachine);
4945 
4946  if (pHWProfileInfo == NULL)
4947  return CR_INVALID_POINTER;
4948 
4949  if (ulFlags != 0)
4950  return CR_INVALID_FLAG;
4951 
4952  if (hMachine != NULL)
4953  {
4954  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4955  if (BindingHandle == NULL)
4956  return CR_FAILURE;
4957  }
4958  else
4959  {
4961  return CR_FAILURE;
4962  }
4963 
4964  RpcTryExcept
4965  {
4966  ret = PNP_GetHwProfInfo(BindingHandle, ulIndex, pHWProfileInfo,
4967  sizeof(HWPROFILEINFO_W), 0);
4968  }
4970  {
4972  }
4973  RpcEndExcept;
4974 
4975  return ret;
4976 }
4977 
4978 
4979 /***********************************************************************
4980  * CM_Get_Log_Conf_Priority [SETUPAPI.@]
4981  */
4982 CONFIGRET
4983 WINAPI
4985  _In_ LOG_CONF lcLogConf,
4986  _Out_ PPRIORITY pPriority,
4987  _In_ ULONG ulFlags)
4988 {
4989  TRACE("CM_Get_Log_Conf_Priority(%p %p %lx)\n",
4990  lcLogConf, pPriority, ulFlags);
4991 
4992  return CM_Get_Log_Conf_Priority_Ex(lcLogConf, pPriority, ulFlags, NULL);
4993 }
4994 
4995 
4996 /***********************************************************************
4997  * CM_Get_Log_Conf_Priority_Ex [SETUPAPI.@]
4998  */
4999 CONFIGRET
5000 WINAPI
5002  _In_ LOG_CONF lcLogConf,
5003  _Out_ PPRIORITY pPriority,
5004  _In_ ULONG ulFlags,
5005  _In_opt_ HMACHINE hMachine)
5006 {
5008  HSTRING_TABLE StringTable = NULL;
5009  PLOG_CONF_INFO pLogConfInfo;
5010  LPWSTR lpDevInst;
5011  CONFIGRET ret;
5012 
5013  FIXME("CM_Get_Log_Conf_Priority_Ex(%p %p %lx %p)\n",
5014  lcLogConf, pPriority, ulFlags, hMachine);
5015 
5016  pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
5017  if (!IsValidLogConf(pLogConfInfo))
5018  return CR_INVALID_LOG_CONF;
5019 
5020  if (pPriority == NULL)
5021  return CR_INVALID_POINTER;
5022 
5023  if (ulFlags != 0)
5024  return CR_INVALID_FLAG;
5025 
5026  if (hMachine != NULL)
5027  {
5028  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5029  if (BindingHandle == NULL)
5030  return CR_FAILURE;
5031 
5032  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5033  if (StringTable == 0)
5034  return CR_FAILURE;
5035  }
5036  else
5037  {
5038  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5039  return CR_FAILURE;
5040  }
5041 
5042  lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
5043  if (lpDevInst == NULL)
5044  return CR_INVALID_DEVNODE;
5045 
5046  RpcTryExcept
5047  {
5049  lpDevInst,
5050  pLogConfInfo->ulType,
5051  pLogConfInfo->ulTag,
5052  pPriority,
5053  0);
5054  }
5056  {
5058  }
5059  RpcEndExcept;
5060 
5061  return ret;
5062 }
5063 
5064 
5065 /***********************************************************************
5066  * CM_Get_Next_Log_Conf [SETUPAPI.@]
5067  */
5068 CONFIGRET
5069 WINAPI
5071  _Out_opt_ PLOG_CONF plcLogConf,
5072  _In_ LOG_CONF lcLogConf,
5073  _In_ ULONG ulFlags)
5074 {
5075  TRACE("CM_Get_Next_Log_Conf(%p %p %lx)\n",
5076  plcLogConf, lcLogConf, ulFlags);
5077 
5078  return CM_Get_Next_Log_Conf_Ex(plcLogConf, lcLogConf, ulFlags, NULL);
5079 }
5080 
5081 
5082 /***********************************************************************
5083  * CM_Get_Next_Log_Conf_Ex [SETUPAPI.@]
5084  */
5085 CONFIGRET
5086 WINAPI
5088  _Out_opt_ PLOG_CONF plcLogConf,
5089  _In_ LOG_CONF lcLogConf,
5090  _In_ ULONG ulFlags,
5091  _In_opt_ HMACHINE hMachine)
5092 {
5094  HSTRING_TABLE StringTable = NULL;
5095  PLOG_CONF_INFO pLogConfInfo;
5096  PLOG_CONF_INFO pNewLogConfInfo;
5097  ULONG ulNewTag;
5098  LPWSTR lpDevInst;
5099  CONFIGRET ret;
5100 
5101  FIXME("CM_Get_Next_Log_Conf_Ex(%p %p %lx %p)\n",
5102  plcLogConf, lcLogConf, ulFlags, hMachine);
5103 
5104  if (plcLogConf)
5105  *plcLogConf = 0;
5106 
5107  pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
5108  if (!IsValidLogConf(pLogConfInfo))
5109  return CR_INVALID_LOG_CONF;
5110 
5111  if (ulFlags != 0)
5112  return CR_INVALID_FLAG;
5113 
5114  if (hMachine != NULL)
5115  {
5116  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5117  if (BindingHandle == NULL)
5118  return CR_FAILURE;
5119 
5120  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5121  if (StringTable == 0)
5122  return CR_FAILURE;
5123  }
5124  else
5125  {
5126  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5127  return CR_FAILURE;
5128  }
5129 
5130  lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
5131  if (lpDevInst == NULL)
5132  return CR_INVALID_DEVNODE;
5133 
5134  RpcTryExcept
5135  {
5137  lpDevInst,
5138  pLogConfInfo->ulType,
5139  pLogConfInfo->ulTag,
5140  &ulNewTag,
5141  0);
5142  }
5144  {
5146  }
5147  RpcEndExcept;
5148 
5149  if (ret != CR_SUCCESS)
5150  return ret;
5151 
5152  if (plcLogConf)
5153  {
5154  pNewLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
5155  if (pNewLogConfInfo == NULL)
5156  return CR_OUT_OF_MEMORY;
5157 
5158  pNewLogConfInfo->ulMagic = LOG_CONF_MAGIC;
5159  pNewLogConfInfo->dnDevInst = pLogConfInfo->dnDevInst;
5160  pNewLogConfInfo->ulType = pLogConfInfo->ulType;
5161  pNewLogConfInfo->ulTag = ulNewTag;
5162 
5163  *plcLogConf = (LOG_CONF)pNewLogConfInfo;
5164  }
5165 
5166  return CR_SUCCESS;
5167 }
5168 
5169 
5170 /***********************************************************************
5171  * CM_Get_Next_Re_Des [SETUPAPI.@]
5172  */
5173 CONFIGRET
5174 WINAPI
5176  _Out_ PRES_DES prdResDes,
5177  _In_ RES_DES rdResDes,
5178  _In_ RESOURCEID ForResource,
5179  _Out_opt_ PRESOURCEID pResourceID,
5180  _In_ ULONG ulFlags)
5181 {
5182  TRACE("CM_Get_Next_Res_Des(%p %p %lu %p %lx)\n",
5183  prdResDes, rdResDes, ForResource, pResourceID, ulFlags);
5184 
5185  return CM_Get_Next_Res_Des_Ex(prdResDes, rdResDes, ForResource,
5186  pResourceID, ulFlags, NULL);
5187 }
5188 
5189 
5190 /***********************************************************************
5191  * CM_Get_Next_Re_Des_Ex [SETUPAPI.@]
5192  */
5193 CONFIGRET
5194 WINAPI
5196  _Out_ PRES_DES prdResDes,
5197  _In_ RES_DES rdResDes,
5198  _In_ RESOURCEID ForResource,
5199  _Out_opt_ PRESOURCEID pResourceID,
5200  _In_ ULONG ulFlags,
5201  _In_opt_ HMACHINE hMachine)
5202 {
5204  HSTRING_TABLE StringTable = NULL;
5205  ULONG ulInTag, ulOutTag = 0;
5206  ULONG ulInType, ulOutType = 0;
5207  LPWSTR lpDevInst;
5208  DEVINST dnDevInst;
5209  CONFIGRET ret;
5210 
5211  FIXME("CM_Get_Next_Res_Des_Ex(%p %p %lu %p %lx %p)\n",
5212  prdResDes, rdResDes, ForResource, pResourceID, ulFlags, hMachine);
5213 
5214  if (prdResDes == NULL)
5215  return CR_INVALID_POINTER;
5216 
5217  if (IsValidLogConf((PLOG_CONF_INFO)rdResDes))
5218  {
5219  FIXME("LogConf found!\n");
5220  dnDevInst = ((PLOG_CONF_INFO)rdResDes)->dnDevInst;
5221  ulInTag = ((PLOG_CONF_INFO)rdResDes)->ulTag;
5222  ulInType = ((PLOG_CONF_INFO)rdResDes)->ulType;
5223  }
5224 #if 0
5225  else if (IsValidResDes((PRES_DES_INFO)rdResDes))
5226  {
5227  FIXME("ResDes found!\n");
5228  dnDevInst = ((PRES_DES_INFO)rdResDes)->dnDevInst;
5229  ulInTag = ((PRES_DES_INFO)rdResDes)->ulTag;
5230  ulInType = ((PRES_DES_INFO)rdResDes)->ulType;
5231  }
5232 #endif
5233  else
5234  {
5235  return CR_INVALID_RES_DES;
5236  }
5237 
5238  if (hMachine != NULL)
5239  {
5240  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5241  if (BindingHandle == NULL)
5242  return CR_FAILURE;
5243 
5244  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5245  if (StringTable == 0)
5246  return CR_FAILURE;
5247  }
5248  else
5249  {
5250  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5251  return CR_FAILURE;
5252  }
5253 
5254  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
5255  if (lpDevInst == NULL)
5256  return CR_INVALID_DEVNODE;
5257 
5258  RpcTryExcept
5259  {
5261  lpDevInst,
5262  ulInTag,
5263  ulInType,
5264  ForResource,
5265  0, /* unsigned long ulResourceTag, */
5266  &ulOutTag,
5267  &ulOutType,
5268  0);
5269  }
5271  {
5273  }
5274  RpcEndExcept;
5275 
5276  if (ret != CR_SUCCESS)
5277  return ret;
5278 
5279  /* FIXME: Create the ResDes handle */
5280 
5281  return CR_SUCCESS;
5282 }
5283 
5284 
5285 /***********************************************************************
5286  * CM_Get_Parent [SETUPAPI.@]
5287  */
5288 CONFIGRET
5289 WINAPI
5291  _Out_ PDEVINST pdnDevInst,
5292  _In_ DEVINST dnDevInst,
5293  _In_ ULONG ulFlags)
5294 {
5295  TRACE("CM_Get_Parent(%p %p %lx)\n",
5296  pdnDevInst, dnDevInst, ulFlags);
5297 
5298  return CM_Get_Parent_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
5299 }
5300 
5301 
5302 /***********************************************************************
5303  * CM_Get_Parent_Ex [SETUPAPI.@]
5304  */
5305 CONFIGRET
5306 WINAPI
5308  _Out_ PDEVINST pdnDevInst,
5309  _In_ DEVINST dnDevInst,
5310  _In_ ULONG ulFlags,
5311  _In_opt_ HMACHINE hMachine)
5312 {
5313  WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
5315  HSTRING_TABLE StringTable = NULL;
5316  LPWSTR lpDevInst;
5317  DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
5318  CONFIGRET ret;
5319 
5320  TRACE("CM_Get_Parent_Ex(%p %lx %lx %p)\n",
5321  pdnDevInst, dnDevInst, ulFlags, hMachine);
5322 
5323  if (pdnDevInst == NULL)
5324  return CR_INVALID_POINTER;
5325 
5326  if (dnDevInst == 0)
5327  return CR_INVALID_DEVINST;
5328 
5329  if (ulFlags != 0)
5330  return CR_INVALID_FLAG;
5331 
5332  *pdnDevInst = -1;
5333 
5334  if (hMachine != NULL)
5335  {
5336  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5337  if (BindingHandle == NULL)
5338  return CR_FAILURE;
5339 
5340  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5341  if (StringTable == 0)
5342  return CR_FAILURE;
5343  }
5344  else
5345  {
5346  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5347  return CR_FAILURE;
5348  }
5349 
5350  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
5351  if (lpDevInst == NULL)
5352  return CR_INVALID_DEVNODE;
5353 
5354  RpcTryExcept
5355  {
5357