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