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