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