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