ReactOS  0.4.15-dev-2531-g03e8246
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 
638  if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
639  {
640  FIXME("Register a window\n");
641 
642  nLength = GetWindowTextW((HWND)hRecipient,
643  szNameBuffer,
644  ARRAYSIZE(szNameBuffer));
645  if (nLength == 0)
646  {
647  HeapFree(GetProcessHeap(), 0, pNotifyData);
648  return CR_INVALID_DATA;
649  }
650 
651  FIXME("Register window: %S\n", szNameBuffer);
652  }
653  else if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_SERVICE_HANDLE)
654  {
655  FIXME("Register a service\n");
656 
657  dwError = I_ScPnPGetServiceName((SERVICE_STATUS_HANDLE)hRecipient,
658  szNameBuffer,
659  ARRAYSIZE(szNameBuffer));
660  if (dwError != ERROR_SUCCESS)
661  {
662  HeapFree(GetProcessHeap(), 0, pNotifyData);
663  return CR_INVALID_DATA;
664  }
665 
666  FIXME("Register service: %S\n", szNameBuffer);
667  }
668 
670  {
672  0, /* ??? */
673  szNameBuffer,
674  (BYTE*)lpvNotificationFilter,
675  ((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size,
676  ulFlags,
677  &pNotifyData->ulNotifyData,
678  0, /* ??? */
679  &ulUnknown9); /* ??? */
680  }
682  {
684  }
685  RpcEndExcept;
686 
687  if (ret == CR_SUCCESS)
688  {
689  *phDevNotify = (HDEVNOTIFY)pNotifyData;
690  }
691  else
692  {
693  if (pNotifyData != NULL)
694  HeapFree(GetProcessHeap(), 0, pNotifyData);
695 
696  *phDevNotify = (HDEVNOTIFY)NULL;
697  }
698 
699  return ret;
700 }
701 
702 
703 /***********************************************************************
704  * CMP_Report_LogOn [SETUPAPI.@]
705  */
706 CONFIGRET
707 WINAPI
709  _In_ DWORD dwMagic,
710  _In_ DWORD dwProcessId)
711 {
714  BOOL bAdmin;
715  DWORD i;
716 
717  TRACE("CMP_Report_LogOn(%lu %lu)\n", dwMagic, dwProcessId);
718 
719  if (dwMagic != CMP_MAGIC)
720  return CR_INVALID_DATA;
721 
723  return CR_FAILURE;
724 
725  bAdmin = pSetupIsUserAdmin();
726 
727  for (i = 0; i < 30; i++)
728  {
730  {
732  bAdmin,
733  dwProcessId);
734  }
736  {
738  }
739  RpcEndExcept;
740 
741  if (ret == CR_SUCCESS)
742  break;
743 
744  Sleep(5000);
745  }
746 
747  return ret;
748 }
749 
750 
751 /***********************************************************************
752  * CMP_UnregisterNotification [SETUPAPI.@]
753  */
754 CONFIGRET
755 WINAPI
757  _In_ HDEVNOTIFY hDevNotify)
758 {
760  PNOTIFY_DATA pNotifyData;
762 
763  TRACE("CMP_UnregisterNotification(%p)\n", hDevNotify);
764 
765  pNotifyData = (PNOTIFY_DATA)hDevNotify;
766 
767  if ((pNotifyData == NULL) ||
768  (pNotifyData->ulMagic != NOTIFY_MAGIC))
769  return CR_INVALID_POINTER;
770 
772  return CR_FAILURE;
773 
775  {
777  pNotifyData->ulNotifyData);
778  }
780  {
782  }
783  RpcEndExcept;
784 
785  if (ret == CR_SUCCESS)
786  HeapFree(GetProcessHeap(), 0, pNotifyData);
787 
788  return ret;
789 }
790 
791 
792 /***********************************************************************
793  * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
794  */
795 DWORD
796 WINAPI
799 {
800  HANDLE hEvent;
801  DWORD ret;
802 
803  TRACE("CMP_WaitNoPendingInstallEvents(%lu)\n", dwTimeout);
804 
805  hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
806  if (hEvent == NULL)
807  return WAIT_FAILED;
808 
811  return ret;
812 }
813 
814 
815 /***********************************************************************
816  * CMP_WaitServicesAvailable [SETUPAPI.@]
817  */
818 CONFIGRET
819 WINAPI
821  _In_opt_ HMACHINE hMachine)
822 {
825  WORD Version;
826 
827  TRACE("CMP_WaitServicesAvailable(%p)\n", hMachine);
828 
829  if (hMachine != NULL)
830  {
831  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
832  if (BindingHandle == NULL)
833  return CR_FAILURE;
834  }
835  else
836  {
838  return CR_FAILURE;
839  }
840 
842  {
844  }
846  {
848  }
849  RpcEndExcept;
850 
851  return ret;
852 }
853 
854 
855 /***********************************************************************
856  * CM_Add_Empty_Log_Conf [SETUPAPI.@]
857  */
858 CONFIGRET
859 WINAPI
861  _Out_ PLOG_CONF plcLogConf,
862  _In_ DEVINST dnDevInst,
864  _In_ ULONG ulFlags)
865 {
866  TRACE("CM_Add_Empty_Log_Conf(%p %p %lu %lx)\n",
867  plcLogConf, dnDevInst, Priority, ulFlags);
868 
869  return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
870  ulFlags, NULL);
871 }
872 
873 
874 /***********************************************************************
875  * CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
876  */
877 CONFIGRET
878 WINAPI
880  _Out_ PLOG_CONF plcLogConf,
881  _In_ DEVINST dnDevInst,
883  _In_ ULONG ulFlags,
884  _In_opt_ HMACHINE hMachine)
885 {
887  HSTRING_TABLE StringTable = NULL;
888  ULONG ulLogConfTag = 0;
889  LPWSTR lpDevInst;
890  PLOG_CONF_INFO pLogConfInfo;
892 
893  FIXME("CM_Add_Empty_Log_Conf_Ex(%p %p %lu %lx %p)\n",
894  plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
895 
896  if (!pSetupIsUserAdmin())
897  return CR_ACCESS_DENIED;
898 
899  if (plcLogConf == NULL)
900  return CR_INVALID_POINTER;
901 
902  if (dnDevInst == 0)
903  return CR_INVALID_DEVINST;
904 
905  if (Priority > 0xFFFF)
906  return CR_INVALID_PRIORITY;
907 
908  if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
909  return CR_INVALID_FLAG;
910 
911  if (hMachine != NULL)
912  {
913  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
914  if (BindingHandle == NULL)
915  return CR_FAILURE;
916 
917  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
918  if (StringTable == 0)
919  return CR_FAILURE;
920  }
921  else
922  {
923  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
924  return CR_FAILURE;
925  }
926 
927  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
928  if (lpDevInst == NULL)
929  return CR_INVALID_DEVNODE;
930 
932  {
934  &ulLogConfTag, ulFlags);
935  }
937  {
939  }
940  RpcEndExcept;
941 
942  if (ret == CR_SUCCESS)
943  {
944  pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
945  if (pLogConfInfo == NULL)
946  {
948  }
949  else
950  {
951  pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
952  pLogConfInfo->dnDevInst = dnDevInst;
953  pLogConfInfo->ulType = ulFlags;
954  pLogConfInfo->ulTag = ulLogConfTag;
955 
956  *plcLogConf = (LOG_CONF)pLogConfInfo;
957 
958  ret = CR_SUCCESS;
959  }
960  }
961 
962  return ret;
963 }
964 
965 
966 /***********************************************************************
967  * CM_Add_IDA [SETUPAPI.@]
968  */
969 CONFIGRET
970 WINAPI
972  _In_ DEVINST dnDevInst,
973  _In_ PSTR pszID,
974  _In_ ULONG ulFlags)
975 {
976  TRACE("CM_Add_IDA(%p %s %lx)\n",
977  dnDevInst, debugstr_a(pszID), ulFlags);
978 
979  return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
980 }
981 
982 
983 /***********************************************************************
984  * CM_Add_IDW [SETUPAPI.@]
985  */
986 CONFIGRET
987 WINAPI
989  _In_ DEVINST dnDevInst,
990  _In_ PWSTR pszID,
991  _In_ ULONG ulFlags)
992 {
993  TRACE("CM_Add_IDW(%p %s %lx)\n",
994  dnDevInst, debugstr_w(pszID), ulFlags);
995 
996  return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
997 }
998 
999 
1000 /***********************************************************************
1001  * CM_Add_ID_ExA [SETUPAPI.@]
1002  */
1003 CONFIGRET
1004 WINAPI
1006  _In_ DEVINST dnDevInst,
1007  _In_ PSTR pszID,
1008  _In_ ULONG ulFlags,
1009  _In_opt_ HMACHINE hMachine)
1010 {
1011  PWSTR pszIDW;
1012  CONFIGRET ret;
1013 
1014  TRACE("CM_Add_ID_ExA(%p %s %lx %p)\n",
1015  dnDevInst, debugstr_a(pszID), ulFlags, hMachine);
1016 
1017  if (pSetupCaptureAndConvertAnsiArg(pszID, &pszIDW))
1018  return CR_INVALID_DATA;
1019 
1020  ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);
1021 
1022  MyFree(pszIDW);
1023 
1024  return ret;
1025 }
1026 
1027 
1028 /***********************************************************************
1029  * CM_Add_ID_ExW [SETUPAPI.@]
1030  */
1031 CONFIGRET
1032 WINAPI
1034  _In_ DEVINST dnDevInst,
1035  _In_ PWSTR pszID,
1036  _In_ ULONG ulFlags,
1037  _In_opt_ HMACHINE hMachine)
1038 {
1040  HSTRING_TABLE StringTable = NULL;
1041  LPWSTR lpDevInst;
1042  CONFIGRET ret;
1043 
1044  TRACE("CM_Add_ID_ExW(%p %s %lx %p)\n",
1045  dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
1046 
1047  if (!pSetupIsUserAdmin())
1048  return CR_ACCESS_DENIED;
1049 
1050  if (dnDevInst == 0)
1051  return CR_INVALID_DEVINST;
1052 
1053  if (pszID == NULL)
1054  return CR_INVALID_POINTER;
1055 
1056  if (ulFlags & ~CM_ADD_ID_BITS)
1057  return CR_INVALID_FLAG;
1058 
1059  if (hMachine != NULL)
1060  {
1061  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1062  if (BindingHandle == NULL)
1063  return CR_FAILURE;
1064 
1065  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1066  if (StringTable == 0)
1067  return CR_FAILURE;
1068  }
1069  else
1070  {
1071  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1072  return CR_FAILURE;
1073  }
1074 
1075  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1076  if (lpDevInst == NULL)
1077  return CR_INVALID_DEVNODE;
1078 
1079  RpcTryExcept
1080  {
1082  lpDevInst,
1083  pszID,
1084  ulFlags);
1085  }
1087  {
1089  }
1090  RpcEndExcept;
1091 
1092  return ret;
1093 }
1094 
1095 
1096 /***********************************************************************
1097  * CM_Add_Range [SETUPAPI.@]
1098  */
1099 CONFIGRET
1100 WINAPI
1102  _In_ DWORDLONG ullStartValue,
1103  _In_ DWORDLONG ullEndValue,
1104  _In_ RANGE_LIST rlh,
1105  _In_ ULONG ulFlags)
1106 {
1107  PINTERNAL_RANGE_LIST pRangeList;
1108  PINTERNAL_RANGE pRange;
1110 
1111  FIXME("CM_Add_Range(%I64u %I64u %p %lx)\n",
1112  ullStartValue, ullEndValue, rlh, ulFlags);
1113 
1114  pRangeList = (PINTERNAL_RANGE_LIST)rlh;
1115 
1116  if (!IsValidRangeList(pRangeList))
1117  return CR_INVALID_RANGE_LIST;
1118 
1119  if (ulFlags & ~CM_ADD_RANGE_BITS)
1120  return CR_INVALID_FLAG;
1121 
1122  if (ullEndValue < ullStartValue)
1123  return CR_INVALID_RANGE;
1124 
1125  /* Lock the range list */
1126  WaitForSingleObject(pRangeList->hMutex, INFINITE);
1127 
1128  /* Allocate the new range */
1129  pRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
1130  if (pRange == NULL)
1131  {
1133  goto done;
1134  }
1135 
1136  pRange->pRangeList = pRangeList;
1137  pRange->ullStart = ullStartValue;
1138  pRange->ullEnd = ullEndValue;
1139 
1140  /* Insert the range */
1141  if (IsListEmpty(&pRangeList->ListHead))
1142  {
1143  InsertTailList(&pRangeList->ListHead, &pRange->ListEntry);
1144  }
1145  else
1146  {
1147  HeapFree(GetProcessHeap(), 0, pRange);
1148  UNIMPLEMENTED;
1149  }
1150 
1151 done:
1152  /* Unlock the range list */
1153  ReleaseMutex(pRangeList->hMutex);
1154 
1155  return ret;
1156 }
1157 
1158 
1159 /***********************************************************************
1160  * CM_Add_Res_Des [SETUPAPI.@]
1161  */
1162 CONFIGRET
1163 WINAPI
1165  _Out_opt_ PRES_DES prdResDes,
1166  _In_ LOG_CONF lcLogConf,
1167  _In_ RESOURCEID ResourceID,
1168  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1169  _In_ ULONG ResourceLen,
1170  _In_ ULONG ulFlags)
1171 {
1172  TRACE("CM_Add_Res_Des(%p %p %lu %p %lu %lx)\n",
1173  prdResDes, lcLogConf, ResourceID, ResourceData, ResourceLen, ulFlags);
1174 
1175  return CM_Add_Res_Des_Ex(prdResDes, lcLogConf, ResourceID, ResourceData,
1176  ResourceLen, ulFlags, NULL);
1177 }
1178 
1179 
1180 /***********************************************************************
1181  * CM_Add_Res_Des_Ex [SETUPAPI.@]
1182  */
1183 CONFIGRET
1184 WINAPI
1186  _Out_opt_ PRES_DES prdResDes,
1187  _In_ LOG_CONF lcLogConf,
1188  _In_ RESOURCEID ResourceID,
1189  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1190  _In_ ULONG ResourceLen,
1191  _In_ ULONG ulFlags,
1192  _In_opt_ HMACHINE hMachine)
1193 {
1194  FIXME("CM_Add_Res_Des_Ex(%p %p %lu %p %lu %lx %p)\n",
1195  prdResDes, lcLogConf, ResourceID,
1196  ResourceData, ResourceLen, ulFlags, hMachine);
1197 
1198  return CR_CALL_NOT_IMPLEMENTED;
1199 }
1200 
1201 
1202 /***********************************************************************
1203  * CM_Connect_MachineA [SETUPAPI.@]
1204  */
1205 CONFIGRET
1206 WINAPI
1208  _In_opt_ PCSTR UNCServerName,
1209  _Out_ PHMACHINE phMachine)
1210 {
1211  PWSTR pServerNameW;
1212  CONFIGRET ret;
1213 
1214  TRACE("CM_Connect_MachineA(%s %p)\n",
1215  debugstr_a(UNCServerName), phMachine);
1216 
1217  if (UNCServerName == NULL || *UNCServerName == 0)
1218  return CM_Connect_MachineW(NULL, phMachine);
1219 
1220  if (pSetupCaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
1221  return CR_INVALID_DATA;
1222 
1223  ret = CM_Connect_MachineW(pServerNameW, phMachine);
1224 
1225  MyFree(pServerNameW);
1226 
1227  return ret;
1228 }
1229 
1230 
1231 /***********************************************************************
1232  * CM_Connect_MachineW [SETUPAPI.@]
1233  */
1234 CONFIGRET
1235 WINAPI
1237  _In_opt_ PCWSTR UNCServerName,
1238  _Out_ PHMACHINE phMachine)
1239 {
1240  PMACHINE_INFO pMachine;
1241 
1242  TRACE("CM_Connect_MachineW(%s %p)\n",
1243  debugstr_w(UNCServerName), phMachine);
1244 
1245  if (phMachine == NULL)
1246  return CR_INVALID_POINTER;
1247 
1248  *phMachine = NULL;
1249 
1250  pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
1251  if (pMachine == NULL)
1252  return CR_OUT_OF_MEMORY;
1253 
1254  if (UNCServerName == NULL || *UNCServerName == 0)
1255  {
1256  pMachine->bLocal = TRUE;
1257 
1258  /* FIXME: store the computers name in pMachine->szMachineName */
1259 
1260  if (!PnpGetLocalHandles(&pMachine->BindingHandle,
1261  &pMachine->StringTable))
1262  {
1263  HeapFree(GetProcessHeap(), 0, pMachine);
1264  return CR_FAILURE;
1265  }
1266  }
1267  else
1268  {
1269  pMachine->bLocal = FALSE;
1270  if (wcslen(UNCServerName) >= SP_MAX_MACHINENAME_LENGTH - 1)
1271  {
1272  HeapFree(GetProcessHeap(), 0, pMachine);
1273  return CR_INVALID_MACHINENAME;
1274  }
1275  lstrcpyW(pMachine->szMachineName, UNCServerName);
1276 
1278  if (pMachine->StringTable == NULL)
1279  {
1280  HeapFree(GetProcessHeap(), 0, pMachine);
1281  return CR_FAILURE;
1282  }
1283 
1284  pSetupStringTableAddString(pMachine->StringTable, L"PLT", 1);
1285 
1286  if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
1287  {
1289  HeapFree(GetProcessHeap(), 0, pMachine);
1290  return CR_INVALID_MACHINENAME;
1291  }
1292  }
1293 
1294  *phMachine = (PHMACHINE)pMachine;
1295 
1296  return CR_SUCCESS;
1297 }
1298 
1299 
1300 /***********************************************************************
1301  * CM_Create_DevNodeA [SETUPAPI.@]
1302  */
1303 CONFIGRET
1304 WINAPI
1306  _Out_ PDEVINST pdnDevInst,
1307  _In_ DEVINSTID_A pDeviceID,
1308  _In_ DEVINST dnParent,
1309  _In_ ULONG ulFlags)
1310 {
1311  TRACE("CM_Create_DevNodeA(%p %s %p %lx)\n",
1312  pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
1313 
1314  return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
1315  ulFlags, NULL);
1316 }
1317 
1318 
1319 /***********************************************************************
1320  * CM_Create_DevNodeW [SETUPAPI.@]
1321  */
1322 CONFIGRET
1323 WINAPI
1325  _Out_ PDEVINST pdnDevInst,
1326  _In_ DEVINSTID_W pDeviceID,
1327  _In_ DEVINST dnParent,
1328  _In_ ULONG ulFlags)
1329 {
1330  TRACE("CM_Create_DevNodeW(%p %s %p %lx)\n",
1331  pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
1332 
1333  return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
1334  ulFlags, NULL);
1335 }
1336 
1337 
1338 /***********************************************************************
1339  * CM_Create_DevNode_ExA [SETUPAPI.@]
1340  */
1341 CONFIGRET
1342 WINAPI
1344  _Out_ PDEVINST pdnDevInst,
1345  _In_ DEVINSTID_A pDeviceID,
1346  _In_ DEVINST dnParent,
1347  _In_ ULONG ulFlags,
1348  _In_opt_ HANDLE hMachine)
1349 {
1350  DEVINSTID_W pDeviceIDW;
1351  CONFIGRET ret;
1352 
1353  TRACE("CM_Create_DevNode_ExA(%p %s %p %lx %p)\n",
1354  pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
1355 
1356  if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
1357  return CR_INVALID_DATA;
1358 
1359  ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
1360  hMachine);
1361 
1362  MyFree(pDeviceIDW);
1363 
1364  return ret;
1365 }
1366 
1367 
1368 /***********************************************************************
1369  * CM_Create_DevNode_ExW [SETUPAPI.@]
1370  */
1371 CONFIGRET
1372 WINAPI
1374  _Out_ PDEVINST pdnDevInst,
1375  _In_ DEVINSTID_W pDeviceID,
1376  _In_ DEVINST dnParent,
1377  _In_ ULONG ulFlags,
1378  _In_opt_ HANDLE hMachine)
1379 {
1381  HSTRING_TABLE StringTable = NULL;
1382  LPWSTR lpParentDevInst;
1384  WCHAR szLocalDeviceID[MAX_DEVICE_ID_LEN];
1385 
1386  TRACE("CM_Create_DevNode_ExW(%p %s %p %lx %p)\n",
1387  pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
1388 
1389  if (!pSetupIsUserAdmin())
1390  return CR_ACCESS_DENIED;
1391 
1392  if (pdnDevInst == NULL)
1393  return CR_INVALID_POINTER;
1394 
1395  if (pDeviceID == NULL || wcslen(pDeviceID) == 0 || wcslen(pDeviceID) >= MAX_DEVICE_ID_LEN)
1396  return CR_INVALID_DEVICE_ID;
1397 
1398  if (dnParent == 0)
1399  return CR_INVALID_DEVNODE;
1400 
1401  if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
1402  return CR_INVALID_FLAG;
1403 
1404  if (hMachine != NULL)
1405  {
1406  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1407  if (BindingHandle == NULL)
1408  return CR_FAILURE;
1409 
1410  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1411  if (StringTable == 0)
1412  return CR_FAILURE;
1413  }
1414  else
1415  {
1416  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1417  return CR_FAILURE;
1418  }
1419 
1420  lpParentDevInst = pSetupStringTableStringFromId(StringTable, dnParent);
1421  if (lpParentDevInst == NULL)
1422  return CR_INVALID_DEVNODE;
1423 
1424  wcscpy(szLocalDeviceID, pDeviceID);
1425 
1426  RpcTryExcept
1427  {
1429  szLocalDeviceID,
1430  lpParentDevInst,
1432  ulFlags);
1433  }
1435  {
1437  }
1438  RpcEndExcept;
1439 
1440  if (ret == CR_SUCCESS)
1441  {
1442  /* If CM_CREATE_DEVINST_GENERATE_ID was passed in, PNP_CreateDevInst
1443  * will return the generated device ID in szLocalDeviceID */
1444  *pdnDevInst = pSetupStringTableAddString(StringTable, szLocalDeviceID, 1);
1445  if (*pdnDevInst == 0)
1447  }
1448 
1449  return ret;
1450 }
1451 
1452 
1453 /***********************************************************************
1454  * CM_Create_Range_List [SETUPAPI.@]
1455  */
1456 CONFIGRET
1457 WINAPI
1459  _Out_ PRANGE_LIST prlh,
1460  _In_ ULONG ulFlags)
1461 {
1462  PINTERNAL_RANGE_LIST pRangeList = NULL;
1463 
1464  FIXME("CM_Create_Range_List(%p %lx)\n",
1465  prlh, ulFlags);
1466 
1467  if (ulFlags != 0)
1468  return CR_INVALID_FLAG;
1469 
1470  if (prlh == NULL)
1471  return CR_INVALID_POINTER;
1472 
1473  /* Allocate the range list */
1475  if (pRangeList == NULL)
1476  return CR_OUT_OF_MEMORY;
1477 
1478  /* Set the magic value */
1479  pRangeList->ulMagic = RANGE_LIST_MAGIC;
1480 
1481  /* Initialize the mutex for synchonized access */
1482  pRangeList->hMutex = CreateMutex(NULL, FALSE, NULL);
1483  if (pRangeList->hMutex == NULL)
1484  {
1485  HeapFree(GetProcessHeap(), 0, pRangeList);
1486  return CR_FAILURE;
1487  }
1488 
1489  InitializeListHead(&pRangeList->ListHead);
1490 
1491  *prlh = (RANGE_LIST)pRangeList;
1492 
1493  return CR_SUCCESS;
1494 }
1495 
1496 
1497 /***********************************************************************
1498  * CM_Delete_Class_Key [SETUPAPI.@]
1499  */
1500 CONFIGRET
1501 WINAPI
1503  _In_ LPGUID ClassGuid,
1504  _In_ ULONG ulFlags)
1505 {
1506  TRACE("CM_Delete_Class_Key(%p %lx)\n",
1507  ClassGuid, ulFlags);
1508 
1509  return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
1510 }
1511 
1512 
1513 /***********************************************************************
1514  * CM_Delete_Class_Key_Ex [SETUPAPI.@]
1515  */
1516 CONFIGRET
1517 WINAPI
1519  _In_ LPGUID ClassGuid,
1520  _In_ ULONG ulFlags,
1521  _In_opt_ HANDLE hMachine)
1522 {
1523  WCHAR szGuidString[MAX_GUID_STRING_LEN];
1525  CONFIGRET ret;
1526 
1527  TRACE("CM_Delete_Class_Key_Ex(%p %lx %p)\n",
1528  ClassGuid, ulFlags, hMachine);
1529 
1530  if (ClassGuid == NULL)
1531  return CR_INVALID_POINTER;
1532 
1533  if (ulFlags & ~CM_DELETE_CLASS_BITS)
1534  return CR_INVALID_FLAG;
1535 
1536  if (!GuidToString(ClassGuid, szGuidString))
1537  return CR_INVALID_DATA;
1538 
1539  if (hMachine != NULL)
1540  {
1541  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1542  if (BindingHandle == NULL)
1543  return CR_FAILURE;
1544  }
1545  else
1546  {
1548  return CR_FAILURE;
1549  }
1550 
1551  RpcTryExcept
1552  {
1554  szGuidString,
1555  ulFlags);
1556  }
1558  {
1560  }
1561  RpcEndExcept;
1562 
1563  return ret;
1564 }
1565 
1566 
1567 /***********************************************************************
1568  * CM_Delete_DevNode_Key [SETUPAPI.@]
1569  */
1570 CONFIGRET
1571 WINAPI
1573  _In_ DEVINST dnDevInst,
1574  _In_ ULONG ulHardwareProfile,
1575  _In_ ULONG ulFlags)
1576 {
1577  TRACE("CM_Delete_DevNode_Key(%p %lu %lx)\n",
1578  dnDevInst, ulHardwareProfile, ulFlags);
1579 
1580  return CM_Delete_DevNode_Key_Ex(dnDevInst, ulHardwareProfile, ulFlags,
1581  NULL);
1582 }
1583 
1584 
1585 /***********************************************************************
1586  * CM_Delete_DevNode_Key_Ex [SETUPAPI.@]
1587  */
1588 CONFIGRET
1589 WINAPI
1591  _In_ DEVINST dnDevInst,
1592  _In_ ULONG ulHardwareProfile,
1593  _In_ ULONG ulFlags,
1594  _In_opt_ HANDLE hMachine)
1595 {
1597  HSTRING_TABLE StringTable = NULL;
1598  PWSTR pszDevInst, pszKeyPath = NULL, pszInstancePath = NULL;
1599  CONFIGRET ret;
1600 
1601  FIXME("CM_Delete_DevNode_Key_Ex(%p %lu %lx %p)\n",
1602  dnDevInst, ulHardwareProfile, ulFlags, hMachine);
1603 
1604  if (dnDevInst == 0)
1605  return CR_INVALID_DEVINST;
1606 
1607  if (ulFlags & ~CM_REGISTRY_BITS)
1608  return CR_INVALID_FLAG;
1609 
1610  if ((ulFlags & CM_REGISTRY_USER) && (ulFlags & CM_REGISTRY_CONFIG))
1611  return CR_INVALID_FLAG;
1612 
1613  if (hMachine != NULL)
1614  {
1615  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1616  if (BindingHandle == NULL)
1617  return CR_FAILURE;
1618 
1619  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1620  if (StringTable == 0)
1621  return CR_FAILURE;
1622  }
1623  else
1624  {
1625  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1626  return CR_FAILURE;
1627  }
1628 
1629  pszDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1630  if (pszDevInst == NULL)
1631  return CR_INVALID_DEVNODE;
1632 
1633  TRACE("pszDevInst: %S\n", pszDevInst);
1634 
1635  pszKeyPath = MyMalloc(512 * sizeof(WCHAR));
1636  if (pszKeyPath == NULL)
1637  {
1639  goto done;
1640  }
1641 
1642  pszInstancePath = MyMalloc(512 * sizeof(WCHAR));
1643  if (pszInstancePath == NULL)
1644  {
1646  goto done;
1647  }
1648 
1650  pszDevInst,
1651  pszKeyPath,
1652  pszInstancePath,
1653  ulHardwareProfile,
1654  ulFlags);
1655  if (ret != CR_SUCCESS)
1656  goto done;
1657 
1658  TRACE("pszKeyPath: %S\n", pszKeyPath);
1659  TRACE("pszInstancePath: %S\n", pszInstancePath);
1660 
1661  if (ulFlags & CM_REGISTRY_USER)
1662  {
1663  FIXME("The CM_REGISTRY_USER flag is not supported yet!\n");
1664  }
1665  else
1666  {
1667 #if 0
1668  if (!pSetupIsUserAdmin())
1669  {
1671  goto done;
1672  }
1673 #endif
1674 
1675  if (!(ulFlags & CM_REGISTRY_CONFIG))
1676  ulHardwareProfile = 0;
1677 
1678  RpcTryExcept
1679  {
1681  pszDevInst,
1682  pszKeyPath,
1683  pszInstancePath,
1684  ulHardwareProfile);
1685  }
1687  {
1689  }
1690  RpcEndExcept;
1691  }
1692 
1693 done:
1694  if (pszInstancePath != NULL)
1695  MyFree(pszInstancePath);
1696 
1697  if (pszKeyPath != NULL)
1698  MyFree(pszKeyPath);
1699 
1700  return ret;
1701 }
1702 
1703 
1704 /***********************************************************************
1705  * CM_Delete_Range [SETUPAPI.@]
1706  */
1707 CONFIGRET
1708 WINAPI
1710  _In_ DWORDLONG ullStartValue,
1711  _In_ DWORDLONG ullEndValue,
1712  _In_ RANGE_LIST rlh,
1713  _In_ ULONG ulFlags)
1714 {
1715  FIXME("CM_Delete_Range(%I64u %I64u %p %lx)\n",
1716  ullStartValue, ullEndValue, rlh, ulFlags);
1717 
1718  return CR_CALL_NOT_IMPLEMENTED;
1719 }
1720 
1721 
1722 /***********************************************************************
1723  * CM_Detect_Resource_Conflict [SETUPAPI.@]
1724  */
1725 CONFIGRET
1726 WINAPI
1728  _In_ DEVINST dnDevInst,
1729  _In_ RESOURCEID ResourceID,
1730  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1731  _In_ ULONG ResourceLen,
1732  _Out_ PBOOL pbConflictDetected,
1733  _In_ ULONG ulFlags)
1734 {
1735  TRACE("CM_Detect_Resource_Conflict(%p %lu %p %lu %p 0x%lx)\n",
1736  dnDevInst, ResourceID, ResourceData, ResourceLen,
1737  pbConflictDetected, ulFlags);
1738 
1739  return CM_Detect_Resource_Conflict_Ex(dnDevInst,
1740  ResourceID,
1741  ResourceData,
1742  ResourceLen,
1743  pbConflictDetected,
1744  ulFlags,
1745  NULL);
1746 }
1747 
1748 
1749 /***********************************************************************
1750  * CM_Detect_Resource_Conflict_Ex [SETUPAPI.@]
1751  */
1752 CONFIGRET
1753 WINAPI
1755  _In_ DEVINST dnDevInst,
1756  _In_ RESOURCEID ResourceID,
1757  _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1758  _In_ ULONG ResourceLen,
1759  _Out_ PBOOL pbConflictDetected,
1760  _In_ ULONG ulFlags,
1761  _In_opt_ HMACHINE hMachine)
1762 {
1763  FIXME("CM_Detect_Resource_Conflict_Ex(%p %lu %p %lu %p 0x%lx %p)\n",
1764  dnDevInst, ResourceID, ResourceData, ResourceLen,
1765  pbConflictDetected, ulFlags, hMachine);
1766 
1767  return CR_CALL_NOT_IMPLEMENTED;
1768 }
1769 
1770 
1771 /***********************************************************************
1772  * CM_Disable_DevNode [SETUPAPI.@]
1773  */
1774 CONFIGRET
1775 WINAPI
1777  _In_ DEVINST dnDevInst,
1778  _In_ ULONG ulFlags)
1779 {
1780  TRACE("CM_Disable_DevNode(%p %lx)\n",
1781  dnDevInst, ulFlags);
1782 
1783  return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1784 }
1785 
1786 
1787 /***********************************************************************
1788  * CM_Disable_DevNode_Ex [SETUPAPI.@]
1789  */
1790 CONFIGRET
1791 WINAPI
1793  _In_ DEVINST dnDevInst,
1794  _In_ ULONG ulFlags,
1795  _In_opt_ HMACHINE hMachine)
1796 {
1798  HSTRING_TABLE StringTable = NULL;
1799  LPWSTR lpDevInst;
1800  CONFIGRET ret;
1801 
1802  TRACE("CM_Disable_DevNode_Ex(%p %lx %p)\n",
1803  dnDevInst, ulFlags, hMachine);
1804 
1805  if (!pSetupIsUserAdmin())
1806  return CR_ACCESS_DENIED;
1807 
1808  if (dnDevInst == 0)
1809  return CR_INVALID_DEVINST;
1810 
1811  if (ulFlags != 0)
1812  return CR_INVALID_FLAG;
1813 
1814  if (hMachine != NULL)
1815  {
1816  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1817  if (BindingHandle == NULL)
1818  return CR_FAILURE;
1819 
1820  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1821  if (StringTable == 0)
1822  return CR_FAILURE;
1823  }
1824  else
1825  {
1826  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1827  return CR_FAILURE;
1828  }
1829 
1830  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1831  if (lpDevInst == NULL)
1832  return CR_INVALID_DEVNODE;
1833 
1834  RpcTryExcept
1835  {
1837  lpDevInst,
1838  NULL,
1839  NULL,
1840  0,
1841  ulFlags);
1842  }
1844  {
1846  }
1847  RpcEndExcept;
1848 
1849  return ret;
1850 }
1851 
1852 
1853 /***********************************************************************
1854  * CM_Disconnect_Machine [SETUPAPI.@]
1855  */
1856 CONFIGRET
1857 WINAPI
1859  _In_opt_ HMACHINE hMachine)
1860 {
1861  PMACHINE_INFO pMachine;
1862 
1863  TRACE("CM_Disconnect_Machine(%p)\n", hMachine);
1864 
1865  pMachine = (PMACHINE_INFO)hMachine;
1866  if (pMachine == NULL)
1867  return CR_SUCCESS;
1868 
1869  if (pMachine->bLocal == FALSE)
1870  {
1871  if (pMachine->StringTable != NULL)
1873 
1874  if (!PnpUnbindRpc(pMachine->BindingHandle))
1875  return CR_ACCESS_DENIED;
1876  }
1877 
1878  HeapFree(GetProcessHeap(), 0, pMachine);
1879 
1880  return CR_SUCCESS;
1881 }
1882 
1883 
1884 /***********************************************************************
1885  * CM_Dup_Range_List [SETUPAPI.@]
1886  */
1887 CONFIGRET
1888 WINAPI
1890  _In_ RANGE_LIST rlhOld,
1891  _In_ RANGE_LIST rlhNew,
1892  _In_ ULONG ulFlags)
1893 {
1894  FIXME("CM_Dup_Range_List(%p %p %lx)\n",
1895  rlhOld, rlhNew, ulFlags);
1896 
1897  return CR_CALL_NOT_IMPLEMENTED;
1898 }
1899 
1900 
1901 /***********************************************************************
1902  * CM_Enable_DevNode [SETUPAPI.@]
1903  */
1904 CONFIGRET
1905 WINAPI
1907  _In_ DEVINST dnDevInst,
1908  _In_ ULONG ulFlags)
1909 {
1910  TRACE("CM_Enable_DevNode(%p %lx)\n",
1911  dnDevInst, ulFlags);
1912 
1913  return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1914 }
1915 
1916 
1917 /***********************************************************************
1918  * CM_Enable_DevNode_Ex [SETUPAPI.@]
1919  */
1920 CONFIGRET
1921 WINAPI
1923  _In_ DEVINST dnDevInst,
1924  _In_ ULONG ulFlags,
1925  _In_opt_ HMACHINE hMachine)
1926 {
1928  HSTRING_TABLE StringTable = NULL;
1929  LPWSTR lpDevInst;
1930  CONFIGRET ret;
1931 
1932  TRACE("CM_Enable_DevNode_Ex(%p %lx %p)\n",
1933  dnDevInst, ulFlags, hMachine);
1934 
1935  if (!pSetupIsUserAdmin())
1936  return CR_ACCESS_DENIED;
1937 
1938  if (dnDevInst == 0)
1939  return CR_INVALID_DEVINST;
1940 
1941  if (ulFlags != 0)
1942  return CR_INVALID_FLAG;
1943 
1944  if (hMachine != NULL)
1945  {
1946  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1947  if (BindingHandle == NULL)
1948  return CR_FAILURE;
1949 
1950  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1951  if (StringTable == 0)
1952  return CR_FAILURE;
1953  }
1954  else
1955  {
1956  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1957  return CR_FAILURE;
1958  }
1959 
1960  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1961  if (lpDevInst == NULL)
1962  return CR_INVALID_DEVNODE;
1963 
1964  RpcTryExcept
1965  {
1967  PNP_DEVINST_ENABLE,
1968  ulFlags,
1969  lpDevInst,
1970  NULL);
1971  }
1973  {
1975  }
1976  RpcEndExcept;
1977 
1978  return ret;
1979 }
1980 
1981 
1982 /***********************************************************************
1983  * CM_Enumerate_Classes [SETUPAPI.@]
1984  */
1985 CONFIGRET
1986 WINAPI
1988  _In_ ULONG ulClassIndex,
1989  _Out_ LPGUID ClassGuid,
1990  _In_ ULONG ulFlags)
1991 {
1992  TRACE("CM_Enumerate_Classes(%lx %p %lx)\n",
1993  ulClassIndex, ClassGuid, ulFlags);
1994 
1995  return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
1996 }
1997 
1998 
1999 /***********************************************************************
2000  * CM_Enumerate_Classes_Ex [SETUPAPI.@]
2001  */
2002 CONFIGRET
2003 WINAPI
2005  _In_ ULONG ulClassIndex,
2006  _Out_ LPGUID ClassGuid,
2007  _In_ ULONG ulFlags,
2008  _In_opt_ HMACHINE hMachine)
2009 {
2010  WCHAR szBuffer[MAX_GUID_STRING_LEN];
2013  ULONG ulLength = MAX_GUID_STRING_LEN;
2014 
2015  TRACE("CM_Enumerate_Classes_Ex(%lx %p %lx %p)\n",
2016  ulClassIndex, ClassGuid, ulFlags, hMachine);
2017 
2018  if (ClassGuid == NULL)
2019  return CR_INVALID_POINTER;
2020 
2021  if (ulFlags != 0)
2022  return CR_INVALID_FLAG;
2023 
2024  if (hMachine != NULL)
2025  {
2026  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2027  if (BindingHandle == NULL)
2028  return CR_FAILURE;
2029  }
2030  else
2031  {
2033  return CR_FAILURE;
2034  }
2035 
2036  RpcTryExcept
2037  {
2039  PNP_CLASS_SUBKEYS,
2040  ulClassIndex,
2041  szBuffer,
2043  &ulLength,
2044  ulFlags);
2045  }
2047  {
2049  }
2050  RpcEndExcept;
2051 
2052  if (ret == CR_SUCCESS)
2053  {
2054  /* Remove the {} */
2055  szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
2056 
2057  /* Convert the buffer to a GUID */
2058  if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
2059  return CR_FAILURE;
2060  }
2061 
2062  return ret;
2063 }
2064 
2065 
2066 /***********************************************************************
2067  * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
2068  */
2069 CONFIGRET
2070 WINAPI
2072  _In_ ULONG ulEnumIndex,
2073  _Out_writes_(*pulLength) PCHAR Buffer,
2074  _Inout_ PULONG pulLength,
2075  _In_ ULONG ulFlags)
2076 {
2077  TRACE("CM_Enumerate_EnumeratorsA(%lu %p %p %lx)\n",
2078  ulEnumIndex, Buffer, pulLength, ulFlags);
2079 
2080  return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
2081  ulFlags, NULL);
2082 }
2083 
2084 
2085 /***********************************************************************
2086  * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
2087  */
2088 CONFIGRET
2089 WINAPI
2091  _In_ ULONG ulEnumIndex,
2092  _Out_writes_(*pulLength) PWCHAR Buffer,
2093  _Inout_ PULONG pulLength,
2094  _In_ ULONG ulFlags)
2095 {
2096  TRACE("CM_Enumerate_EnumeratorsW(%lu %p %p %lx)\n",
2097  ulEnumIndex, Buffer, pulLength, ulFlags);
2098 
2099  return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
2100  ulFlags, NULL);
2101 }
2102 
2103 
2104 /***********************************************************************
2105  * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
2106  */
2107 CONFIGRET
2108 WINAPI
2110  _In_ ULONG ulEnumIndex,
2111  _Out_writes_(*pulLength) PCHAR Buffer,
2112  _Inout_ PULONG pulLength,
2113  _In_ ULONG ulFlags,
2114  _In_opt_ HMACHINE hMachine)
2115 {
2116  WCHAR szBuffer[MAX_DEVICE_ID_LEN];
2117  ULONG ulOrigLength;
2118  ULONG ulLength;
2120 
2121  TRACE("CM_Enumerate_Enumerators_ExA(%lu %p %p %lx %p)\n",
2122  ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2123 
2124  if (Buffer == NULL || pulLength == NULL)
2125  return CR_INVALID_POINTER;
2126 
2127  if (ulFlags != 0)
2128  return CR_INVALID_FLAG;
2129 
2130  ulOrigLength = *pulLength;
2131  *pulLength = 0;
2132 
2133  ulLength = MAX_DEVICE_ID_LEN;
2134  ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
2135  ulFlags, hMachine);
2136  if (ret == CR_SUCCESS)
2137  {
2139  0,
2140  szBuffer,
2141  ulLength,
2142  Buffer,
2143  ulOrigLength,
2144  NULL,
2145  NULL) == 0)
2146  ret = CR_FAILURE;
2147  else
2148  *pulLength = lstrlenA(Buffer) + 1;
2149  }
2150 
2151  return ret;
2152 }
2153 
2154 
2155 /***********************************************************************
2156  * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
2157  */
2158 CONFIGRET
2159 WINAPI
2161  _In_ ULONG ulEnumIndex,
2162  _Out_writes_(*pulLength) PWCHAR Buffer,
2163  _Inout_ PULONG pulLength,
2164  _In_ ULONG ulFlags,
2165  _In_opt_ HMACHINE hMachine)
2166 {
2168  CONFIGRET ret;
2169 
2170  TRACE("CM_Enumerate_Enumerators_ExW(%lu %p %p %lx %p)\n",
2171  ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2172 
2173  if (Buffer == NULL || pulLength == NULL)
2174  return CR_INVALID_POINTER;
2175 
2176  if (ulFlags != 0)
2177  return CR_INVALID_FLAG;
2178 
2179  *Buffer = UNICODE_NULL;
2180 
2181  if (hMachine != NULL)
2182  {
2183  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2184  if (BindingHandle == NULL)
2185  return CR_FAILURE;
2186  }
2187  else
2188  {
2190  return CR_FAILURE;
2191  }
2192 
2193  RpcTryExcept
2194  {
2196  PNP_ENUMERATOR_SUBKEYS,
2197  ulEnumIndex,
2198  Buffer,
2199  *pulLength,
2200  pulLength,
2201  ulFlags);
2202  }
2204  {
2206  }
2207  RpcEndExcept;
2208 
2209  return ret;
2210 }
2211 
2212 
2213 /***********************************************************************
2214  * CM_Find_Range [SETUPAPI.@]
2215  */
2216 CONFIGRET
2217 WINAPI
2219  _Out_ PDWORDLONG pullStart,
2220  _In_ DWORDLONG ullStart,
2221  _In_ ULONG ulLength,
2222  _In_ DWORDLONG ullAlignment,
2223  _In_ DWORDLONG ullEnd,
2224  _In_ RANGE_LIST rlh,
2225  _In_ ULONG ulFlags)
2226 {
2227  FIXME("CM_Find_Range(%p %I64u %lu %I64u %I64u %p %lx)\n",
2228  pullStart, ullStart, ulLength, ullAlignment, ullEnd, rlh, ulFlags);
2229 
2230  return CR_CALL_NOT_IMPLEMENTED;
2231 }
2232 
2233 
2234 /***********************************************************************
2235  * CM_First_Range [SETUPAPI.@]
2236  */
2237 CONFIGRET
2238 WINAPI
2240  _In_ RANGE_LIST rlh,
2241  _Out_ PDWORDLONG pullStart,
2242  _Out_ PDWORDLONG pullEnd,
2243  _Out_ PRANGE_ELEMENT preElement,
2244  _In_ ULONG ulFlags)
2245 {
2246  PINTERNAL_RANGE_LIST pRangeList;
2247  PINTERNAL_RANGE pRange;
2248  PLIST_ENTRY ListEntry;
2250 
2251  FIXME("CM_First_Range(%p %p %p %p %lx)\n",
2252  rlh, pullStart, pullEnd, preElement, ulFlags);
2253 
2254  pRangeList = (PINTERNAL_RANGE_LIST)rlh;
2255 
2256  if (!IsValidRangeList(pRangeList))
2257  return CR_INVALID_RANGE_LIST;
2258 
2259  if (pullStart == NULL || pullEnd == NULL || preElement == NULL)
2260  return CR_INVALID_POINTER;
2261 
2262  if (ulFlags != 0)
2263  return CR_INVALID_FLAG;
2264 
2265  /* Lock the range list */
2266  WaitForSingleObject(pRangeList->hMutex, INFINITE);
2267 
2268  /* Fail, if the list is empty */
2269  if (IsListEmpty(&pRangeList->ListHead))
2270  {
2271  ret = CR_FAILURE;
2272  goto done;
2273  }
2274 
2275  /* Get the first range */
2276  ListEntry = pRangeList->ListHead.Flink;
2277  pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2278 
2279  /* Return the range data */
2280  *pullStart = pRange->ullStart;
2281  *pullEnd = pRange->ullEnd;
2282  *preElement = (RANGE_ELEMENT)pRange;
2283 
2284 done:
2285  /* Unlock the range list */
2286  ReleaseMutex(pRangeList->hMutex);
2287 
2288  return ret;
2289 }
2290 
2291 
2292 /***********************************************************************
2293  * CM_Free_Log_Conf [SETUPAPI.@]
2294  */
2295 CONFIGRET
2296 WINAPI
2298  _In_ LOG_CONF lcLogConfToBeFreed,
2299  _In_ ULONG ulFlags)
2300 {
2301  TRACE("CM_Free_Log_Conf(%lx %lx)\n",
2302  lcLogConfToBeFreed, ulFlags);
2303 
2304  return CM_Free_Log_Conf_Ex(lcLogConfToBeFreed, ulFlags, NULL);
2305 }
2306 
2307 
2308 /***********************************************************************
2309  * CM_Free_Log_Conf_Ex [SETUPAPI.@]
2310  */
2311 CONFIGRET
2312 WINAPI
2314  _In_ LOG_CONF lcLogConfToBeFreed,
2315  _In_ ULONG ulFlags,
2316  _In_opt_ HMACHINE hMachine)
2317 {
2319  HSTRING_TABLE StringTable = NULL;
2320  LPWSTR lpDevInst;
2321  PLOG_CONF_INFO pLogConfInfo;
2322  CONFIGRET ret;
2323 
2324  TRACE("CM_Free_Log_Conf_Ex(%lx %lx %p)\n",
2325  lcLogConfToBeFreed, ulFlags, hMachine);
2326 
2327  if (!pSetupIsUserAdmin())
2328  return CR_ACCESS_DENIED;
2329 
2330  pLogConfInfo = (PLOG_CONF_INFO)lcLogConfToBeFreed;
2331  if (!IsValidLogConf(pLogConfInfo))
2332  return CR_INVALID_LOG_CONF;
2333 
2334  if (ulFlags != 0)
2335  return CR_INVALID_FLAG;
2336 
2337  if (hMachine != NULL)
2338  {
2339  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2340  if (BindingHandle == NULL)
2341  return CR_FAILURE;
2342 
2343  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2344  if (StringTable == 0)
2345  return CR_FAILURE;
2346  }
2347  else
2348  {
2349  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2350  return CR_FAILURE;
2351  }
2352 
2353  lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
2354  if (lpDevInst == NULL)
2355  return CR_INVALID_DEVNODE;
2356 
2357  RpcTryExcept
2358  {
2360  lpDevInst,
2361  pLogConfInfo->ulType,
2362  pLogConfInfo->ulTag,
2363  0);
2364  }
2366  {
2368  }
2369  RpcEndExcept;
2370 
2371  return ret;
2372 }
2373 
2374 
2375 /***********************************************************************
2376  * CM_Free_Log_Conf_Handle [SETUPAPI.@]
2377  */
2378 CONFIGRET
2379 WINAPI
2381  _In_ LOG_CONF lcLogConf)
2382 {
2383  PLOG_CONF_INFO pLogConfInfo;
2384 
2385  TRACE("CM_Free_Log_Conf_Handle(%lx)\n", lcLogConf);
2386 
2387  pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
2388  if (!IsValidLogConf(pLogConfInfo))
2389  return CR_INVALID_LOG_CONF;
2390 
2391  HeapFree(GetProcessHeap(), 0, pLogConfInfo);
2392 
2393  return CR_SUCCESS;
2394 }
2395 
2396 
2397 /***********************************************************************
2398  * CM_Free_Range_List [SETUPAPI.@]
2399  */
2400 CONFIGRET
2401 WINAPI
2403  _In_ RANGE_LIST RangeList,
2404  _In_ ULONG ulFlags)
2405 {
2406  PINTERNAL_RANGE_LIST pRangeList;
2407  PINTERNAL_RANGE pRange;
2408  PLIST_ENTRY ListEntry;
2409 
2410  FIXME("CM_Free_Range_List(%p %lx)\n",
2411  RangeList, ulFlags);
2412 
2413  pRangeList = (PINTERNAL_RANGE_LIST)RangeList;
2414 
2415  if (!IsValidRangeList(pRangeList))
2416  return CR_INVALID_RANGE_LIST;
2417 
2418  if (ulFlags != 0)
2419  return CR_INVALID_FLAG;
2420 
2421  /* Lock the range list */
2422  WaitForSingleObject(pRangeList->hMutex, INFINITE);
2423 
2424  /* Free the list of ranges */
2425  while (!IsListEmpty(&pRangeList->ListHead))
2426  {
2427  ListEntry = RemoveHeadList(&pRangeList->ListHead);
2428  pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2429  HeapFree(GetProcessHeap(), 0, pRange);
2430  }
2431 
2432  /* Unlock the range list */
2433  ReleaseMutex(pRangeList->hMutex);
2434 
2435  /* Close the mutex */
2436  CloseHandle(pRangeList->hMutex);
2437 
2438  /* Free the range list */
2439  HeapFree(GetProcessHeap(), 0, pRangeList);
2440 
2441  return CR_SUCCESS;
2442 }
2443 
2444 
2445 /***********************************************************************
2446  * CM_Free_Res_Des [SETUPAPI.@]
2447  */
2448 CONFIGRET
2449 WINAPI
2451  _Out_ PRES_DES prdResDes,
2452  _In_ RES_DES rdResDes,
2453  _In_ ULONG ulFlags)
2454 {
2455  TRACE("CM_Free_Res_Des(%p %p %lx)\n",
2456  prdResDes, rdResDes, ulFlags);
2457 
2458  return CM_Free_Res_Des_Ex(prdResDes, rdResDes, ulFlags, NULL);
2459 }
2460 
2461 
2462 /***********************************************************************
2463  * CM_Free_Res_Des_Ex [SETUPAPI.@]
2464  */
2465 CONFIGRET
2466 WINAPI
2468  _Out_ PRES_DES prdResDes,
2469  _In_ RES_DES rdResDes,
2470  _In_ ULONG ulFlags,
2471  _In_opt_ HMACHINE hMachine)
2472 {
2473  FIXME("CM_Free_Res_Des_Ex(%p %p %lx %p)\n",
2474  prdResDes, rdResDes, ulFlags, hMachine);
2475 
2476  return CR_CALL_NOT_IMPLEMENTED;
2477 }
2478 
2479 
2480 /***********************************************************************
2481  * CM_Free_Res_Des_Handle [SETUPAPI.@]
2482  */
2483 CONFIGRET
2484 WINAPI
2486  _In_ RES_DES rdResDes)
2487 {
2488  FIXME("CM_Free_Res_Des_Handle(%p)\n", rdResDes);
2489 
2490  return CR_CALL_NOT_IMPLEMENTED;
2491 }
2492 
2493 
2494 /***********************************************************************
2495  * CM_Free_Resource_Conflict_Handle [SETUPAPI.@]
2496  */
2497 CONFIGRET
2498 WINAPI
2500  _In_ CONFLICT_LIST clConflictList)
2501 {
2502  PCONFLICT_DATA pConflictData;
2503 
2504  FIXME("CM_Free_Resource_Conflict_Handle(%p)\n",
2505  clConflictList);
2506 
2507  pConflictData = (PCONFLICT_DATA)clConflictList;
2508  if (!IsValidConflictData(pConflictData))
2509  return CR_INVALID_CONFLICT_LIST;
2510 
2511  if (pConflictData->pConflictList != NULL)
2512  MyFree(pConflictData->pConflictList);
2513 
2514  MyFree(pConflictData);
2515 
2516  return CR_SUCCESS;
2517 }
2518 
2519 
2520 /***********************************************************************
2521  * CM_Get_Child [SETUPAPI.@]
2522  */
2523 CONFIGRET
2524 WINAPI
2526  _Out_ PDEVINST pdnDevInst,
2527  _In_ DEVINST dnDevInst,
2528  _In_ ULONG ulFlags)
2529 {
2530  TRACE("CM_Get_Child(%p %p %lx)\n",
2531  pdnDevInst, dnDevInst, ulFlags);
2532 
2533  return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
2534 }
2535 
2536 
2537 /***********************************************************************
2538  * CM_Get_Child_Ex [SETUPAPI.@]
2539  */
2540 CONFIGRET
2541 WINAPI
2543  _Out_ PDEVINST pdnDevInst,
2544  _In_ DEVINST dnDevInst,
2545  _In_ ULONG ulFlags,
2546  _In_opt_ HMACHINE hMachine)
2547 {
2548  WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
2550  HSTRING_TABLE StringTable = NULL;
2551  LPWSTR lpDevInst;
2552  DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
2553  CONFIGRET ret;
2554 
2555  TRACE("CM_Get_Child_Ex(%p %lx %lx %p)\n",
2556  pdnDevInst, dnDevInst, ulFlags, hMachine);
2557 
2558  if (pdnDevInst == NULL)
2559  return CR_INVALID_POINTER;
2560 
2561  if (dnDevInst == 0)
2562  return CR_INVALID_DEVINST;
2563 
2564  if (ulFlags != 0)
2565  return CR_INVALID_FLAG;
2566 
2567  *pdnDevInst = -1;
2568 
2569  if (hMachine != NULL)
2570  {
2571  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2572  if (BindingHandle == NULL)
2573  return CR_FAILURE;
2574 
2575  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2576  if (StringTable == 0)
2577  return CR_FAILURE;
2578  }
2579  else
2580  {
2581  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2582  return CR_FAILURE;
2583  }
2584 
2585  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2586  if (lpDevInst == NULL)
2587  return CR_INVALID_DEVNODE;
2588 
2589  RpcTryExcept
2590  {
2592  PNP_GET_CHILD_DEVICE_INSTANCE,
2593  lpDevInst,
2594  szRelatedDevInst,
2595  &dwLength,
2596  0);
2597  }
2599  {
2601  }
2602  RpcEndExcept;
2603 
2604  if (ret != CR_SUCCESS)
2605  return ret;
2606 
2607  TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
2608 
2609  dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
2610  if (dwIndex == -1)
2611  return CR_FAILURE;
2612 
2613  *pdnDevInst = dwIndex;
2614 
2615  return CR_SUCCESS;
2616 }
2617 
2618 
2619 /***********************************************************************
2620  * CM_Get_Class_Key_NameA [SETUPAPI.@]
2621  */
2622 CONFIGRET
2623 WINAPI
2625  _In_ LPGUID ClassGuid,
2626  _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2627  _Inout_ PULONG pulLength,
2628  _In_ ULONG ulFlags)
2629 {
2630  TRACE("CM_Get_Class_Key_NameA(%p %p %p %lx)\n",
2631  ClassGuid, pszKeyName, pulLength, ulFlags);
2632 
2633  return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
2634  ulFlags, NULL);
2635 }
2636 
2637 
2638 /***********************************************************************
2639  * CM_Get_Class_Key_NameW [SETUPAPI.@]
2640  */
2641 CONFIGRET
2642 WINAPI
2644  _In_ LPGUID ClassGuid,
2645  _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2646  _Inout_ PULONG pulLength,
2647  _In_ ULONG ulFlags)
2648 {
2649  TRACE("CM_Get_Class_Key_NameW(%p %p %p %lx)\n",
2650  ClassGuid, pszKeyName, pulLength, ulFlags);
2651 
2652  return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
2653  ulFlags, NULL);
2654 }
2655 
2656 
2657 /***********************************************************************
2658  * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
2659  */
2660 CONFIGRET
2661 WINAPI
2663  _In_ LPGUID ClassGuid,
2664  _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2665  _Inout_ PULONG pulLength,
2666  _In_ ULONG ulFlags,
2667  _In_opt_ HMACHINE hMachine)
2668 {
2669  WCHAR szBuffer[MAX_GUID_STRING_LEN];
2671  ULONG ulLength;
2672  ULONG ulOrigLength;
2673 
2674  TRACE("CM_Get_Class_Key_Name_ExA(%p %p %p %lx %p)\n",
2675  ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2676 
2677  if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2678  return CR_INVALID_POINTER;
2679 
2680  ulOrigLength = *pulLength;
2681  *pulLength = 0;
2682 
2683  ulLength = MAX_GUID_STRING_LEN;
2684  ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
2685  ulFlags, hMachine);
2686  if (ret == CR_SUCCESS)
2687  {
2689  0,
2690  szBuffer,
2691  ulLength,
2692  pszKeyName,
2693  ulOrigLength,
2694  NULL,
2695  NULL) == 0)
2696  ret = CR_FAILURE;
2697  else
2698  *pulLength = lstrlenA(pszKeyName) + 1;
2699  }
2700 
2701  return CR_SUCCESS;
2702 }
2703 
2704 
2705 /***********************************************************************
2706  * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
2707  */
2708 CONFIGRET
2709 WINAPI
2711  _In_ LPGUID ClassGuid,
2712  _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2713  _Inout_ PULONG pulLength,
2714  _In_ ULONG ulFlags,
2715  _In_opt_ HMACHINE hMachine)
2716 {
2717  TRACE("CM_Get_Class_Key_Name_ExW(%p %p %p %lx %p)\n",
2718  ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2719 
2720  if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2721  return CR_INVALID_POINTER;
2722 
2723  if (ulFlags != 0)
2724  return CR_INVALID_FLAG;
2725 
2726  if (*pulLength < MAX_GUID_STRING_LEN)
2727  {
2728  *pulLength = 0;
2729  return CR_BUFFER_SMALL;
2730  }
2731 
2732  if (!GuidToString(ClassGuid, pszKeyName))
2733  return CR_INVALID_DATA;
2734 
2735  *pulLength = MAX_GUID_STRING_LEN;
2736 
2737  return CR_SUCCESS;
2738 }
2739 
2740 
2741 /***********************************************************************
2742  * CM_Get_Class_NameA [SETUPAPI.@]
2743  */
2744 CONFIGRET
2745 WINAPI
2747  _In_ LPGUID ClassGuid,
2748  _Out_writes_opt_(*pulLength) PCHAR Buffer,
2749  _Inout_ PULONG pulLength,
2750  _In_ ULONG ulFlags)
2751 {
2752  TRACE("CM_Get_Class_NameA(%p %p %p %lx)\n",
2753  ClassGuid, Buffer, pulLength, ulFlags);
2754 
2755  return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
2756  NULL);
2757 }
2758 
2759 
2760 /***********************************************************************
2761  * CM_Get_Class_NameW [SETUPAPI.@]
2762  */
2763 CONFIGRET
2764 WINAPI
2766  _In_ LPGUID ClassGuid,
2767  _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2768  _Inout_ PULONG pulLength,
2769  _In_ ULONG ulFlags)
2770 {
2771  TRACE("CM_Get_Class_NameW(%p %p %p %lx)\n",
2772  ClassGuid, Buffer, pulLength, ulFlags);
2773 
2774  return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
2775  NULL);
2776 }
2777 
2778 
2779 /***********************************************************************
2780  * CM_Get_Class_Name_ExA [SETUPAPI.@]
2781  */
2782 CONFIGRET
2783 WINAPI
2785  _In_ LPGUID ClassGuid,
2786  _Out_writes_opt_(*pulLength) PCHAR Buffer,
2787  _Inout_ PULONG pulLength,
2788  _In_ ULONG ulFlags,
2789  _In_opt_ HMACHINE hMachine)
2790 {
2791  WCHAR szBuffer[MAX_CLASS_NAME_LEN];
2793  ULONG ulLength;
2794  ULONG ulOrigLength;
2795 
2796  TRACE("CM_Get_Class_Name_ExA(%p %p %p %lx %p)\n",
2797  ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2798 
2799  if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2800  return CR_INVALID_POINTER;
2801 
2802  ulOrigLength = *pulLength;
2803  *pulLength = 0;
2804 
2805  ulLength = MAX_CLASS_NAME_LEN;
2806  ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
2807  ulFlags, hMachine);
2808  if (ret == CR_SUCCESS)
2809  {
2811  0,
2812  szBuffer,
2813  ulLength,
2814  Buffer,
2815  ulOrigLength,
2816  NULL,
2817  NULL) == 0)
2818  ret = CR_FAILURE;
2819  else
2820  *pulLength = lstrlenA(Buffer) + 1;
2821  }
2822 
2823  return ret;
2824 }
2825 
2826 
2827 /***********************************************************************
2828  * CM_Get_Class_Name_ExW [SETUPAPI.@]
2829  */
2830 CONFIGRET
2831 WINAPI
2833  _In_ LPGUID ClassGuid,
2834  _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2835  _Inout_ PULONG pulLength,
2836  _In_ ULONG ulFlags,
2837  _In_opt_ HMACHINE hMachine)
2838 {
2839  WCHAR szGuidString[MAX_GUID_STRING_LEN];
2841  CONFIGRET ret;
2842 
2843  TRACE("CM_Get_Class_Name_ExW(%p %p %p %lx %p\n",
2844  ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2845 
2846  if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2847  return CR_INVALID_POINTER;
2848 
2849  if (ulFlags != 0)
2850  return CR_INVALID_FLAG;
2851 
2852  if (!GuidToString(ClassGuid, szGuidString))
2853  return CR_INVALID_DATA;
2854 
2855  TRACE("Guid %s\n", debugstr_w(szGuidString));
2856 
2857  if (hMachine != NULL)
2858  {
2859  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2860  if (BindingHandle == NULL)
2861  return CR_FAILURE;
2862  }
2863  else
2864  {
2866  return CR_FAILURE;
2867  }
2868 
2869  RpcTryExcept
2870  {
2872  szGuidString,
2873  Buffer,
2874  pulLength,
2875  ulFlags);
2876  }
2878  {
2880  }
2881  RpcEndExcept;
2882 
2883  return ret;
2884 }
2885 
2886 
2887 /***********************************************************************
2888  * CM_Get_Class_Registry_PropertyA [SETUPAPI.@]
2889  */
2890 CONFIGRET
2891 WINAPI
2893  LPGUID ClassGuid,
2894  ULONG ulProperty,
2895  PULONG pulRegDataType,
2896  PVOID Buffer,
2897  PULONG pulLength,
2898  ULONG ulFlags,
2899  HMACHINE hMachine)
2900 {
2901  PWSTR BufferW = NULL;
2902  ULONG ulLength = 0;
2903  ULONG ulType;
2904  CONFIGRET ret;
2905 
2906  TRACE("CM_Get_Class_Registry_PropertyA(%p %lu %p %p %p %lx %p)\n",
2907  ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
2908  ulFlags, hMachine);
2909 
2910  if (pulLength == NULL)
2911  return CR_INVALID_POINTER;
2912 
2913  if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
2914  return CR_INVALID_PROPERTY;
2915 
2916  ulType = GetRegistryPropertyType(ulProperty);
2917  if (ulType == REG_SZ || ulType == REG_MULTI_SZ)
2918  {
2919  /* Get the required buffer size */
2920  ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2921  NULL, &ulLength, ulFlags, hMachine);
2922  if (ret != CR_BUFFER_SMALL)
2923  return ret;
2924 
2925  /* Allocate the unicode buffer */
2926  BufferW = HeapAlloc(GetProcessHeap(), 0, ulLength);
2927  if (BufferW == NULL)
2928  return CR_OUT_OF_MEMORY;
2929 
2930  /* Get the property */
2931  ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2932  BufferW, &ulLength, ulFlags, hMachine);
2933  if (ret != CR_SUCCESS)
2934  {
2935  HeapFree(GetProcessHeap(), 0, BufferW);
2936  return ret;
2937  }
2938 
2939  /* Do W->A conversion */
2940  *pulLength = WideCharToMultiByte(CP_ACP,
2941  0,
2942  BufferW,
2943  ulLength,
2944  Buffer,
2945  *pulLength,
2946  NULL,
2947  NULL);
2948 
2949  /* Release the unicode buffer */
2950  HeapFree(GetProcessHeap(), 0, BufferW);
2951 
2952  if (*pulLength == 0)
2953  ret = CR_FAILURE;
2954  }
2955  else
2956  {
2957  /* Get the property */
2958  ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2959  Buffer, pulLength, ulFlags, hMachine);
2960  }
2961 
2962  return ret;
2963 }
2964 
2965 
2966 /***********************************************************************
2967  * CM_Get_Class_Registry_PropertyW [SETUPAPI.@]
2968  */
2969 CONFIGRET
2970 WINAPI
2972  LPGUID ClassGuid,
2973  ULONG ulProperty,
2974  PULONG pulRegDataType,
2975  PVOID Buffer,
2976  PULONG pulLength,
2977  ULONG ulFlags,
2978  HMACHINE hMachine)
2979 {
2981  WCHAR szGuidString[PNP_MAX_GUID_STRING_LEN + 1];
2982  ULONG ulType = 0;
2983  ULONG ulTransferLength = 0;
2984  CONFIGRET ret;
2985 
2986  TRACE("CM_Get_Class_Registry_PropertyW(%p %lu %p %p %p %lx %p)\n",
2987  ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
2988  ulFlags, hMachine);
2989 
2990  if (ClassGuid == NULL || pulLength == NULL)
2991  return CR_INVALID_POINTER;
2992 
2993  if (ulFlags != 0)
2994  return CR_INVALID_FLAG;
2995 
2996  if (pSetupStringFromGuid(ClassGuid,
2997  szGuidString,
2999  return CR_INVALID_DATA;
3000 
3001  if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
3002  return CR_INVALID_PROPERTY;
3003 
3004  if (hMachine != NULL)
3005  {
3006  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3007  if (BindingHandle == NULL)
3008  return CR_FAILURE;
3009  }
3010  else
3011  {
3013  return CR_FAILURE;
3014  }
3015 
3016  ulTransferLength = *pulLength;
3017 
3018  RpcTryExcept
3019  {
3021  szGuidString,
3022  ulProperty,
3023  &ulType,
3024  Buffer,
3025  &ulTransferLength,
3026  pulLength,
3027  ulFlags);
3028  }
3030  {
3032  }
3033  RpcEndExcept;
3034 
3035  if (ret == CR_SUCCESS)
3036  {
3037  if (pulRegDataType != NULL)
3038  *pulRegDataType = ulType;
3039  }
3040 
3041  return ret;
3042 }
3043 
3044 
3045 /***********************************************************************
3046  * CM_Get_Depth [SETUPAPI.@]
3047  */
3048 CONFIGRET
3049 WINAPI
3051  _Out_ PULONG pulDepth,
3052  _In_ DEVINST dnDevInst,
3053  _In_ ULONG ulFlags)
3054 {
3055  TRACE("CM_Get_Depth(%p %lx %lx)\n",
3056  pulDepth, dnDevInst, ulFlags);
3057 
3058  return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
3059 }
3060 
3061 
3062 /***********************************************************************
3063  * CM_Get_Depth_Ex [SETUPAPI.@]
3064  */
3065 CONFIGRET
3066 WINAPI
3068  _Out_ PULONG pulDepth,
3069  _In_ DEVINST dnDevInst,
3070  _In_ ULONG ulFlags,
3071  _In_opt_ HMACHINE hMachine)
3072 {
3074  HSTRING_TABLE StringTable = NULL;
3075  LPWSTR lpDevInst;
3076  CONFIGRET ret;
3077 
3078  TRACE("CM_Get_Depth_Ex(%p %lx %lx %p)\n",
3079  pulDepth, dnDevInst, ulFlags, hMachine);
3080 
3081  if (pulDepth == NULL)
3082  return CR_INVALID_POINTER;
3083 
3084  if (dnDevInst == 0)
3085  return CR_INVALID_DEVINST;
3086 
3087  if (ulFlags != 0)
3088  return CR_INVALID_FLAG;
3089 
3090  if (hMachine != NULL)
3091  {
3092  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3093  if (BindingHandle == NULL)
3094  return CR_FAILURE;
3095 
3096  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3097  if (StringTable == 0)
3098  return CR_FAILURE;
3099  }
3100  else
3101  {
3102  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3103  return CR_FAILURE;
3104  }
3105 
3106  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3107  if (lpDevInst == NULL)
3108  return CR_INVALID_DEVNODE;
3109 
3110  RpcTryExcept
3111  {
3113  lpDevInst,
3114  pulDepth,
3115  ulFlags);
3116  }
3118  {
3120  }
3121  RpcEndExcept;
3122 
3123  return ret;
3124 }
3125 
3126 
3127 /***********************************************************************
3128  * CM_Get_DevNode_Custom_PropertyA [SETUPAPI.@]
3129  */
3130 CONFIGRET
3131 WINAPI
3133  _In_ DEVINST dnDevInst,
3134  _In_ PCSTR pszCustomPropertyName,
3135  _Out_opt_ PULONG pulRegDataType,
3136  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3137  _Inout_ PULONG pulLength,
3138  _In_ ULONG ulFlags)
3139 {
3140  TRACE("CM_Get_DevNode_Custom_PropertyA(%lx %s %p %p %p %lx)\n",
3141  dnDevInst, pszCustomPropertyName, pulRegDataType,
3142  Buffer, pulLength, ulFlags);
3143 
3144  return CM_Get_DevNode_Custom_Property_ExA(dnDevInst, pszCustomPropertyName,
3145  pulRegDataType, Buffer,
3146  pulLength, ulFlags, NULL);
3147 }
3148 
3149 
3150 /***********************************************************************
3151  * CM_Get_DevNode_Custom_PropertyW [SETUPAPI.@]
3152  */
3153 CONFIGRET
3154 WINAPI
3156  _In_ DEVINST dnDevInst,
3157  _In_ PCWSTR pszCustomPropertyName,
3158  _Out_opt_ PULONG pulRegDataType,
3159  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3160  _Inout_ PULONG pulLength,
3161  _In_ ULONG ulFlags)
3162 {
3163  TRACE("CM_Get_DevNode_Custom_PropertyW(%lx %s %p %p %p %lx)\n",
3164  dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3165  Buffer, pulLength, ulFlags);
3166 
3167  return CM_Get_DevNode_Custom_Property_ExW(dnDevInst, pszCustomPropertyName,
3168  pulRegDataType, Buffer,
3169  pulLength, ulFlags, NULL);
3170 }
3171 
3172 
3173 /***********************************************************************
3174  * CM_Get_DevNode_Custom_Property_ExA [SETUPAPI.@]
3175  */
3176 CONFIGRET
3177 WINAPI
3179  _In_ DEVINST dnDevInst,
3180  _In_ PCSTR pszCustomPropertyName,
3181  _Out_opt_ PULONG pulRegDataType,
3182  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3183  _Inout_ PULONG pulLength,
3184  _In_ ULONG ulFlags,
3185  _In_opt_ HMACHINE hMachine)
3186 {
3187  LPWSTR pszPropertyNameW = NULL;
3188  PVOID BufferW;
3189  ULONG ulLengthW;
3190  ULONG ulDataType = REG_NONE;
3191  CONFIGRET ret;
3192 
3193  TRACE("CM_Get_DevNode_Custom_Property_ExA(%lx %s %p %p %p %lx %p)\n",
3194  dnDevInst, pszCustomPropertyName, pulRegDataType,
3195  Buffer, pulLength, ulFlags, hMachine);
3196 
3197  if (!pulLength)
3198  return CR_INVALID_POINTER;
3199 
3200  ulLengthW = *pulLength * sizeof(WCHAR);
3201  BufferW = HeapAlloc(GetProcessHeap(), 0, ulLengthW);
3202  if (!BufferW)
3203  return CR_OUT_OF_MEMORY;
3204 
3205  pszPropertyNameW = pSetupMultiByteToUnicode(pszCustomPropertyName,
3206  CP_ACP);
3207  if (pszPropertyNameW == NULL)
3208  {
3209  HeapFree(GetProcessHeap(), 0, BufferW);
3210  return CR_OUT_OF_MEMORY;
3211  }
3212 
3214  pszPropertyNameW,
3215  &ulDataType,
3216  BufferW,
3217  &ulLengthW,
3218  ulFlags,
3219  hMachine);
3220  if (ret == CR_SUCCESS)
3221  {
3222  if (ulDataType == REG_SZ ||
3223  ulDataType == REG_EXPAND_SZ ||
3224  ulDataType == REG_MULTI_SZ)
3225  {
3226  /* Do W->A conversion */
3227  *pulLength = WideCharToMultiByte(CP_ACP,
3228  0,
3229  BufferW,
3230  lstrlenW(BufferW) + 1,
3231  Buffer,
3232  *pulLength,
3233  NULL,
3234  NULL);
3235  if (*pulLength == 0)
3236  ret = CR_FAILURE;
3237  }
3238  else
3239  {
3240  /* Directly copy the value */
3241  if (ulLengthW <= *pulLength)
3242  memcpy(Buffer, BufferW, ulLengthW);
3243  else
3244  {
3245  *pulLength = ulLengthW;
3246  ret = CR_BUFFER_SMALL;
3247  }
3248  }
3249  }
3250 
3251  if (pulRegDataType)
3252  *pulRegDataType = ulDataType;
3253 
3254  HeapFree(GetProcessHeap(), 0, BufferW);
3255  MyFree(pszPropertyNameW);
3256 
3257  return ret;
3258 }
3259 
3260 
3261 /***********************************************************************
3262  * CM_Get_DevNode_Custom_Property_ExW [SETUPAPI.@]
3263  */
3264 CONFIGRET
3265 WINAPI
3267  _In_ DEVINST dnDevInst,
3268  _In_ PCWSTR pszCustomPropertyName,
3269  _Out_opt_ PULONG pulRegDataType,
3270  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3271  _Inout_ PULONG pulLength,
3272  _In_ ULONG ulFlags,
3273  _In_opt_ HMACHINE hMachine)
3274 {
3276  HSTRING_TABLE StringTable = NULL;
3277  LPWSTR lpDevInst;
3278  ULONG ulDataType = REG_NONE;
3279  ULONG ulTransferLength;
3281 
3282  TRACE("CM_Get_DevNode_Custom_Property_ExW(%lx %s %p %p %p %lx %p)\n",
3283  dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3284  Buffer, pulLength, ulFlags, hMachine);
3285 
3286  if (dnDevInst == 0)
3287  return CR_INVALID_DEVNODE;
3288 
3289  if (pszCustomPropertyName == NULL ||
3290  pulLength == NULL ||
3291  *pulLength == 0)
3292  return CR_INVALID_POINTER;
3293 
3294  if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
3295  return CR_INVALID_FLAG;
3296 
3297  if (hMachine != NULL)
3298  {
3299  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3300  if (BindingHandle == NULL)
3301  return CR_FAILURE;
3302 
3303  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3304  if (StringTable == 0)
3305  return CR_FAILURE;
3306  }
3307  else
3308  {
3309  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3310  return CR_FAILURE;
3311  }
3312 
3313  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3314  if (lpDevInst == NULL)
3315  return CR_INVALID_DEVNODE;
3316 
3317  ulTransferLength = *pulLength;
3318 
3319  RpcTryExcept
3320  {
3322  lpDevInst,
3323  (LPWSTR)pszCustomPropertyName,
3324  &ulDataType,
3325  Buffer,
3326  &ulTransferLength,
3327  pulLength,
3328  ulFlags);
3329  }
3331  {
3333  }
3334  RpcEndExcept;
3335 
3336  if (ret == CR_SUCCESS)
3337  {
3338  if (pulRegDataType != NULL)
3339  *pulRegDataType = ulDataType;
3340  }
3341 
3342  return ret;
3343 }
3344 
3345 
3346 /***********************************************************************
3347  * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
3348  */
3349 CONFIGRET
3350 WINAPI
3352  _In_ DEVINST dnDevInst,
3353  _In_ ULONG ulProperty,
3354  _Out_opt_ PULONG pulRegDataType,
3355  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3356  _Inout_ PULONG pulLength,
3357  _In_ ULONG ulFlags)
3358 {
3359  TRACE("CM_Get_DevNode_Registry_PropertyA(%lx %lu %p %p %p %lx)\n",
3360  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3361 
3362  return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
3363  pulRegDataType, Buffer,
3364  pulLength, ulFlags, NULL);
3365 }
3366 
3367 
3368 /***********************************************************************
3369  * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
3370  */
3371 CONFIGRET
3372 WINAPI
3374  _In_ DEVINST dnDevInst,
3375  _In_ ULONG ulProperty,
3376  _Out_opt_ PULONG pulRegDataType,
3377  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3378  _Inout_ PULONG pulLength,
3379  _In_ ULONG ulFlags)
3380 {
3381  TRACE("CM_Get_DevNode_Registry_PropertyW(%lx %lu %p %p %p %lx)\n",
3382  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3383 
3384  return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
3385  pulRegDataType, Buffer,
3386  pulLength, ulFlags, NULL);
3387 }
3388 
3389 
3390 /***********************************************************************
3391  * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
3392  */
3393 CONFIGRET
3394 WINAPI
3396  _In_ DEVINST dnDevInst,
3397  _In_ ULONG ulProperty,
3398  _Out_opt_ PULONG pulRegDataType,
3399  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3400  _Inout_ PULONG pulLength,
3401  _In_ ULONG ulFlags,
3402  _In_opt_ HMACHINE hMachine)
3403 {
3404  PVOID BufferW;
3405  ULONG LengthW;
3406  ULONG ulDataType = REG_NONE;
3407  CONFIGRET ret;
3408 
3409  TRACE("CM_Get_DevNode_Registry_Property_ExA(%lx %lu %p %p %p %lx %p)\n",
3410  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3411  ulFlags, hMachine);
3412 
3413  if (!pulLength)
3414  return CR_INVALID_POINTER;
3415 
3416  LengthW = *pulLength * sizeof(WCHAR);
3417  BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
3418 
3419  if (!BufferW)
3420  return CR_OUT_OF_MEMORY;
3421 
3423  ulProperty,
3424  &ulDataType,
3425  BufferW,
3426  &LengthW,
3427  ulFlags,
3428  hMachine);
3429 
3430  if (ret == CR_SUCCESS)
3431  {
3432  if (ulDataType == REG_SZ ||
3433  ulDataType == REG_EXPAND_SZ ||
3434  ulDataType == REG_MULTI_SZ)
3435  {
3436  /* Do W->A conversion */
3437  *pulLength = WideCharToMultiByte(CP_ACP,
3438  0,
3439  BufferW,
3440  lstrlenW(BufferW) + 1,
3441  Buffer,
3442  *pulLength,
3443  NULL,
3444  NULL);
3445  if (*pulLength == 0)
3446  ret = CR_FAILURE;
3447  }
3448  else
3449  {
3450  /* Directly copy the value */
3451  if (LengthW <= *pulLength)
3452  memcpy(Buffer, BufferW, LengthW);
3453  else
3454  {
3455  *pulLength = LengthW;
3456  ret = CR_BUFFER_SMALL;
3457  }
3458  }
3459  }
3460 
3461  if (pulRegDataType)
3462  *pulRegDataType = ulDataType;
3463 
3464  HeapFree(GetProcessHeap(), 0, BufferW);
3465 
3466  return ret;
3467 }
3468 
3469 
3470 /***********************************************************************
3471  * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
3472  */
3473 CONFIGRET
3474 WINAPI
3476  _In_ DEVINST dnDevInst,
3477  _In_ ULONG ulProperty,
3478  _Out_opt_ PULONG pulRegDataType,
3479  _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3480  _Inout_ PULONG pulLength,
3481  _In_ ULONG ulFlags,
3482  _In_opt_ HMACHINE hMachine)
3483 {
3485  HSTRING_TABLE StringTable = NULL;
3487  LPWSTR lpDevInst;
3488  ULONG ulDataType = REG_NONE;
3489  ULONG ulTransferLength = 0;
3490 
3491  TRACE("CM_Get_DevNode_Registry_Property_ExW(%lx %lu %p %p %p %lx %p)\n",
3492  dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3493  ulFlags, hMachine);
3494 
3495  if (dnDevInst == 0)
3496  return CR_INVALID_DEVNODE;
3497 
3498  if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
3499  return CR_INVALID_PROPERTY;
3500 
3501  /* pulRegDataType is optional */
3502 
3503  /* Buffer is optional */
3504 
3505  if (pulLength == NULL)
3506  return CR_INVALID_POINTER;
3507 
3508  if (*pulLength == 0)
3509  return CR_INVALID_POINTER;
3510 
3511  if (ulFlags != 0)
3512  return CR_INVALID_FLAG;
3513 
3514  if (hMachine != NULL)
3515  {
3516  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3517  if (BindingHandle == NULL)
3518  return CR_FAILURE;
3519 
3520  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3521  if (StringTable == 0)
3522  return CR_FAILURE;
3523  }
3524  else
3525  {
3526  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3527  return CR_FAILURE;
3528  }
3529 
3530  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3531  if (lpDevInst == NULL)
3532  return CR_INVALID_DEVNODE;
3533 
3534  ulTransferLength = *pulLength;
3535 
3536  RpcTryExcept
3537  {
3539  lpDevInst,
3540  ulProperty,
3541  &ulDataType,
3542  Buffer,
3543  &ulTransferLength,
3544  pulLength,
3545  ulFlags);
3546  }
3548  {
3550  }
3551  RpcEndExcept;
3552 
3553  if (ret == CR_SUCCESS)
3554  {
3555  if (pulRegDataType != NULL)
3556  *pulRegDataType = ulDataType;
3557  }
3558 
3559  return ret;
3560 }
3561 
3562 
3563 /***********************************************************************
3564  * CM_Get_DevNode_Status [SETUPAPI.@]
3565  */
3566 CONFIGRET
3567 WINAPI
3569  _Out_ PULONG pulStatus,
3570  _Out_ PULONG pulProblemNumber,
3571  _In_ DEVINST dnDevInst,
3572  _In_ ULONG ulFlags)
3573 {
3574  TRACE("CM_Get_DevNode_Status(%p %p %lx %lx)\n",
3575  pulStatus, pulProblemNumber, dnDevInst, ulFlags);
3576 
3577  return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
3578  ulFlags, NULL);
3579 }
3580 
3581 
3582 /***********************************************************************
3583  * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
3584  */
3585 CONFIGRET
3586 WINAPI
3588  _Out_ PULONG pulStatus,
3589  _Out_ PULONG pulProblemNumber,
3590  _In_ DEVINST dnDevInst,
3591  _In_ ULONG ulFlags,
3592  _In_opt_ HMACHINE hMachine)
3593 {
3595  HSTRING_TABLE StringTable = NULL;
3596  LPWSTR lpDevInst;
3597  CONFIGRET ret;
3598 
3599  TRACE("CM_Get_DevNode_Status_Ex(%p %p %lx %lx %p)\n",
3600  pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
3601 
3602  if (pulStatus == NULL || pulProblemNumber == NULL)
3603  return CR_INVALID_POINTER;
3604 
3605  if (dnDevInst == 0)
3606  return CR_INVALID_DEVINST;
3607 
3608  if (ulFlags != 0)
3609  return CR_INVALID_FLAG;
3610 
3611  if (hMachine != NULL)
3612  {
3613  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3614  if (BindingHandle == NULL)
3615  return CR_FAILURE;
3616 
3617  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3618  if (StringTable == 0)
3619  return CR_FAILURE;
3620  }
3621  else
3622  {
3623  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3624  return CR_FAILURE;
3625  }
3626 
3627  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3628  if (lpDevInst == NULL)
3629  return CR_INVALID_DEVNODE;
3630 
3631  RpcTryExcept
3632  {
3634  lpDevInst,
3635  pulStatus,
3636  pulProblemNumber,
3637  ulFlags);
3638  }
3640  {
3642  }
3643  RpcEndExcept;
3644 
3645  return ret;
3646 }
3647 
3648 
3649 /***********************************************************************
3650  * CM_Get_Device_IDA [SETUPAPI.@]
3651  */
3652 CONFIGRET
3653 WINAPI
3655  _In_ DEVINST dnDevInst,
3656  _Out_writes_(BufferLen) PCHAR Buffer,
3657  _In_ ULONG BufferLen,
3658  _In_ ULONG ulFlags)
3659 {
3660  TRACE("CM_Get_Device_IDA(%lx %p %lu %lx)\n",
3661  dnDevInst, Buffer, BufferLen, ulFlags);
3662 
3663  return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3664 }
3665 
3666 
3667 /***********************************************************************
3668  * CM_Get_Device_IDW [SETUPAPI.@]
3669  */
3670 CONFIGRET
3671 WINAPI
3673  _In_ DEVINST dnDevInst,
3674  _Out_writes_(BufferLen) PWCHAR Buffer,
3675  _In_ ULONG BufferLen,
3676  _In_ ULONG ulFlags)
3677 {
3678  TRACE("CM_Get_Device_IDW(%lx %p %lu %lx)\n",
3679  dnDevInst, Buffer, BufferLen, ulFlags);
3680 
3681  return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3682 }
3683 
3684 
3685 /***********************************************************************
3686  * CM_Get_Device_ID_ExA [SETUPAPI.@]
3687  */
3688 CONFIGRET
3689 WINAPI
3691  _In_ DEVINST dnDevInst,
3692  _Out_writes_(BufferLen) PCHAR Buffer,
3693  _In_ ULONG BufferLen,
3694  _In_ ULONG ulFlags,
3695  _In_opt_ HMACHINE hMachine)
3696 {
3697  WCHAR szBufferW[MAX_DEVICE_ID_LEN];
3699 
3700  TRACE("CM_Get_Device_ID_ExA(%lx %p %lu %lx %p)\n",
3701  dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3702 
3703  if (Buffer == NULL)
3704  return CR_INVALID_POINTER;
3705 
3706  ret = CM_Get_Device_ID_ExW(dnDevInst,
3707  szBufferW,
3709  ulFlags,
3710  hMachine);
3711  if (ret == CR_SUCCESS)
3712  {
3714  0,
3715  szBufferW,
3716  lstrlenW(szBufferW) + 1,
3717  Buffer,
3718  BufferLen,
3719  NULL,
3720  NULL) == 0)
3721  ret = CR_FAILURE;
3722  }
3723 
3724  return ret;
3725 }
3726 
3727 
3728 /***********************************************************************
3729  * CM_Get_Device_ID_ExW [SETUPAPI.@]
3730  */
3731 CONFIGRET
3732 WINAPI
3734  _In_ DEVINST dnDevInst,
3735  _Out_writes_(BufferLen) PWCHAR Buffer,
3736  _In_ ULONG BufferLen,
3737  _In_ ULONG ulFlags,
3738  _In_opt_ HMACHINE hMachine)
3739 {
3740  HSTRING_TABLE StringTable = NULL;
3741 
3742  TRACE("CM_Get_Device_ID_ExW(%lx %p %lu %lx %p)\n",
3743  dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3744 
3745  if (dnDevInst == 0)
3746  return CR_INVALID_DEVINST;
3747 
3748  if (Buffer == NULL)
3749  return CR_INVALID_POINTER;
3750 
3751  if (ulFlags != 0)
3752  return CR_INVALID_FLAG;
3753 
3754  if (hMachine != NULL)
3755  {
3756  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3757  if (StringTable == NULL)
3758  return CR_FAILURE;
3759  }
3760  else
3761  {
3762  if (!PnpGetLocalHandles(NULL, &StringTable))
3763  return CR_FAILURE;
3764  }
3765 
3766  if (!pSetupStringTableStringFromIdEx(StringTable,
3767  dnDevInst,
3768  Buffer,
3769  &BufferLen))
3770  return CR_FAILURE;
3771 
3772  return CR_SUCCESS;
3773 }
3774 
3775 
3776 /***********************************************************************
3777  * CM_Get_Device_ID_ListA [SETUPAPI.@]
3778  */
3779 CONFIGRET
3780 WINAPI
3782  _In_ PCSTR pszFilter,
3783  _Out_writes_(BufferLen) PCHAR Buffer,
3784  _In_ ULONG BufferLen,
3785  _In_ ULONG ulFlags)
3786 {
3787  TRACE("CM_Get_Device_ID_ListA(%p %p %lu %lx)\n",
3788  pszFilter, Buffer, BufferLen, ulFlags);
3789 
3790  return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
3791  ulFlags, NULL);
3792 }
3793 
3794 
3795 /***********************************************************************
3796  * CM_Get_Device_ID_ListW [SETUPAPI.@]
3797  */
3798 CONFIGRET
3799 WINAPI
3801  _In_ PCWSTR pszFilter,
3802  _Out_writes_(BufferLen) PWCHAR Buffer,
3803  _In_ ULONG BufferLen,
3804  _In_ ULONG ulFlags)
3805 {
3806  TRACE("CM_Get_Device_ID_ListW(%p %p %lu %lx)\n",
3807  pszFilter, Buffer, BufferLen, ulFlags);
3808 
3809  return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
3810  ulFlags, NULL);
3811 }
3812 
3813 
3814 /***********************************************************************
3815  * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
3816  */
3817 CONFIGRET
3818 WINAPI
3820  _In_ PCSTR pszFilter,
3821  _Out_writes_(BufferLen) PCHAR Buffer,
3822  _In_ ULONG BufferLen,
3823  _In_ ULONG ulFlags,
3824  _In_opt_ HMACHINE hMachine)
3825 {
3826  LPWSTR BufferW = NULL;
3827  LPWSTR pszFilterW = NULL;
3829 
3830  TRACE("CM_Get_Device_ID_List_ExA(%p %p %lu %lx %p)\n",
3831  pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3832 
3833  BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
3834  if (BufferW == NULL)
3835  return CR_OUT_OF_MEMORY;
3836 
3837  if (pszFilter == NULL)
3838  {
3840  BufferW,
3841  BufferLen,
3842  ulFlags,
3843  hMachine);
3844  }
3845  else
3846  {
3847  if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3848  {
3850  goto Done;
3851  }
3852 
3853  ret = CM_Get_Device_ID_List_ExW(pszFilterW,
3854  BufferW,
3855  BufferLen,
3856  ulFlags,
3857  hMachine);
3858 
3859  MyFree(pszFilterW);
3860  }
3861 
3863  0,
3864  BufferW,
3865  BufferLen,
3866  Buffer,
3867  BufferLen,
3868  NULL,
3869  NULL) == 0)
3870  ret = CR_FAILURE;
3871 
3872 Done:
3873  MyFree(BufferW);
3874 
3875  return ret;
3876 }
3877 
3878 
3879 /***********************************************************************
3880  * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
3881  */
3882 CONFIGRET
3883 WINAPI
3885  _In_ PCWSTR pszFilter,
3886  _Out_writes_(BufferLen) PWCHAR Buffer,
3887  _In_ ULONG BufferLen,
3888  _In_ ULONG ulFlags,
3889  _In_opt_ HMACHINE hMachine)
3890 {
3892  CONFIGRET ret;
3893 
3894  TRACE("CM_Get_Device_ID_List_ExW(%p %p %lu %lx %p)\n",
3895  pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3896 
3897  if (Buffer == NULL || BufferLen == 0)
3898  return CR_INVALID_POINTER;
3899 
3900  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
3901  return CR_INVALID_FLAG;
3902 
3903  if (hMachine != NULL)
3904  {
3905  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3906  if (BindingHandle == NULL)
3907  return CR_FAILURE;
3908  }
3909  else
3910  {
3912  return CR_FAILURE;
3913  }
3914 
3915  *Buffer = 0;
3916 
3917  RpcTryExcept
3918  {
3920  (LPWSTR)pszFilter,
3921  Buffer,
3922  &BufferLen,
3923  ulFlags);
3924  }
3926  {
3928  }
3929  RpcEndExcept;
3930 
3931  return ret;
3932 }
3933 
3934 
3935 /***********************************************************************
3936  * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
3937  */
3938 CONFIGRET
3939 WINAPI
3941  _Out_ PULONG pulLen,
3942  _In_opt_ PCSTR pszFilter,
3943  _In_ ULONG ulFlags)
3944 {
3945  TRACE("CM_Get_Device_ID_List_SizeA(%p %s %lx)\n",
3946  pulLen, debugstr_a(pszFilter), ulFlags);
3947 
3948  return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
3949 }
3950 
3951 
3952 /***********************************************************************
3953  * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
3954  */
3955 CONFIGRET
3956 WINAPI
3958  _Out_ PULONG pulLen,
3959  _In_opt_ PCWSTR pszFilter,
3960  _In_ ULONG ulFlags)
3961 {
3962  TRACE("CM_Get_Device_ID_List_SizeW(%p %s %lx)\n",
3963  pulLen, debugstr_w(pszFilter), ulFlags);
3964 
3965  return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
3966 }
3967 
3968 
3969 /***********************************************************************
3970  * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
3971  */
3972 CONFIGRET
3973 WINAPI
3975  _Out_ PULONG pulLen,
3976  _In_opt_ PCSTR pszFilter,
3977  _In_ ULONG ulFlags,
3978  _In_opt_ HMACHINE hMachine)
3979 {
3980  LPWSTR pszFilterW = NULL;
3982 
3983  FIXME("CM_Get_Device_ID_List_Size_ExA(%p %s %lx %p)\n",
3984  pulLen, debugstr_a(pszFilter), ulFlags, hMachine);
3985 
3986  if (pszFilter == NULL)
3987  {
3989  NULL,
3990  ulFlags,
3991  hMachine);
3992  }
3993  else
3994  {
3995  if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3996  return CR_INVALID_DEVICE_ID;
3997 
3999  pszFilterW,
4000  ulFlags,
4001  hMachine);
4002 
4003  MyFree(pszFilterW);
4004  }
4005 
4006  return ret;
4007 }
4008 
4009 
4010 /***********************************************************************
4011  * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
4012  */
4013 CONFIGRET
4014 WINAPI
4016  _Out_ PULONG pulLen,
4017  _In_opt_ PCWSTR pszFilter,
4018  _In_ ULONG ulFlags,
4019  _In_opt_ HMACHINE hMachine)
4020 {
4022  CONFIGRET ret;
4023 
4024  FIXME("CM_Get_Device_ID_List_Size_ExW(%p %s %lx %p)\n",
4025  pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
4026 
4027  if (pulLen == NULL)
4028  return CR_INVALID_POINTER;
4029 
4030  if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
4031  return CR_INVALID_FLAG;
4032 
4033  if (hMachine != NULL)
4034  {
4035  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4036  if (BindingHandle == NULL)
4037  return CR_FAILURE;
4038  }
4039  else
4040  {
4042  return CR_FAILURE;
4043  }
4044 
4045  *pulLen = 0;
4046 
4047  RpcTryExcept
4048  {
4050  (LPWSTR)pszFilter,
4051  pulLen,
4052  ulFlags);
4053  }
4055  {
4057  }
4058  RpcEndExcept;
4059 
4060  return ret;
4061 }
4062 
4063 
4064 /***********************************************************************
4065  * CM_Get_Device_ID_Size [SETUPAPI.@]
4066  */
4067 CONFIGRET
4068 WINAPI
4070  _Out_ PULONG pulLen,
4071  _In_ DEVINST dnDevInst,
4072  _In_ ULONG ulFlags)
4073 {
4074  TRACE("CM_Get_Device_ID_Size(%p %lx %lx)\n",
4075  pulLen, dnDevInst, ulFlags);
4076 
4077  return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
4078 }
4079 
4080 
4081 /***********************************************************************
4082  * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
4083  */
4084 CONFIGRET
4085 WINAPI
4087  _Out_ PULONG pulLen,
4088  _In_ DEVINST dnDevInst,
4089  _In_ ULONG ulFlags,
4090  _In_opt_ HMACHINE hMachine)
4091 {
4092  HSTRING_TABLE StringTable = NULL;
4093  LPWSTR DeviceId;
4094 
4095  TRACE("CM_Get_Device_ID_Size_Ex(%p %lx %lx %p)\n",
4096  pulLen, dnDevInst, ulFlags, hMachine);
4097 
4098  if (pulLen == NULL)
4099  return CR_INVALID_POINTER;
4100 
4101  if (dnDevInst == 0)
4102  return CR_INVALID_DEVINST;
4103 
4104  if (ulFlags != 0)
4105  return CR_INVALID_FLAG;
4106 
4107  if (hMachine != NULL)
4108  {
4109  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4110  if (StringTable == NULL)
4111  return CR_FAILURE;
4112  }
4113  else
4114  {
4115  if (!PnpGetLocalHandles(NULL, &StringTable))
4116  return CR_FAILURE;
4117  }
4118 
4119  DeviceId = pSetupStringTableStringFromId(StringTable, dnDevInst);
4120  if (DeviceId == NULL)
4121  {
4122  *pulLen = 0;
4123  return CR_SUCCESS;
4124  }
4125 
4126  *pulLen = lstrlenW(DeviceId);
4127 
4128  return CR_SUCCESS;
4129 }
4130 
4131 
4132 /***********************************************************************
4133  * CM_Get_Device_Interface_AliasA [SETUPAPI.@]
4134  */
4135 CONFIGRET
4136 WINAPI
4138  _In_ LPCSTR pszDeviceInterface,
4139  _In_ LPGUID AliasInterfaceGuid,
4140  _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4141  _Inout_ PULONG pulLength,
4142  _In_ ULONG ulFlags)
4143 {
4144  TRACE("CM_Get_Device_Interface_AliasA(%p %p %p %p %lx)\n",
4145  pszDeviceInterface, AliasInterfaceGuid,
4146  pszAliasDeviceInterface, pulLength, ulFlags);
4147 
4148  return CM_Get_Device_Interface_Alias_ExA(pszDeviceInterface,
4149  AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4150  ulFlags, NULL);
4151 }
4152 
4153 
4154 /***********************************************************************
4155  * CM_Get_Device_Interface_AliasW [SETUPAPI.@]
4156  */
4157 CONFIGRET
4158 WINAPI
4160  _In_ LPCWSTR pszDeviceInterface,
4161  _In_ LPGUID AliasInterfaceGuid,
4162  _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4163  _Inout_ PULONG pulLength,
4164  _In_ ULONG ulFlags)
4165 {
4166  TRACE("CM_Get_Device_Interface_AliasW(%p %p %p %p %lx)\n",
4167  pszDeviceInterface, AliasInterfaceGuid,
4168  pszAliasDeviceInterface, pulLength, ulFlags);
4169 
4170  return CM_Get_Device_Interface_Alias_ExW(pszDeviceInterface,
4171  AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4172  ulFlags, NULL);
4173 }
4174 
4175 
4176 /***********************************************************************
4177  * CM_Get_Device_Interface_Alias_ExA [SETUPAPI.@]
4178  */
4179 CONFIGRET
4180 WINAPI
4182  _In_ LPCSTR pszDeviceInterface,
4183  _In_ LPGUID AliasInterfaceGuid,
4184  _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4185  _Inout_ PULONG pulLength,
4186  _In_ ULONG ulFlags,
4187  _In_opt_ HMACHINE hMachine)
4188 {
4189  FIXME("CM_Get_Device_Interface_Alias_ExA(%p %p %p %p %lx %p)\n",
4190  pszDeviceInterface, AliasInterfaceGuid,
4191  pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4192 
4193  return CR_CALL_NOT_IMPLEMENTED;
4194 }
4195 
4196 
4197 /***********************************************************************
4198  * CM_Get_Device_Interface_Alias_ExW [SETUPAPI.@]
4199  */
4200 CONFIGRET
4201 WINAPI
4203  _In_ LPCWSTR pszDeviceInterface,
4204  _In_ LPGUID AliasInterfaceGuid,
4205  _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4206  _Inout_ PULONG pulLength,
4207  _In_ ULONG ulFlags,
4208  _In_opt_ HMACHINE hMachine)
4209 {
4211  ULONG ulTransferLength;
4213 
4214  TRACE("CM_Get_Device_Interface_Alias_ExW(%p %p %p %p %lx %p)\n",
4215  pszDeviceInterface, AliasInterfaceGuid,
4216  pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4217 
4218  if (pszDeviceInterface == NULL ||
4219  AliasInterfaceGuid == NULL ||
4220  pszAliasDeviceInterface == NULL ||
4221  pulLength == NULL)
4222  return CR_INVALID_POINTER;
4223 
4224  if (ulFlags != 0)
4225  return CR_INVALID_FLAG;
4226 
4227  if (hMachine != NULL)
4228  {
4229  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4230  if (BindingHandle == NULL)
4231  return CR_FAILURE;
4232  }
4233  else
4234  {
4236  return CR_FAILURE;
4237  }
4238 
4239  ulTransferLength = *pulLength;
4240 
4241  RpcTryExcept
4242  {
4244  (LPWSTR)pszDeviceInterface,
4245  AliasInterfaceGuid,
4246  pszAliasDeviceInterface,
4247  pulLength,
4248  &ulTransferLength,
4249  0);
4250  }
4252  {
4254  }
4255  RpcEndExcept;
4256 
4257  return ret;
4258 }
4259 
4260 
4261 /***********************************************************************
4262  * CM_Get_Device_Interface_ListA (SETUPAPI.@)
4263  */
4264 CONFIGRET
4265 WINAPI
4268  _In_opt_ DEVINSTID_A pDeviceID,
4269  _Out_writes_(BufferLen) PCHAR Buffer,
4270  _In_ ULONG BufferLen,
4271  _In_ ULONG ulFlags)
4272 {
4273  TRACE("CM_Get_Device_Interface_ListA(%s %s %p %lu 0x%08lx)\n",
4275  Buffer, BufferLen, ulFlags);
4276 
4278  Buffer, BufferLen, ulFlags, NULL);
4279 }
4280 
4281 
4282 /***********************************************************************
4283  * CM_Get_Device_Interface_ListW (SETUPAPI.@)
4284  */
4285 CONFIGRET
4286 WINAPI
4289  _In_opt_ DEVINSTID_W pDeviceID,
4290  _Out_writes_(BufferLen) PWCHAR Buffer,
4291  _In_ ULONG BufferLen,
4292  _In_ ULONG ulFlags)
4293 {
4294  TRACE("CM_Get_Device_Interface_ListW(%s %s %p %lu 0x%08lx)\n",
4296  Buffer, BufferLen, ulFlags);
4297 
4299  Buffer, BufferLen, ulFlags, NULL);
4300 }
4301 
4302 
4303 /***********************************************************************
4304  * CM_Get_Device_Interface_List_ExA (SETUPAPI.@)
4305  */
4306 CONFIGRET
4307 WINAPI
4310  _In_opt_ DEVINSTID_A pDeviceID,
4311  _Out_writes_(BufferLen) PCHAR Buffer,
4312  _In_ ULONG BufferLen,
4313  _In_ ULONG ulFlags,
4314  _In_opt_ HMACHINE hMachine)
4315 {
4316  DEVINSTID_W pDeviceIdW = NULL;
4317  PWCHAR BufferW = NULL;
4319 
4320  TRACE("CM_Get_Device_Interface_List_ExA(%s %s %p %lu 0x%08lx %p)\n",
4322  Buffer, BufferLen, ulFlags, hMachine);
4323 
4324  if (Buffer == NULL ||
4325  BufferLen == 0)
4326  return CR_INVALID_POINTER;
4327 
4328  if (pDeviceID != NULL)
4329  {
4330  if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4331  return CR_INVALID_DEVICE_ID;
4332  }
4333 
4334  BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
4335  if (BufferW == NULL)
4336  {
4338  goto Done;
4339  }
4340 
4342  BufferW, BufferLen, ulFlags,
4343  hMachine);
4344  if (ret != CR_SUCCESS)
4345  goto Done;
4346 
4348  0,
4349  BufferW,
4350  BufferLen,
4351  Buffer,
4352  BufferLen,
4353  NULL,
4354  NULL) == 0)
4355  ret = CR_FAILURE;
4356 
4357 Done:
4358  if (BufferW != NULL)
4359  MyFree(BufferW);
4360 
4361  if (pDeviceIdW != NULL)
4362  MyFree(pDeviceIdW);
4363 
4364  return ret;
4365 }
4366 
4367 
4368 /***********************************************************************
4369  * CM_Get_Device_Interface_List_ExW (SETUPAPI.@)
4370  */
4371 CONFIGRET
4372 WINAPI
4375  _In_opt_ DEVINSTID_W pDeviceID,
4376  _Out_writes_(BufferLen) PWCHAR Buffer,
4377  _In_ ULONG BufferLen,
4378  _In_ ULONG ulFlags,
4379  _In_opt_ HMACHINE hMachine)
4380 {
4384 
4385  TRACE("CM_Get_Device_Interface_List_ExW(%s %s %p %lu 0x%08lx %p)\n",
4387  Buffer, BufferLen, ulFlags, hMachine);
4388 
4389  if (Buffer == NULL ||
4390  BufferLen == 0)
4391  return CR_INVALID_POINTER;
4392 
4393  if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4394  return CR_INVALID_FLAG;
4395 
4396  if (hMachine != NULL)
4397  {
4398  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4399  if (BindingHandle == NULL)
4400  return CR_FAILURE;
4401  }
4402  else
4403  {
4405  return CR_FAILURE;
4406  }
4407 
4408  *Buffer = 0;
4409  BufferSize = BufferLen;
4410 
4411  RpcTryExcept
4412  {
4415  pDeviceID,
4416  (LPBYTE)Buffer,
4417  &BufferSize,
4418  ulFlags);
4419  }
4421  {
4423  }
4424  RpcEndExcept;
4425 
4426  return ret;
4427 }
4428 
4429 
4430 /***********************************************************************
4431  * CM_Get_Device_Interface_List_SizeA (SETUPAPI.@)
4432  */
4433 CONFIGRET
4434 WINAPI
4436  _Out_ PULONG pulLen,
4438  _In_opt_ DEVINSTID_A pDeviceID,
4439  _In_ ULONG ulFlags)
4440 {
4441  TRACE("CM_Get_Device_Interface_List_SizeA(%p %p %s 0x%08lx)\n",
4442  pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags);
4443 
4445  pDeviceID, ulFlags, NULL);
4446 }
4447 
4448 
4449 /***********************************************************************
4450  * CM_Get_Device_Interface_List_SizeW (SETUPAPI.@)
4451  */
4452 CONFIGRET
4453 WINAPI
4455  _Out_ PULONG pulLen,
4457  _In_opt_ DEVINSTID_W pDeviceID,
4458  _In_ ULONG ulFlags)
4459 {
4460  TRACE("CM_Get_Device_Interface_List_SizeW(%p %p %s 0x%08lx)\n",
4461  pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags);
4462 
4464  pDeviceID, ulFlags, NULL);
4465 }
4466 
4467 
4468 /***********************************************************************
4469  * CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@)
4470  */
4471 CONFIGRET
4472 WINAPI
4474  _Out_ PULONG pulLen,
4476  _In_opt_ DEVINSTID_A pDeviceID,
4477  _In_ ULONG ulFlags,
4478  _In_opt_ HMACHINE hMachine)
4479 {
4480  DEVINSTID_W pDeviceIdW = NULL;
4482 
4483  TRACE("CM_Get_Device_Interface_List_Size_ExA(%p %p %s 0x%08lx %p)\n",
4484  pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags, hMachine);
4485 
4486  if (pulLen == NULL)
4487  return CR_INVALID_POINTER;
4488 
4489  if (pDeviceID != NULL)
4490  {
4491  if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4492  return CR_INVALID_DEVICE_ID;
4493  }
4494 
4495  *pulLen = 0;
4496 
4498  pDeviceIdW, ulFlags, hMachine);
4499 
4500  if (pDeviceIdW != NULL)
4501  MyFree(pDeviceIdW);
4502 
4503  return ret;
4504 }
4505 
4506 
4507 /***********************************************************************
4508  * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@)
4509  */
4510 CONFIGRET
4511 WINAPI
4513  _Out_ PULONG pulLen,
4515  _In_opt_ DEVINSTID_W pDeviceID,
4516  _In_ ULONG ulFlags,
4517  _In_opt_ HMACHINE hMachine)
4518 {
4521 
4522  TRACE("CM_Get_Device_Interface_List_Size_ExW(%p %p %s 0x%08lx %p)\n",
4523  pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags, hMachine);
4524 
4525  if (pulLen == NULL)
4526  return CR_INVALID_POINTER;
4527 
4528  if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4529  return CR_INVALID_FLAG;
4530 
4531  if (hMachine != NULL)
4532  {
4533  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4534  if (BindingHandle == NULL)
4535  return CR_FAILURE;
4536  }
4537  else
4538  {
4540  return CR_FAILURE;
4541  }
4542 
4543  *pulLen = 0;
4544 
4545  RpcTryExcept
4546  {
4548  pulLen,
4550  pDeviceID,
4551  ulFlags);
4552  }
4554  {
4556  }
4557  RpcEndExcept;
4558 
4559  return ret;
4560 }
4561 
4562 
4563 /***********************************************************************
4564  * CM_Get_First_Log_Conf [SETUPAPI.@]
4565  */
4566 CONFIGRET
4567 WINAPI
4569  _Out_opt_ PLOG_CONF plcLogConf,
4570  _In_ DEVINST dnDevInst,
4571  _In_ ULONG ulFlags)
4572 {
4573  TRACE("CM_Get_First_Log_Conf(%p %lx %lx)\n",
4574  plcLogConf, dnDevInst, ulFlags);
4575 
4576  return CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, NULL);
4577 }
4578 
4579 
4580 /***********************************************************************
4581  * CM_Get_First_Log_Conf_Ex [SETUPAPI.@]
4582  */
4583 CONFIGRET
4584 WINAPI
4586  _Out_opt_ PLOG_CONF plcLogConf,
4587  _In_ DEVINST dnDevInst,
4588  _In_ ULONG ulFlags,
4589  _In_opt_ HMACHINE hMachine)
4590 {
4592  HSTRING_TABLE StringTable = NULL;
4593  LPWSTR lpDevInst = NULL;
4595  ULONG ulTag;
4596  PLOG_CONF_INFO pLogConfInfo;
4597 
4598  FIXME("CM_Get_First_Log_Conf_Ex(%p %lx %lx %p)\n",
4599  plcLogConf, dnDevInst, ulFlags, hMachine);
4600 
4601  if (dnDevInst == 0)
4602  return CR_INVALID_DEVINST;
4603 
4604  if (ulFlags & ~LOG_CONF_BITS)
4605  return CR_INVALID_FLAG;
4606 
4607  if (plcLogConf)
4608  *plcLogConf = 0;
4609 
4610  if (hMachine != NULL)
4611  {
4612  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4613  if (BindingHandle == NULL)
4614  return CR_FAILURE;
4615 
4616  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4617  if (StringTable == 0)
4618  return CR_FAILURE;
4619  }
4620  else
4621  {
4622  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
4623  return CR_FAILURE;
4624  }
4625 
4626  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
4627  if (lpDevInst == NULL)
4628  return CR_INVALID_DEVNODE;
4629 
4630  RpcTryExcept
4631  {
4633  lpDevInst,
4634  ulFlags,
4635  &ulTag,
4636  ulFlags);
4637  }
4639  {
4641  }
4642  RpcEndExcept;
4643 
4644  if (ret != CR_SUCCESS)
4645  return ret;
4646 
4647  if (plcLogConf)
4648  {
4649  pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
4650  if (pLogConfInfo == NULL)
4651  return CR_OUT_OF_MEMORY;
4652 
4653  pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
4654  pLogConfInfo->dnDevInst = dnDevInst;
4655  pLogConfInfo->ulType = ulFlags;
4656  pLogConfInfo->ulTag = ulTag;
4657 
4658  *plcLogConf = (LOG_CONF)pLogConfInfo;
4659  }
4660 
4661  return CR_SUCCESS;
4662 }
4663 
4664 
4665 /***********************************************************************
4666  * CM_Get_Global_State [SETUPAPI.@]
4667  */
4668 CONFIGRET
4669 WINAPI
4671  _Out_ PULONG pulState,
4672  _In_ ULONG ulFlags)
4673 {
4674  TRACE("CM_Get_Global_State(%p %lx)\n",
4675  pulState, ulFlags);
4676 
4677  return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
4678 }
4679 
4680 
4681 /***********************************************************************
4682  * CM_Get_Global_State_Ex [SETUPAPI.@]
4683  */
4684 CONFIGRET
4685 WINAPI
4687  _Out_ PULONG pulState,
4688  _In_ ULONG ulFlags,
4689  _In_opt_ HMACHINE hMachine)
4690 {
4692  CONFIGRET ret;
4693 
4694  TRACE("CM_Get_Global_State_Ex(%p %lx %p)\n",
4695  pulState, ulFlags, hMachine);
4696 
4697  if (pulState == NULL)
4698  return CR_INVALID_POINTER;
4699 
4700  if (ulFlags != 0)
4701  return CR_INVALID_FLAG;
4702 
4703  if (hMachine != NULL)
4704  {
4705  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4706  if (BindingHandle == NULL)
4707  return CR_FAILURE;
4708  }
4709  else
4710  {
4712  return CR_FAILURE;
4713  }
4714 
4715  RpcTryExcept
4716  {
4717  ret = PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
4718  }
4720  {
4722  }
4723  RpcEndExcept;
4724 
4725  return ret;
4726 }
4727 
4728 
4729 /***********************************************************************
4730  * CM_Get_HW_Prof_FlagsA [SETUPAPI.@]
4731  */
4732 CONFIGRET
4733 WINAPI
4735  _In_ DEVINSTID_A szDevInstName,
4736  _In_ ULONG ulHardwareProfile,
4737  _Out_ PULONG pulValue,
4738  _In_ ULONG ulFlags)
4739 {
4740  TRACE("CM_Get_HW_Prof_FlagsA(%s %lu %p %lx)\n",
4741  debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4742 
4743  return CM_Get_HW_Prof_Flags_ExA(szDevInstName, ulHardwareProfile,
4744  pulValue, ulFlags, NULL);
4745 }
4746 
4747 
4748 /***********************************************************************
4749  * CM_Get_HW_Prof_FlagsW [SETUPAPI.@]
4750  */
4751 CONFIGRET
4752 WINAPI
4754  _In_ DEVINSTID_W szDevInstName,
4755  _In_ ULONG ulHardwareProfile,
4756  _Out_ PULONG pulValue,
4757  _In_ ULONG ulFlags)
4758 {
4759  TRACE("CM_Get_HW_Prof_FlagsW(%s %lu %p %lx)\n",
4760  debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4761 
4762  return CM_Get_HW_Prof_Flags_ExW(szDevInstName, ulHardwareProfile,
4763  pulValue, ulFlags, NULL);
4764 }
4765 
4766 
4767 /***********************************************************************
4768  * CM_Get_HW_Prof_Flags_ExA [SETUPAPI.@]
4769  */
4770 CONFIGRET
4771 WINAPI
4773  _In_ DEVINSTID_A szDevInstName,
4774  _In_ ULONG ulHardwareProfile,
4775  _Out_ PULONG pulValue,
4776  _In_ ULONG ulFlags,
4777  _In_opt_ HMACHINE hMachine)
4778 {
4779  DEVINSTID_W pszDevIdW = NULL;
4781 
4782  TRACE("CM_Get_HW_Prof_Flags_ExA(%s %lu %p %lx %p)\n",
4783  debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4784 
4785  if (szDevInstName != NULL)
4786  {
4787  if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
4788  return CR_INVALID_DEVICE_ID;
4789  }
4790 
4791  ret = CM_Get_HW_Prof_Flags_ExW(pszDevIdW, ulHardwareProfile,
4792  pulValue, ulFlags, hMachine);
4793 
4794  if (pszDevIdW != NULL)
4795  MyFree(pszDevIdW);
4796 
4797  return ret;
4798 }
4799 
4800 
4801 /***********************************************************************
4802  * CM_Get_HW_Prof_Flags_ExW [SETUPAPI.@]
4803  */
4804 CONFIGRET
4805 WINAPI
4807  _In_ DEVINSTID_W szDevInstName,
4808  _In_ ULONG ulHardwareProfile,
4809  _Out_ PULONG pulValue,
4810  _In_ ULONG ulFlags,
4811  _In_opt_ HMACHINE hMachine)
4812 {
4814  CONFIGRET ret;
4815 
4816  FIXME("CM_Get_HW_Prof_Flags_ExW(%s %lu %p %lx %p)\n",
4817  debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4818 
4819  if ((szDevInstName == NULL) || (pulValue == NULL))
4820  return CR_INVALID_POINTER;
4821 
4822  if (ulFlags != 0)
4823  return CR_INVALID_FLAG;
4824 
4825  /* FIXME: Check whether szDevInstName is valid */
4826 
4827  if (hMachine != NULL)
4828  {
4829  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4830  if (BindingHandle == NULL)
4831  return CR_FAILURE;
4832  }
4833  else
4834  {
4836  return CR_FAILURE;
4837  }
4838 
4839  RpcTryExcept
4840  {
4841  ret = PNP_HwProfFlags(BindingHandle, PNP_GET_HWPROFFLAGS, szDevInstName,
4842  ulHardwareProfile, pulValue, NULL, NULL, 0, 0);
4843  }
4845  {
4847  }
4848  RpcEndExcept;
4849 
4850  return ret;
4851 }
4852 
4853 
4854 /***********************************************************************
4855  * CM_Get_Hardware_Profile_InfoA [SETUPAPI.@]
4856  */
4857 CONFIGRET
4858 WINAPI
4860  _In_ ULONG ulIndex,
4861  _Out_ PHWPROFILEINFO_A pHWProfileInfo,
4862  _In_ ULONG ulFlags)
4863 {
4864  TRACE("CM_Get_Hardware_Profile_InfoA(%lu %p %lx)\n",
4865  ulIndex, pHWProfileInfo, ulFlags);
4866 
4867  return CM_Get_Hardware_Profile_Info_ExA(ulIndex, pHWProfileInfo,
4868  ulFlags, NULL);
4869 }
4870 
4871 
4872 /***********************************************************************
4873  * CM_Get_Hardware_Profile_InfoW [SETUPAPI.@]
4874  */
4875 CONFIGRET
4876 WINAPI
4878  _In_ ULONG ulIndex,
4879  _Out_ PHWPROFILEINFO_W pHWProfileInfo,
4880  _In_ ULONG ulFlags)
4881 {
4882  TRACE("CM_Get_Hardware_Profile_InfoW(%lu %p %lx)\n",
4883  ulIndex, pHWProfileInfo, ulFlags);
4884 
4885  return CM_Get_Hardware_Profile_Info_ExW(ulIndex, pHWProfileInfo,
4886  ulFlags, NULL);
4887 }
4888 
4889 
4890 /***********************************************************************
4891  * CM_Get_Hardware_Profile_Info_ExA [SETUPAPI.@]
4892  */
4893 CONFIGRET
4894 WINAPI
4896  _In_ ULONG ulIndex,
4897  _Out_ PHWPROFILEINFO_A pHWProfileInfo,
4898  _In_ ULONG ulFlags,
4899  _In_opt_ HMACHINE hMachine)
4900 {
4901  HWPROFILEINFO_W LocalProfileInfo;
4902  CONFIGRET ret;
4903 
4904  TRACE("CM_Get_Hardware_Profile_Info_ExA(%lu %p %lx %p)\n",
4905  ulIndex, pHWProfileInfo, ulFlags, hMachine);
4906 
4907  if (pHWProfileInfo == NULL)
4908  return CR_INVALID_POINTER;
4909 
4910  ret = CM_Get_Hardware_Profile_Info_ExW(ulIndex, &LocalProfileInfo,
4911  ulFlags, hMachine);
4912  if (ret == CR_SUCCESS)
4913  {
4914  pHWProfileInfo->HWPI_ulHWProfile = LocalProfileInfo.HWPI_ulHWProfile;
4915  pHWProfileInfo->HWPI_dwFlags = LocalProfileInfo.HWPI_dwFlags;
4916 
4918  0,
4919  LocalProfileInfo.HWPI_szFriendlyName,
4920  lstrlenW(LocalProfileInfo.HWPI_szFriendlyName) + 1,
4921  pHWProfileInfo->HWPI_szFriendlyName,
4923  NULL,
4924  NULL) == 0)
4925  ret = CR_FAILURE;
4926  }
4927 
4928  return ret;
4929 }
4930 
4931 
4932 /***********************************************************************
4933  * CM_Get_Hardware_Profile_Info_ExW [SETUPAPI.@]
4934  */
4935 CONFIGRET
4936 WINAPI
4938  _In_ ULONG ulIndex,
4939  _Out_ PHWPROFILEINFO_W pHWProfileInfo,
4940  _In_ ULONG ulFlags,
4941  _In_opt_ HMACHINE hMachine)
4942 {
4944  CONFIGRET ret;
4945 
4946  TRACE("CM_Get_Hardware_Profile_Info_ExW(%lu %p %lx %p)\n",
4947  ulIndex, pHWProfileInfo, ulFlags, hMachine);
4948 
4949  if (pHWProfileInfo == NULL)
4950  return CR_INVALID_POINTER;
4951 
4952  if (ulFlags != 0)
4953  return CR_INVALID_FLAG;
4954 
4955  if (hMachine != NULL)
4956  {
4957  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4958  if (BindingHandle == NULL)
4959  return CR_FAILURE;
4960  }
4961  else
4962  {
4964  return CR_FAILURE;
4965  }
4966 
4967  RpcTryExcept
4968  {
4969  ret = PNP_GetHwProfInfo(BindingHandle, ulIndex, pHWProfileInfo,
4970  sizeof(HWPROFILEINFO_W), 0);
4971  }
4973  {
4975  }
4976  RpcEndExcept;
4977 
4978  return ret;
4979 }
4980 
4981 
4982 /***********************************************************************
4983  * CM_Get_Log_Conf_Priority [SETUPAPI.@]
4984  */
4985 CONFIGRET
4986 WINAPI
4988  _In_ LOG_CONF lcLogConf,
4989  _Out_ PPRIORITY pPriority,
4990  _In_ ULONG ulFlags)
4991 {
4992  TRACE("CM_Get_Log_Conf_Priority(%p %p %lx)\n",
4993  lcLogConf, pPriority, ulFlags);
4994 
4995  return CM_Get_Log_Conf_Priority_Ex(lcLogConf, pPriority, ulFlags, NULL);
4996 }
4997 
4998 
4999 /***********************************************************************
5000  * CM_Get_Log_Conf_Priority_Ex [SETUPAPI.@]
5001  */
5002 CONFIGRET
5003 WINAPI
5005  _In_ LOG_CONF lcLogConf,
5006  _Out_ PPRIORITY pPriority,
5007  _In_ ULONG ulFlags,
5008  _In_opt_ HMACHINE hMachine)
5009 {
5011  HSTRING_TABLE StringTable = NULL;
5012  PLOG_CONF_INFO pLogConfInfo;
5013  LPWSTR lpDevInst;
5014  CONFIGRET ret;
5015 
5016  FIXME("CM_Get_Log_Conf_Priority_Ex(%p %p %lx %p)\n",
5017  lcLogConf, pPriority, ulFlags, hMachine);
5018 
5019  pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
5020  if (!IsValidLogConf(pLogConfInfo))
5021  return CR_INVALID_LOG_CONF;
5022 
5023  if (pPriority == NULL)
5024  return CR_INVALID_POINTER;
5025 
5026  if (ulFlags != 0)
5027  return CR_INVALID_FLAG;
5028 
5029  if (hMachine != NULL)
5030  {
5031  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5032  if (BindingHandle == NULL)
5033  return CR_FAILURE;
5034 
5035  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5036  if (StringTable == 0)
5037  return CR_FAILURE;
5038  }
5039  else
5040  {
5041  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5042  return CR_FAILURE;
5043  }
5044 
5045  lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
5046  if (lpDevInst == NULL)
5047  return CR_INVALID_DEVNODE;
5048 
5049  RpcTryExcept
5050  {
5052  lpDevInst,
5053  pLogConfInfo->ulType,
5054  pLogConfInfo->ulTag,
5055  pPriority,
5056  0);
5057  }
5059  {
5061  }
5062  RpcEndExcept;
5063 
5064  return ret;
5065 }
5066 
5067 
5068 /***********************************************************************
5069  * CM_Get_Next_Log_Conf [SETUPAPI.@]
5070  */
5071 CONFIGRET
5072 WINAPI
5074  _Out_opt_ PLOG_CONF plcLogConf,
5075  _In_ LOG_CONF lcLogConf,
5076  _In_ ULONG ulFlags)
5077 {
5078  TRACE("CM_Get_Next_Log_Conf(%p %p %lx)\n",
5079  plcLogConf, lcLogConf, ulFlags);
5080 
5081  return CM_Get_Next_Log_Conf_Ex(plcLogConf, lcLogConf, ulFlags, NULL);
5082 }
5083 
5084 
5085 /***********************************************************************
5086  * CM_Get_Next_Log_Conf_Ex [SETUPAPI.@]
5087  */
5088 CONFIGRET
5089 WINAPI
5091  _Out_opt_ PLOG_CONF plcLogConf,
5092  _In_ LOG_CONF lcLogConf,
5093  _In_ ULONG ulFlags,
5094  _In_opt_ HMACHINE hMachine)
5095 {
5097  HSTRING_TABLE StringTable = NULL;
5098  PLOG_CONF_INFO pLogConfInfo;
5099  PLOG_CONF_INFO pNewLogConfInfo;
5100  ULONG ulNewTag;
5101  LPWSTR lpDevInst;
5102  CONFIGRET ret;
5103 
5104  FIXME("CM_Get_Next_Log_Conf_Ex(%p %p %lx %p)\n",
5105  plcLogConf, lcLogConf, ulFlags, hMachine);
5106 
5107  if (plcLogConf)
5108  *plcLogConf = 0;
5109 
5110  pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
5111  if (!IsValidLogConf(pLogConfInfo))
5112  return CR_INVALID_LOG_CONF;
5113 
5114  if (ulFlags != 0)
5115  return CR_INVALID_FLAG;
5116 
5117  if (hMachine != NULL)
5118  {
5119  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5120  if (BindingHandle == NULL)
5121  return CR_FAILURE;
5122 
5123  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5124  if (StringTable == 0)
5125  return CR_FAILURE;
5126  }
5127  else
5128  {
5129  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5130  return CR_FAILURE;
5131  }
5132 
5133  lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
5134  if (lpDevInst == NULL)
5135  return CR_INVALID_DEVNODE;
5136 
5137  RpcTryExcept
5138  {
5140  lpDevInst,
5141  pLogConfInfo->ulType,
5142  pLogConfInfo->ulTag,
5143  &ulNewTag,
5144  0);
5145  }
5147  {
5149  }
5150  RpcEndExcept;
5151 
5152  if (ret != CR_SUCCESS)
5153  return ret;
5154 
5155  if (plcLogConf)
5156  {
5157  pNewLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
5158  if (pNewLogConfInfo == NULL)
5159  return CR_OUT_OF_MEMORY;
5160 
5161  pNewLogConfInfo->ulMagic = LOG_CONF_MAGIC;
5162  pNewLogConfInfo->dnDevInst = pLogConfInfo->dnDevInst;
5163  pNewLogConfInfo->ulType = pLogConfInfo->ulType;
5164  pNewLogConfInfo->ulTag = ulNewTag;
5165 
5166  *plcLogConf = (LOG_CONF)pNewLogConfInfo;
5167  }
5168 
5169  return CR_SUCCESS;
5170 }
5171 
5172 
5173 /***********************************************************************
5174  * CM_Get_Next_Re_Des [SETUPAPI.@]
5175  */
5176 CONFIGRET
5177 WINAPI
5179  _Out_ PRES_DES prdResDes,
5180  _In_ RES_DES rdResDes,
5181  _In_ RESOURCEID ForResource,
5182  _Out_opt_ PRESOURCEID pResourceID,
5183  _In_ ULONG ulFlags)
5184 {
5185  TRACE("CM_Get_Next_Res_Des(%p %p %lu %p %lx)\n",
5186  prdResDes, rdResDes, ForResource, pResourceID, ulFlags);
5187 
5188  return CM_Get_Next_Res_Des_Ex(prdResDes, rdResDes, ForResource,
5189  pResourceID, ulFlags, NULL);
5190 }
5191 
5192 
5193 /***********************************************************************
5194  * CM_Get_Next_Re_Des_Ex [SETUPAPI.@]
5195  */
5196 CONFIGRET
5197 WINAPI
5199  _Out_ PRES_DES prdResDes,
5200  _In_ RES_DES rdResDes,
5201  _In_ RESOURCEID ForResource,
5202  _Out_opt_ PRESOURCEID pResourceID,
5203  _In_ ULONG ulFlags,
5204  _In_opt_ HMACHINE hMachine)
5205 {
5207  HSTRING_TABLE StringTable = NULL;
5208  ULONG ulInTag, ulOutTag = 0;
5209  ULONG ulInType, ulOutType = 0;
5210  LPWSTR lpDevInst;
5211  DEVINST dnDevInst;
5212  CONFIGRET ret;
5213 
5214  FIXME("CM_Get_Next_Res_Des_Ex(%p %p %lu %p %lx %p)\n",
5215  prdResDes, rdResDes, ForResource, pResourceID, ulFlags, hMachine);
5216 
5217  if (prdResDes == NULL)
5218  return CR_INVALID_POINTER;
5219 
5220  if (IsValidLogConf((PLOG_CONF_INFO)rdResDes))
5221  {
5222  FIXME("LogConf found!\n");
5223  dnDevInst = ((PLOG_CONF_INFO)rdResDes)->dnDevInst;
5224  ulInTag = ((PLOG_CONF_INFO)rdResDes)->ulTag;
5225  ulInType = ((PLOG_CONF_INFO)rdResDes)->ulType;
5226  }
5227 #if 0
5228  else if (IsValidResDes((PRES_DES_INFO)rdResDes))
5229  {
5230  FIXME("ResDes found!\n");
5231  dnDevInst = ((PRES_DES_INFO)rdResDes)->dnDevInst;
5232  ulInTag = ((PRES_DES_INFO)rdResDes)->ulTag;
5233  ulInType = ((PRES_DES_INFO)rdResDes)->ulType;
5234  }
5235 #endif
5236  else
5237  {
5238  return CR_INVALID_RES_DES;
5239  }
5240 
5241  if (hMachine != NULL)
5242  {
5243  BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5244  if (BindingHandle == NULL)
5245  return CR_FAILURE;
5246 
5247  StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5248  if (StringTable == 0)
5249  return CR_FAILURE;
5250  }
5251  else
5252  {
5253  if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5254  return CR_FAILURE;
5255  }
5256 
5257  lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
5258  if (lpDevInst == NULL)
5259  return CR_INVALID_DEVNODE;
5260 
5261  RpcTryExcept
5262  {
5264  lpDevInst,
5265  ulInTag,
5266  ulInType,
5267  ForResource,
5268  0, /* unsigned long ulResourceTag, */
5269  &ulOutTag,
5270  &ulOutType,
5271  0);
5272  }
5274  {
5276  }
5277  RpcEndExcept;
5278 
5279  if (ret != CR_SUCCESS)
5280  return ret;
5281 
5282  /* FIXME: Create the ResDes handle */
5283 
5284  return CR_SUCCESS;
5285 }
5286 
5287 
5288 /***********************************************************************
5289  * CM_Get_Parent [SETUPAPI.@]
5290  */
5291 CONFIGRET
5292 WINAPI
5294  _Out_ PDEVINST pdnDevInst,