ReactOS 0.4.16-dev-570-g1868985
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
35 OUT LPWSTR lpServiceName,
36 IN DWORD cchServiceName);
37
38
39/* Registry key and value names */
40static const WCHAR BackslashOpenBrace[] = {'\\', '{', 0};
41static const WCHAR CloseBrace[] = {'}', 0};
42static const WCHAR Class[] = {'C','l','a','s','s',0};
43
44static 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
49static 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
54typedef struct _MACHINE_INFO
55{
61
62
63typedef struct _LOG_CONF_INFO
64{
70
71#define LOG_CONF_MAGIC 0x464E434C /* "LCNF" */
72
73typedef struct _RES_DES_INFO
74{
82
83#define RES_DES_MAGIC 0x53445352 /* "RSDS" */
84
85typedef struct _NOTIFY_DATA
86{
90
91#define NOTIFY_MAGIC 0x44556677
92
93
94typedef struct _INTERNAL_RANGE
95{
101
103{
108
109#define RANGE_LIST_MAGIC 0x33445566
110
111typedef struct _CONFLICT_DATA
112{
116
117#define CONFLICT_MAGIC 0x11225588
118
119
120/* FUNCTIONS ****************************************************************/
121
122static
123BOOL
127{
128 LPWSTR lpString;
129
130 if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
131 return FALSE;
132
133 lstrcpyW(&String[1], lpString);
134
135 String[0] = '{';
136 String[MAX_GUID_STRING_LEN - 2] = '}';
138
139 RpcStringFreeW(&lpString);
140
141 return TRUE;
142}
143
144
145static
149{
150 return CR_FAILURE;
151}
152
153
154static
155ULONG
157 _In_ ULONG ulProperty)
158{
159 switch (ulProperty)
160 {
162 case CM_DRP_SERVICE:
163 case CM_DRP_CLASS:
164 case CM_DRP_CLASSGUID:
165 case CM_DRP_DRIVER:
166 case CM_DRP_MFG:
173 return REG_SZ;
174
179 return REG_MULTI_SZ;
180
183 case CM_DRP_UI_NUMBER:
185 case CM_DRP_BUSNUMBER:
186 case CM_DRP_DEVTYPE:
187 case CM_DRP_EXCLUSIVE:
189 case CM_DRP_ADDRESS:
194 return REG_DWORD;
195
197 case CM_DRP_SECURITY:
199 default:
200 return REG_BINARY;
201 }
202
203 return REG_NONE;
204}
205
206
207static
208VOID
210 _In_ PWSTR pszDeviceInstanceId,
211 _Out_ PWSTR pszDeviceId,
212 _Out_ PWSTR pszInstanceId)
213{
214 PWCHAR ptr;
215
216 wcscpy(pszDeviceId, pszDeviceInstanceId);
217
218 ptr = wcschr(pszDeviceId, L'\\');
219 if (ptr != NULL)
220 {
221 *ptr = UNICODE_NULL;
222 ptr++;
223
224 wcscpy(pszInstanceId, ptr);
225 }
226 else
227 {
228 *pszInstanceId = UNICODE_NULL;
229 }
230}
231
232
233static
237 _In_ PWSTR pszDeviceInst,
238 _Out_ PWSTR pszKeyPath,
239 _Out_ PWSTR pszInstancePath,
240 _In_ ULONG ulHardwareProfile,
241 _In_ ULONG ulFlags)
242{
243 PWSTR pszBuffer = NULL;
244 ULONG ulType = 0;
245 ULONG ulTransferLength, ulLength;
247
248 TRACE("GetDeviceInstanceKeyPath()\n");
249
250 /* Allocate a buffer for the device id */
251 pszBuffer = MyMalloc(300 * sizeof(WCHAR));
252 if (pszBuffer == NULL)
253 {
254 ERR("MyMalloc() failed\n");
255 return CR_OUT_OF_MEMORY;
256 }
257
258 if (ulFlags & CM_REGISTRY_SOFTWARE)
259 {
260 /* Software Key Path */
261
262 ulTransferLength = 300 * sizeof(WCHAR);
263 ulLength = 300 * sizeof(WCHAR);
264
266 {
268 pszDeviceInst,
270 &ulType,
271 (PVOID)pszBuffer,
272 &ulTransferLength,
273 &ulLength,
274 0);
275 }
277 {
279 }
281
282 if (ret != CR_SUCCESS)
283 {
285 {
287 pszDeviceInst,
288 (PVOID)pszBuffer,
289 300);
290 }
292 {
294 }
296
297 if (ret != CR_SUCCESS)
298 {
299 goto done;
300 }
301 }
302
303 TRACE("szBuffer: %S\n", pszBuffer);
304
305 SplitDeviceInstanceId(pszBuffer,
306 pszBuffer,
307 pszInstancePath);
308
309 TRACE("szBuffer: %S\n", pszBuffer);
310
311 if (ulFlags & CM_REGISTRY_CONFIG)
312 {
313 if (ulHardwareProfile == 0)
314 {
315 wsprintfW(pszKeyPath,
316 L"%s\\%s\\%s\\%s",
317 L"System\\CurrentControlSet\\Hardware Profiles",
318 L"Current",
319 L"System\\CurrentControlSet\\Control\\Class",
320 pszBuffer);
321 }
322 else
323 {
324 wsprintfW(pszKeyPath,
325 L"%s\\%04lu\\%s\\%s",
326 L"System\\CurrentControlSet\\Hardware Profiles",
327 ulHardwareProfile,
328 L"System\\CurrentControlSet\\Control\\Class",
329 pszBuffer);
330 }
331 }
332 else
333 {
334 wsprintfW(pszKeyPath,
335 L"%s\\%s",
336 L"System\\CurrentControlSet\\Control\\Class",
337 pszBuffer);
338 }
339 }
340 else
341 {
342 /* Hardware Key Path */
343
344 if (ulFlags & CM_REGISTRY_CONFIG)
345 {
346 SplitDeviceInstanceId(pszDeviceInst,
347 pszBuffer,
348 pszInstancePath);
349
350 if (ulHardwareProfile == 0)
351 {
352 wsprintfW(pszKeyPath,
353 L"%s\\%s\\%s\\%s",
354 L"System\\CurrentControlSet\\Hardware Profiles",
355 L"Current",
356 L"System\\CurrentControlSet\\Enum",
357 pszBuffer);
358 }
359 else
360 {
361 wsprintfW(pszKeyPath,
362 L"%s\\%04lu\\%s\\%s",
363 L"System\\CurrentControlSet\\Hardware Profiles",
364 ulHardwareProfile,
365 L"System\\CurrentControlSet\\Enum",
366 pszBuffer);
367 }
368 }
369 else if (ulFlags & CM_REGISTRY_USER)
370 {
371 wsprintfW(pszKeyPath,
372 L"%s\\%s",
373 L"System\\CurrentControlSet\\Enum",
374 pszDeviceInst);
375
376 wcscpy(pszInstancePath,
377 L"Device Parameters");
378 }
379 else
380 {
381 SplitDeviceInstanceId(pszDeviceInst,
382 pszBuffer,
383 pszInstancePath);
384
385 wsprintfW(pszKeyPath,
386 L"%s\\%s",
387 L"System\\CurrentControlSet\\Enum",
388 pszBuffer);
389 }
390 }
391
392done:
393 if (pszBuffer != NULL)
394 MyFree(pszBuffer);
395
396 return ret;
397}
398
399
400BOOL
403{
404 BOOL bValid = TRUE;
405
406 if (pRangeList == NULL)
407 return FALSE;
408
410 {
411 if (pRangeList->ulMagic != RANGE_LIST_MAGIC)
412 bValid = FALSE;
413 }
415 {
416 bValid = FALSE;
417 }
418 _SEH2_END;
419
420 return bValid;
421}
422
423
424BOOL
426 _In_opt_ PLOG_CONF_INFO pLogConfInfo)
427{
428 BOOL bValid = TRUE;
429
430 if (pLogConfInfo == NULL)
431 return FALSE;
432
434 {
435 if (pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
436 bValid = FALSE;
437 }
439 {
440 bValid = FALSE;
441 }
442 _SEH2_END;
443
444 return bValid;
445}
446
447
448BOOL
450 _In_opt_ PRES_DES_INFO pResDesInfo)
451{
452 BOOL bValid = TRUE;
453
454 if (pResDesInfo == NULL)
455 return FALSE;
456
458 {
459 if (pResDesInfo->ulMagic != RES_DES_MAGIC)
460 bValid = FALSE;
461 }
463 {
464 bValid = FALSE;
465 }
466 _SEH2_END;
467
468 return bValid;
469}
470
471
472BOOL
474 _In_opt_ PCONFLICT_DATA pConflictData)
475{
476 BOOL bValid = TRUE;
477
478 if (pConflictData == NULL)
479 return FALSE;
480
482 {
483 if (pConflictData->ulMagic != CONFLICT_MAGIC)
484 bValid = FALSE;
485 }
487 {
488 bValid = FALSE;
489 }
490 _SEH2_END;
491
492 return bValid;
493}
494
495
496/***********************************************************************
497 * CMP_GetBlockedDriverInfo [SETUPAPI.@]
498 */
500WINAPI
502 _Out_opt_ LPWSTR pszNames,
503 _Inout_ PULONG pulLength,
504 _In_ ULONG ulFlags,
505 _In_opt_ HMACHINE hMachine)
506{
508 ULONG ulTransferLength;
510
511 TRACE("CMP_GetBlockedDriverInfo(%p %p %lx %p)\n",
512 pszNames, pulLength, ulFlags, hMachine);
513
514 if (hMachine != NULL)
515 {
516 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
517 if (BindingHandle == NULL)
518 return CR_FAILURE;
519 }
520 else
521 {
523 return CR_FAILURE;
524 }
525
526 ulTransferLength = *pulLength;
527
529 {
531 (PBYTE)pszNames,
532 &ulTransferLength,
533 pulLength,
534 ulFlags);
535 }
537 {
539 }
541
542 return ret;
543}
544
545
546/***********************************************************************
547 * CMP_GetServerSideDeviceInstallFlags [SETUPAPI.@]
548 */
550WINAPI
552 _Out_ PULONG pulSSDIFlags,
553 _In_ ULONG ulFlags,
554 _In_opt_ HMACHINE hMachine)
555{
558
559 TRACE("CMP_GetServerSideDeviceInstallFlags(%p %lx %p)\n",
560 pulSSDIFlags, ulFlags, hMachine);
561
562 if (pulSSDIFlags == NULL)
563 return CR_INVALID_POINTER;
564
565 if (ulFlags != 0)
566 return CR_INVALID_FLAG;
567
568 if (hMachine != NULL)
569 {
570 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
571 if (BindingHandle == NULL)
572 return CR_FAILURE;
573 }
574 else
575 {
577 return CR_FAILURE;
578 }
579
581 {
583 pulSSDIFlags,
584 ulFlags);
585 }
587 {
589 }
591
592 return ret;
593}
594
595
596/***********************************************************************
597 * CMP_Init_Detection [SETUPAPI.@]
598 */
600WINAPI
602 _In_ ULONG ulMagic)
603{
606
607 TRACE("CMP_Init_Detection(%lu)\n", ulMagic);
608
609 if (ulMagic != CMP_MAGIC)
610 return CR_INVALID_DATA;
611
613 return CR_FAILURE;
614
616 {
618 }
620 {
622 }
624
625 return ret;
626}
627
628
629/***********************************************************************
630 * CMP_RegisterNotification [SETUPAPI.@]
631 */
633WINAPI
635 _In_ HANDLE hRecipient,
636 _In_ LPVOID lpvNotificationFilter,
637 _In_ ULONG ulFlags,
638 _Out_ PHDEVNOTIFY phDevNotify)
639{
641 PNOTIFY_DATA pNotifyData;
642 WCHAR szNameBuffer[256];
643 INT nLength;
644 DWORD ulUnknown9 = 0;
645 DWORD dwError;
647
648 FIXME("CMP_RegisterNotification(%p %p %lu %p)\n",
649 hRecipient, lpvNotificationFilter, ulFlags, phDevNotify);
650
651 if ((hRecipient == NULL) ||
652 (lpvNotificationFilter == NULL) ||
653 (phDevNotify == NULL))
654 return CR_INVALID_POINTER;
655
656 if (ulFlags & ~0x7)
657 return CR_INVALID_FLAG;
658
659 if (((PDEV_BROADCAST_HDR)lpvNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR))
660 return CR_INVALID_DATA;
661
663 return CR_FAILURE;
664
665 pNotifyData = HeapAlloc(GetProcessHeap(),
667 sizeof(NOTIFY_DATA));
668 if (pNotifyData == NULL)
669 return CR_OUT_OF_MEMORY;
670
671 pNotifyData->ulMagic = NOTIFY_MAGIC;
672 pNotifyData->hNotifyHandle = NULL;
673
674 ZeroMemory(szNameBuffer, sizeof(szNameBuffer));
675
676 if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
677 {
678 FIXME("Register a window\n");
679
680 nLength = GetWindowTextW((HWND)hRecipient,
681 szNameBuffer,
682 ARRAYSIZE(szNameBuffer));
683 if (nLength == 0)
684 {
685 szNameBuffer[0] = UNICODE_NULL;
686 }
687
688 FIXME("Register window: %S\n", szNameBuffer);
689 }
690 else if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_SERVICE_HANDLE)
691 {
692 FIXME("Register a service\n");
693
694 dwError = I_ScPnPGetServiceName((SERVICE_STATUS_HANDLE)hRecipient,
695 szNameBuffer,
696 ARRAYSIZE(szNameBuffer));
697 if (dwError != ERROR_SUCCESS)
698 {
699 HeapFree(GetProcessHeap(), 0, pNotifyData);
700 return CR_INVALID_DATA;
701 }
702
703 FIXME("Register service: %S\n", szNameBuffer);
704 }
705
707 {
709 (DWORD_PTR)hRecipient,
710 szNameBuffer,
711 (BYTE*)lpvNotificationFilter,
712 ((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size,
713 ulFlags,
714 &pNotifyData->hNotifyHandle,
716 &ulUnknown9); /* ??? */
717 }
719 {
721 }
723
724 if (ret == CR_SUCCESS)
725 {
726 TRACE("hNotifyHandle: %p\n", pNotifyData->hNotifyHandle);
727 *phDevNotify = (HDEVNOTIFY)pNotifyData;
728 }
729 else
730 {
731 HeapFree(GetProcessHeap(), 0, pNotifyData);
732
733 *phDevNotify = (HDEVNOTIFY)NULL;
734 }
735
736 return ret;
737}
738
739
740/***********************************************************************
741 * CMP_Report_LogOn [SETUPAPI.@]
742 */
744WINAPI
746 _In_ DWORD dwMagic,
747 _In_ DWORD dwProcessId)
748{
751 BOOL bAdmin;
752 DWORD i;
753
754 TRACE("CMP_Report_LogOn(%lu %lu)\n", dwMagic, dwProcessId);
755
756 if (dwMagic != CMP_MAGIC)
757 return CR_INVALID_DATA;
758
760 return CR_FAILURE;
761
762 bAdmin = pSetupIsUserAdmin();
763
764 for (i = 0; i < 30; i++)
765 {
767 {
769 bAdmin,
770 dwProcessId);
771 }
773 {
775 }
777
778 if (ret == CR_SUCCESS)
779 break;
780
781 Sleep(5000);
782 }
783
784 return ret;
785}
786
787
788/***********************************************************************
789 * CMP_UnregisterNotification [SETUPAPI.@]
790 */
792WINAPI
794 _In_ HDEVNOTIFY hDevNotify)
795{
797 PNOTIFY_DATA pNotifyData;
799
800 TRACE("CMP_UnregisterNotification(%p)\n", hDevNotify);
801
802 pNotifyData = (PNOTIFY_DATA)hDevNotify;
803
804 if ((pNotifyData == NULL) ||
805 (pNotifyData->ulMagic != NOTIFY_MAGIC))
806 return CR_INVALID_POINTER;
807
809 return CR_FAILURE;
810
812 {
814 &pNotifyData->hNotifyHandle);
815 }
817 {
819 }
821
822 if (ret == CR_SUCCESS)
823 {
824 pNotifyData->hNotifyHandle = NULL;
825 HeapFree(GetProcessHeap(), 0, pNotifyData);
826 }
827
828 return ret;
829}
830
831
832/***********************************************************************
833 * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
834 */
835DWORD
836WINAPI
839{
841 DWORD ret;
842
843 TRACE("CMP_WaitNoPendingInstallEvents(%lu)\n", dwTimeout);
844
845 hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
846 if (hEvent == NULL)
847 return WAIT_FAILED;
848
851 return ret;
852}
853
854
855/***********************************************************************
856 * CMP_WaitServicesAvailable [SETUPAPI.@]
857 */
859WINAPI
861 _In_opt_ HMACHINE hMachine)
862{
866
867 TRACE("CMP_WaitServicesAvailable(%p)\n", hMachine);
868
869 if (hMachine != NULL)
870 {
871 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
872 if (BindingHandle == NULL)
873 return CR_FAILURE;
874 }
875 else
876 {
878 return CR_FAILURE;
879 }
880
882 {
884 }
886 {
888 }
890
891 return ret;
892}
893
894
895/***********************************************************************
896 * CM_Add_Empty_Log_Conf [SETUPAPI.@]
897 */
899WINAPI
901 _Out_ PLOG_CONF plcLogConf,
902 _In_ DEVINST dnDevInst,
904 _In_ ULONG ulFlags)
905{
906 TRACE("CM_Add_Empty_Log_Conf(%p %p %lu %lx)\n",
907 plcLogConf, dnDevInst, Priority, ulFlags);
908
909 return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
910 ulFlags, NULL);
911}
912
913
914/***********************************************************************
915 * CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
916 */
918WINAPI
920 _Out_ PLOG_CONF plcLogConf,
921 _In_ DEVINST dnDevInst,
923 _In_ ULONG ulFlags,
924 _In_opt_ HMACHINE hMachine)
925{
927 HSTRING_TABLE StringTable = NULL;
928 ULONG ulLogConfTag = 0;
929 LPWSTR lpDevInst;
930 PLOG_CONF_INFO pLogConfInfo;
932
933 FIXME("CM_Add_Empty_Log_Conf_Ex(%p %p %lu %lx %p)\n",
934 plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
935
936 if (!pSetupIsUserAdmin())
937 return CR_ACCESS_DENIED;
938
939 if (plcLogConf == NULL)
940 return CR_INVALID_POINTER;
941
942 if (dnDevInst == 0)
943 return CR_INVALID_DEVINST;
944
945 if (Priority > 0xFFFF)
946 return CR_INVALID_PRIORITY;
947
948 if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
949 return CR_INVALID_FLAG;
950
951 if (hMachine != NULL)
952 {
953 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
954 if (BindingHandle == NULL)
955 return CR_FAILURE;
956
957 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
958 if (StringTable == 0)
959 return CR_FAILURE;
960 }
961 else
962 {
963 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
964 return CR_FAILURE;
965 }
966
967 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
968 if (lpDevInst == NULL)
969 return CR_INVALID_DEVNODE;
970
972 {
974 &ulLogConfTag, ulFlags);
975 }
977 {
979 }
981
982 if (ret == CR_SUCCESS)
983 {
984 pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
985 if (pLogConfInfo == NULL)
986 {
988 }
989 else
990 {
991 pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
992 pLogConfInfo->dnDevInst = dnDevInst;
993 pLogConfInfo->ulType = ulFlags;
994 pLogConfInfo->ulTag = ulLogConfTag;
995
996 *plcLogConf = (LOG_CONF)pLogConfInfo;
997
998 ret = CR_SUCCESS;
999 }
1000 }
1001
1002 return ret;
1003}
1004
1005
1006/***********************************************************************
1007 * CM_Add_IDA [SETUPAPI.@]
1008 */
1010WINAPI
1012 _In_ DEVINST dnDevInst,
1013 _In_ PSTR pszID,
1014 _In_ ULONG ulFlags)
1015{
1016 TRACE("CM_Add_IDA(%p %s %lx)\n",
1017 dnDevInst, debugstr_a(pszID), ulFlags);
1018
1019 return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
1020}
1021
1022
1023/***********************************************************************
1024 * CM_Add_IDW [SETUPAPI.@]
1025 */
1027WINAPI
1029 _In_ DEVINST dnDevInst,
1030 _In_ PWSTR pszID,
1031 _In_ ULONG ulFlags)
1032{
1033 TRACE("CM_Add_IDW(%p %s %lx)\n",
1034 dnDevInst, debugstr_w(pszID), ulFlags);
1035
1036 return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
1037}
1038
1039
1040/***********************************************************************
1041 * CM_Add_ID_ExA [SETUPAPI.@]
1042 */
1044WINAPI
1046 _In_ DEVINST dnDevInst,
1047 _In_ PSTR pszID,
1048 _In_ ULONG ulFlags,
1049 _In_opt_ HMACHINE hMachine)
1050{
1051 PWSTR pszIDW;
1052 CONFIGRET ret;
1053
1054 TRACE("CM_Add_ID_ExA(%p %s %lx %p)\n",
1055 dnDevInst, debugstr_a(pszID), ulFlags, hMachine);
1056
1057 if (pSetupCaptureAndConvertAnsiArg(pszID, &pszIDW))
1058 return CR_INVALID_DATA;
1059
1060 ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);
1061
1062 MyFree(pszIDW);
1063
1064 return ret;
1065}
1066
1067
1068/***********************************************************************
1069 * CM_Add_ID_ExW [SETUPAPI.@]
1070 */
1072WINAPI
1074 _In_ DEVINST dnDevInst,
1075 _In_ PWSTR pszID,
1076 _In_ ULONG ulFlags,
1077 _In_opt_ HMACHINE hMachine)
1078{
1080 HSTRING_TABLE StringTable = NULL;
1081 LPWSTR lpDevInst;
1082 CONFIGRET ret;
1083
1084 TRACE("CM_Add_ID_ExW(%p %s %lx %p)\n",
1085 dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
1086
1087 if (!pSetupIsUserAdmin())
1088 return CR_ACCESS_DENIED;
1089
1090 if (dnDevInst == 0)
1091 return CR_INVALID_DEVINST;
1092
1093 if (pszID == NULL)
1094 return CR_INVALID_POINTER;
1095
1096 if (ulFlags & ~CM_ADD_ID_BITS)
1097 return CR_INVALID_FLAG;
1098
1099 if (hMachine != NULL)
1100 {
1101 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1102 if (BindingHandle == NULL)
1103 return CR_FAILURE;
1104
1105 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1106 if (StringTable == 0)
1107 return CR_FAILURE;
1108 }
1109 else
1110 {
1111 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1112 return CR_FAILURE;
1113 }
1114
1115 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1116 if (lpDevInst == NULL)
1117 return CR_INVALID_DEVNODE;
1118
1120 {
1122 lpDevInst,
1123 pszID,
1124 ulFlags);
1125 }
1127 {
1129 }
1131
1132 return ret;
1133}
1134
1135
1136/***********************************************************************
1137 * CM_Add_Range [SETUPAPI.@]
1138 */
1140WINAPI
1142 _In_ DWORDLONG ullStartValue,
1143 _In_ DWORDLONG ullEndValue,
1144 _In_ RANGE_LIST rlh,
1145 _In_ ULONG ulFlags)
1146{
1147 PINTERNAL_RANGE_LIST pRangeList;
1148 PINTERNAL_RANGE pRange;
1150
1151 FIXME("CM_Add_Range(%I64u %I64u %p %lx)\n",
1152 ullStartValue, ullEndValue, rlh, ulFlags);
1153
1154 pRangeList = (PINTERNAL_RANGE_LIST)rlh;
1155
1156 if (!IsValidRangeList(pRangeList))
1157 return CR_INVALID_RANGE_LIST;
1158
1159 if (ulFlags & ~CM_ADD_RANGE_BITS)
1160 return CR_INVALID_FLAG;
1161
1162 if (ullEndValue < ullStartValue)
1163 return CR_INVALID_RANGE;
1164
1165 /* Lock the range list */
1166 WaitForSingleObject(pRangeList->hMutex, INFINITE);
1167
1168 /* Allocate the new range */
1169 pRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
1170 if (pRange == NULL)
1171 {
1173 goto done;
1174 }
1175
1176 pRange->pRangeList = pRangeList;
1177 pRange->ullStart = ullStartValue;
1178 pRange->ullEnd = ullEndValue;
1179
1180 /* Insert the range */
1181 if (IsListEmpty(&pRangeList->ListHead))
1182 {
1183 InsertTailList(&pRangeList->ListHead, &pRange->ListEntry);
1184 }
1185 else
1186 {
1187 HeapFree(GetProcessHeap(), 0, pRange);
1189 }
1190
1191done:
1192 /* Unlock the range list */
1193 ReleaseMutex(pRangeList->hMutex);
1194
1195 return ret;
1196}
1197
1198
1199/***********************************************************************
1200 * CM_Add_Res_Des [SETUPAPI.@]
1201 */
1203WINAPI
1205 _Out_opt_ PRES_DES prdResDes,
1206 _In_ LOG_CONF lcLogConf,
1207 _In_ RESOURCEID ResourceID,
1208 _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1209 _In_ ULONG ResourceLen,
1210 _In_ ULONG ulFlags)
1211{
1212 TRACE("CM_Add_Res_Des(%p %p %lu %p %lu %lx)\n",
1213 prdResDes, lcLogConf, ResourceID, ResourceData, ResourceLen, ulFlags);
1214
1215 return CM_Add_Res_Des_Ex(prdResDes, lcLogConf, ResourceID, ResourceData,
1216 ResourceLen, ulFlags, NULL);
1217}
1218
1219
1220/***********************************************************************
1221 * CM_Add_Res_Des_Ex [SETUPAPI.@]
1222 */
1224WINAPI
1226 _Out_opt_ PRES_DES prdResDes,
1227 _In_ LOG_CONF lcLogConf,
1228 _In_ RESOURCEID ResourceID,
1229 _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1230 _In_ ULONG ResourceLen,
1231 _In_ ULONG ulFlags,
1232 _In_opt_ HMACHINE hMachine)
1233{
1234 FIXME("CM_Add_Res_Des_Ex(%p %p %lu %p %lu %lx %p)\n",
1235 prdResDes, lcLogConf, ResourceID,
1236 ResourceData, ResourceLen, ulFlags, hMachine);
1237
1239}
1240
1241
1242/***********************************************************************
1243 * CM_Connect_MachineA [SETUPAPI.@]
1244 */
1246WINAPI
1248 _In_opt_ PCSTR UNCServerName,
1249 _Out_ PHMACHINE phMachine)
1250{
1251 PWSTR pServerNameW;
1252 CONFIGRET ret;
1253
1254 TRACE("CM_Connect_MachineA(%s %p)\n",
1255 debugstr_a(UNCServerName), phMachine);
1256
1257 if (UNCServerName == NULL || *UNCServerName == 0)
1258 return CM_Connect_MachineW(NULL, phMachine);
1259
1260 if (pSetupCaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
1261 return CR_INVALID_DATA;
1262
1263 ret = CM_Connect_MachineW(pServerNameW, phMachine);
1264
1265 MyFree(pServerNameW);
1266
1267 return ret;
1268}
1269
1270
1271/***********************************************************************
1272 * CM_Connect_MachineW [SETUPAPI.@]
1273 */
1275WINAPI
1277 _In_opt_ PCWSTR UNCServerName,
1278 _Out_ PHMACHINE phMachine)
1279{
1280 PMACHINE_INFO pMachine;
1281
1282 TRACE("CM_Connect_MachineW(%s %p)\n",
1283 debugstr_w(UNCServerName), phMachine);
1284
1285 if (phMachine == NULL)
1286 return CR_INVALID_POINTER;
1287
1288 *phMachine = NULL;
1289
1290 pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
1291 if (pMachine == NULL)
1292 return CR_OUT_OF_MEMORY;
1293
1294 if (UNCServerName == NULL || *UNCServerName == 0)
1295 {
1296 pMachine->bLocal = TRUE;
1297
1298 /* FIXME: store the computers name in pMachine->szMachineName */
1299
1300 if (!PnpGetLocalHandles(&pMachine->BindingHandle,
1301 &pMachine->StringTable))
1302 {
1303 HeapFree(GetProcessHeap(), 0, pMachine);
1304 return CR_FAILURE;
1305 }
1306 }
1307 else
1308 {
1309 pMachine->bLocal = FALSE;
1310 if (wcslen(UNCServerName) >= SP_MAX_MACHINENAME_LENGTH - 1)
1311 {
1312 HeapFree(GetProcessHeap(), 0, pMachine);
1314 }
1315 lstrcpyW(pMachine->szMachineName, UNCServerName);
1316
1318 if (pMachine->StringTable == NULL)
1319 {
1320 HeapFree(GetProcessHeap(), 0, pMachine);
1321 return CR_FAILURE;
1322 }
1323
1324 pSetupStringTableAddString(pMachine->StringTable, L"PLT", 1);
1325
1326 if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
1327 {
1329 HeapFree(GetProcessHeap(), 0, pMachine);
1331 }
1332 }
1333
1334 *phMachine = (PHMACHINE)pMachine;
1335
1336 return CR_SUCCESS;
1337}
1338
1339
1340/***********************************************************************
1341 * CM_Create_DevNodeA [SETUPAPI.@]
1342 */
1344WINAPI
1346 _Out_ PDEVINST pdnDevInst,
1347 _In_ DEVINSTID_A pDeviceID,
1348 _In_ DEVINST dnParent,
1349 _In_ ULONG ulFlags)
1350{
1351 TRACE("CM_Create_DevNodeA(%p %s %p %lx)\n",
1352 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
1353
1354 return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
1355 ulFlags, NULL);
1356}
1357
1358
1359/***********************************************************************
1360 * CM_Create_DevNodeW [SETUPAPI.@]
1361 */
1363WINAPI
1365 _Out_ PDEVINST pdnDevInst,
1366 _In_ DEVINSTID_W pDeviceID,
1367 _In_ DEVINST dnParent,
1368 _In_ ULONG ulFlags)
1369{
1370 TRACE("CM_Create_DevNodeW(%p %s %p %lx)\n",
1371 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
1372
1373 return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
1374 ulFlags, NULL);
1375}
1376
1377
1378/***********************************************************************
1379 * CM_Create_DevNode_ExA [SETUPAPI.@]
1380 */
1382WINAPI
1384 _Out_ PDEVINST pdnDevInst,
1385 _In_ DEVINSTID_A pDeviceID,
1386 _In_ DEVINST dnParent,
1387 _In_ ULONG ulFlags,
1388 _In_opt_ HANDLE hMachine)
1389{
1390 DEVINSTID_W pDeviceIDW;
1391 CONFIGRET ret;
1392
1393 TRACE("CM_Create_DevNode_ExA(%p %s %p %lx %p)\n",
1394 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
1395
1396 if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
1397 return CR_INVALID_DATA;
1398
1399 ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
1400 hMachine);
1401
1402 MyFree(pDeviceIDW);
1403
1404 return ret;
1405}
1406
1407
1408/***********************************************************************
1409 * CM_Create_DevNode_ExW [SETUPAPI.@]
1410 */
1412WINAPI
1414 _Out_ PDEVINST pdnDevInst,
1415 _In_ DEVINSTID_W pDeviceID,
1416 _In_ DEVINST dnParent,
1417 _In_ ULONG ulFlags,
1418 _In_opt_ HANDLE hMachine)
1419{
1421 HSTRING_TABLE StringTable = NULL;
1422 LPWSTR lpParentDevInst;
1424 WCHAR szLocalDeviceID[MAX_DEVICE_ID_LEN];
1425
1426 TRACE("CM_Create_DevNode_ExW(%p %s %p %lx %p)\n",
1427 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
1428
1429 if (!pSetupIsUserAdmin())
1430 return CR_ACCESS_DENIED;
1431
1432 if (pdnDevInst == NULL)
1433 return CR_INVALID_POINTER;
1434
1435 if (pDeviceID == NULL || wcslen(pDeviceID) == 0 || wcslen(pDeviceID) >= MAX_DEVICE_ID_LEN)
1436 return CR_INVALID_DEVICE_ID;
1437
1438 if (dnParent == 0)
1439 return CR_INVALID_DEVNODE;
1440
1441 if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
1442 return CR_INVALID_FLAG;
1443
1444 if (hMachine != NULL)
1445 {
1446 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1447 if (BindingHandle == NULL)
1448 return CR_FAILURE;
1449
1450 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1451 if (StringTable == 0)
1452 return CR_FAILURE;
1453 }
1454 else
1455 {
1456 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1457 return CR_FAILURE;
1458 }
1459
1460 lpParentDevInst = pSetupStringTableStringFromId(StringTable, dnParent);
1461 if (lpParentDevInst == NULL)
1462 return CR_INVALID_DEVNODE;
1463
1464 wcscpy(szLocalDeviceID, pDeviceID);
1465
1467 {
1469 szLocalDeviceID,
1470 lpParentDevInst,
1472 ulFlags);
1473 }
1475 {
1477 }
1479
1480 if (ret == CR_SUCCESS)
1481 {
1482 /* If CM_CREATE_DEVINST_GENERATE_ID was passed in, PNP_CreateDevInst
1483 * will return the generated device ID in szLocalDeviceID */
1484 *pdnDevInst = pSetupStringTableAddString(StringTable, szLocalDeviceID, 1);
1485 if (*pdnDevInst == 0)
1487 }
1488
1489 return ret;
1490}
1491
1492
1493/***********************************************************************
1494 * CM_Create_Range_List [SETUPAPI.@]
1495 */
1497WINAPI
1499 _Out_ PRANGE_LIST prlh,
1500 _In_ ULONG ulFlags)
1501{
1502 PINTERNAL_RANGE_LIST pRangeList;
1503
1504 FIXME("CM_Create_Range_List(%p %lx)\n",
1505 prlh, ulFlags);
1506
1507 if (ulFlags != 0)
1508 return CR_INVALID_FLAG;
1509
1510 if (prlh == NULL)
1511 return CR_INVALID_POINTER;
1512
1513 /* Allocate the range list */
1515 if (pRangeList == NULL)
1516 return CR_OUT_OF_MEMORY;
1517
1518 /* Set the magic value */
1519 pRangeList->ulMagic = RANGE_LIST_MAGIC;
1520
1521 /* Initialize the mutex for synchonized access */
1522 pRangeList->hMutex = CreateMutex(NULL, FALSE, NULL);
1523 if (pRangeList->hMutex == NULL)
1524 {
1525 HeapFree(GetProcessHeap(), 0, pRangeList);
1526 return CR_FAILURE;
1527 }
1528
1529 InitializeListHead(&pRangeList->ListHead);
1530
1531 *prlh = (RANGE_LIST)pRangeList;
1532
1533 return CR_SUCCESS;
1534}
1535
1536
1537/***********************************************************************
1538 * CM_Delete_Class_Key [SETUPAPI.@]
1539 */
1541WINAPI
1543 _In_ LPGUID ClassGuid,
1544 _In_ ULONG ulFlags)
1545{
1546 TRACE("CM_Delete_Class_Key(%p %lx)\n",
1547 ClassGuid, ulFlags);
1548
1549 return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
1550}
1551
1552
1553/***********************************************************************
1554 * CM_Delete_Class_Key_Ex [SETUPAPI.@]
1555 */
1557WINAPI
1559 _In_ LPGUID ClassGuid,
1560 _In_ ULONG ulFlags,
1561 _In_opt_ HANDLE hMachine)
1562{
1563 WCHAR szGuidString[MAX_GUID_STRING_LEN];
1565 CONFIGRET ret;
1566
1567 TRACE("CM_Delete_Class_Key_Ex(%p %lx %p)\n",
1568 ClassGuid, ulFlags, hMachine);
1569
1570 if (ClassGuid == NULL)
1571 return CR_INVALID_POINTER;
1572
1573 if (ulFlags & ~CM_DELETE_CLASS_BITS)
1574 return CR_INVALID_FLAG;
1575
1576 if (!GuidToString(ClassGuid, szGuidString))
1577 return CR_INVALID_DATA;
1578
1579 if (hMachine != NULL)
1580 {
1581 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1582 if (BindingHandle == NULL)
1583 return CR_FAILURE;
1584 }
1585 else
1586 {
1588 return CR_FAILURE;
1589 }
1590
1592 {
1594 szGuidString,
1595 ulFlags);
1596 }
1598 {
1600 }
1602
1603 return ret;
1604}
1605
1606
1607/***********************************************************************
1608 * CM_Delete_DevNode_Key [SETUPAPI.@]
1609 */
1611WINAPI
1613 _In_ DEVINST dnDevInst,
1614 _In_ ULONG ulHardwareProfile,
1615 _In_ ULONG ulFlags)
1616{
1617 TRACE("CM_Delete_DevNode_Key(%p %lu %lx)\n",
1618 dnDevInst, ulHardwareProfile, ulFlags);
1619
1620 return CM_Delete_DevNode_Key_Ex(dnDevInst, ulHardwareProfile, ulFlags,
1621 NULL);
1622}
1623
1624
1625/***********************************************************************
1626 * CM_Delete_DevNode_Key_Ex [SETUPAPI.@]
1627 */
1629WINAPI
1631 _In_ DEVINST dnDevInst,
1632 _In_ ULONG ulHardwareProfile,
1633 _In_ ULONG ulFlags,
1634 _In_opt_ HANDLE hMachine)
1635{
1637 HSTRING_TABLE StringTable = NULL;
1638 PWSTR pszDevInst, pszKeyPath = NULL, pszInstancePath = NULL;
1639 CONFIGRET ret;
1640
1641 FIXME("CM_Delete_DevNode_Key_Ex(%p %lu %lx %p)\n",
1642 dnDevInst, ulHardwareProfile, ulFlags, hMachine);
1643
1644 if (dnDevInst == 0)
1645 return CR_INVALID_DEVINST;
1646
1647 if (ulFlags & ~CM_REGISTRY_BITS)
1648 return CR_INVALID_FLAG;
1649
1650 if ((ulFlags & CM_REGISTRY_USER) && (ulFlags & CM_REGISTRY_CONFIG))
1651 return CR_INVALID_FLAG;
1652
1653 if (hMachine != NULL)
1654 {
1655 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1656 if (BindingHandle == NULL)
1657 return CR_FAILURE;
1658
1659 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1660 if (StringTable == 0)
1661 return CR_FAILURE;
1662 }
1663 else
1664 {
1665 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1666 return CR_FAILURE;
1667 }
1668
1669 pszDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1670 if (pszDevInst == NULL)
1671 return CR_INVALID_DEVNODE;
1672
1673 TRACE("pszDevInst: %S\n", pszDevInst);
1674
1675 pszKeyPath = MyMalloc(512 * sizeof(WCHAR));
1676 if (pszKeyPath == NULL)
1677 {
1679 goto done;
1680 }
1681
1682 pszInstancePath = MyMalloc(512 * sizeof(WCHAR));
1683 if (pszInstancePath == NULL)
1684 {
1686 goto done;
1687 }
1688
1690 pszDevInst,
1691 pszKeyPath,
1692 pszInstancePath,
1693 ulHardwareProfile,
1694 ulFlags);
1695 if (ret != CR_SUCCESS)
1696 goto done;
1697
1698 TRACE("pszKeyPath: %S\n", pszKeyPath);
1699 TRACE("pszInstancePath: %S\n", pszInstancePath);
1700
1701 if (ulFlags & CM_REGISTRY_USER)
1702 {
1703 FIXME("The CM_REGISTRY_USER flag is not supported yet!\n");
1704 }
1705 else
1706 {
1707#if 0
1708 if (!pSetupIsUserAdmin())
1709 {
1711 goto done;
1712 }
1713#endif
1714
1715 if (!(ulFlags & CM_REGISTRY_CONFIG))
1716 ulHardwareProfile = 0;
1717
1719 {
1721 pszDevInst,
1722 pszKeyPath,
1723 pszInstancePath,
1724 ulHardwareProfile);
1725 }
1727 {
1729 }
1731 }
1732
1733done:
1734 if (pszInstancePath != NULL)
1735 MyFree(pszInstancePath);
1736
1737 if (pszKeyPath != NULL)
1738 MyFree(pszKeyPath);
1739
1740 return ret;
1741}
1742
1743
1744/***********************************************************************
1745 * CM_Delete_Range [SETUPAPI.@]
1746 */
1748WINAPI
1750 _In_ DWORDLONG ullStartValue,
1751 _In_ DWORDLONG ullEndValue,
1752 _In_ RANGE_LIST rlh,
1753 _In_ ULONG ulFlags)
1754{
1755 FIXME("CM_Delete_Range(%I64u %I64u %p %lx)\n",
1756 ullStartValue, ullEndValue, rlh, ulFlags);
1757
1759}
1760
1761
1762/***********************************************************************
1763 * CM_Detect_Resource_Conflict [SETUPAPI.@]
1764 */
1766WINAPI
1768 _In_ DEVINST dnDevInst,
1769 _In_ RESOURCEID ResourceID,
1770 _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1771 _In_ ULONG ResourceLen,
1772 _Out_ PBOOL pbConflictDetected,
1773 _In_ ULONG ulFlags)
1774{
1775 TRACE("CM_Detect_Resource_Conflict(%p %lu %p %lu %p 0x%lx)\n",
1776 dnDevInst, ResourceID, ResourceData, ResourceLen,
1777 pbConflictDetected, ulFlags);
1778
1779 return CM_Detect_Resource_Conflict_Ex(dnDevInst,
1780 ResourceID,
1781 ResourceData,
1782 ResourceLen,
1783 pbConflictDetected,
1784 ulFlags,
1785 NULL);
1786}
1787
1788
1789/***********************************************************************
1790 * CM_Detect_Resource_Conflict_Ex [SETUPAPI.@]
1791 */
1793WINAPI
1795 _In_ DEVINST dnDevInst,
1796 _In_ RESOURCEID ResourceID,
1797 _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1798 _In_ ULONG ResourceLen,
1799 _Out_ PBOOL pbConflictDetected,
1800 _In_ ULONG ulFlags,
1801 _In_opt_ HMACHINE hMachine)
1802{
1803 FIXME("CM_Detect_Resource_Conflict_Ex(%p %lu %p %lu %p 0x%lx %p)\n",
1804 dnDevInst, ResourceID, ResourceData, ResourceLen,
1805 pbConflictDetected, ulFlags, hMachine);
1806
1808}
1809
1810
1811/***********************************************************************
1812 * CM_Disable_DevNode [SETUPAPI.@]
1813 */
1815WINAPI
1817 _In_ DEVINST dnDevInst,
1818 _In_ ULONG ulFlags)
1819{
1820 TRACE("CM_Disable_DevNode(%p %lx)\n",
1821 dnDevInst, ulFlags);
1822
1823 return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1824}
1825
1826
1827/***********************************************************************
1828 * CM_Disable_DevNode_Ex [SETUPAPI.@]
1829 */
1831WINAPI
1833 _In_ DEVINST dnDevInst,
1834 _In_ ULONG ulFlags,
1835 _In_opt_ HMACHINE hMachine)
1836{
1838 HSTRING_TABLE StringTable = NULL;
1839 LPWSTR lpDevInst;
1840 CONFIGRET ret;
1841
1842 TRACE("CM_Disable_DevNode_Ex(%p %lx %p)\n",
1843 dnDevInst, ulFlags, hMachine);
1844
1845 if (!pSetupIsUserAdmin())
1846 return CR_ACCESS_DENIED;
1847
1848 if (dnDevInst == 0)
1849 return CR_INVALID_DEVINST;
1850
1851 if (ulFlags != 0)
1852 return CR_INVALID_FLAG;
1853
1854 if (hMachine != NULL)
1855 {
1856 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1857 if (BindingHandle == NULL)
1858 return CR_FAILURE;
1859
1860 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1861 if (StringTable == 0)
1862 return CR_FAILURE;
1863 }
1864 else
1865 {
1866 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1867 return CR_FAILURE;
1868 }
1869
1870 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1871 if (lpDevInst == NULL)
1872 return CR_INVALID_DEVNODE;
1873
1875 {
1877 lpDevInst,
1878 NULL,
1879 NULL,
1880 0,
1881 ulFlags);
1882 }
1884 {
1886 }
1888
1889 return ret;
1890}
1891
1892
1893/***********************************************************************
1894 * CM_Disconnect_Machine [SETUPAPI.@]
1895 */
1897WINAPI
1899 _In_opt_ HMACHINE hMachine)
1900{
1901 PMACHINE_INFO pMachine;
1902
1903 TRACE("CM_Disconnect_Machine(%p)\n", hMachine);
1904
1905 pMachine = (PMACHINE_INFO)hMachine;
1906 if (pMachine == NULL)
1907 return CR_SUCCESS;
1908
1909 if (pMachine->bLocal == FALSE)
1910 {
1911 if (pMachine->StringTable != NULL)
1913
1914 if (!PnpUnbindRpc(pMachine->BindingHandle))
1915 return CR_ACCESS_DENIED;
1916 }
1917
1918 HeapFree(GetProcessHeap(), 0, pMachine);
1919
1920 return CR_SUCCESS;
1921}
1922
1923
1924/***********************************************************************
1925 * CM_Dup_Range_List [SETUPAPI.@]
1926 */
1928WINAPI
1930 _In_ RANGE_LIST rlhOld,
1931 _In_ RANGE_LIST rlhNew,
1932 _In_ ULONG ulFlags)
1933{
1934 PINTERNAL_RANGE_LIST pOldRangeList, pNewRangeList;
1935 PINTERNAL_RANGE pOldRange, pNewRange;
1936 PLIST_ENTRY ListEntry;
1938
1939 FIXME("CM_Dup_Range_List(%p %p %lx)\n",
1940 rlhOld, rlhNew, ulFlags);
1941
1942 pOldRangeList = (PINTERNAL_RANGE_LIST)rlhOld;
1943 pNewRangeList = (PINTERNAL_RANGE_LIST)rlhNew;
1944
1945 if (!IsValidRangeList(pOldRangeList))
1946 return CR_INVALID_RANGE_LIST;
1947
1948 if (!IsValidRangeList(pNewRangeList))
1949 return CR_INVALID_RANGE_LIST;
1950
1951 if (ulFlags != 0)
1952 return CR_INVALID_FLAG;
1953
1954 /* Lock the range lists */
1955 WaitForSingleObject(pOldRangeList->hMutex, INFINITE);
1956 WaitForSingleObject(pNewRangeList->hMutex, INFINITE);
1957
1958 /* Delete the new range list, if ist is not empty */
1959 while (!IsListEmpty(&pNewRangeList->ListHead))
1960 {
1961 ListEntry = RemoveHeadList(&pNewRangeList->ListHead);
1962 pNewRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
1963 HeapFree(GetProcessHeap(), 0, pNewRange);
1964 }
1965
1966 /* Copy the old range list into the new range list */
1967 ListEntry = &pOldRangeList->ListHead;
1968 while (ListEntry->Flink == &pOldRangeList->ListHead)
1969 {
1970 pOldRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
1971
1972 pNewRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
1973 if (pNewRange == NULL)
1974 {
1976 goto done;
1977 }
1978
1979 pNewRange->pRangeList = pNewRangeList;
1980 pNewRange->ullStart = pOldRange->ullStart;
1981 pNewRange->ullEnd = pOldRange->ullEnd;
1982
1983 InsertTailList(&pNewRangeList->ListHead, &pNewRange->ListEntry);
1984
1985 ListEntry = ListEntry->Flink;
1986 }
1987
1988done:
1989 /* Unlock the range lists */
1990 ReleaseMutex(pNewRangeList->hMutex);
1991 ReleaseMutex(pOldRangeList->hMutex);
1992
1993 return ret;
1994}
1995
1996
1997/***********************************************************************
1998 * CM_Enable_DevNode [SETUPAPI.@]
1999 */
2001WINAPI
2003 _In_ DEVINST dnDevInst,
2004 _In_ ULONG ulFlags)
2005{
2006 TRACE("CM_Enable_DevNode(%p %lx)\n",
2007 dnDevInst, ulFlags);
2008
2009 return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
2010}
2011
2012
2013/***********************************************************************
2014 * CM_Enable_DevNode_Ex [SETUPAPI.@]
2015 */
2017WINAPI
2019 _In_ DEVINST dnDevInst,
2020 _In_ ULONG ulFlags,
2021 _In_opt_ HMACHINE hMachine)
2022{
2024 HSTRING_TABLE StringTable = NULL;
2025 LPWSTR lpDevInst;
2026 CONFIGRET ret;
2027
2028 TRACE("CM_Enable_DevNode_Ex(%p %lx %p)\n",
2029 dnDevInst, ulFlags, hMachine);
2030
2031 if (!pSetupIsUserAdmin())
2032 return CR_ACCESS_DENIED;
2033
2034 if (dnDevInst == 0)
2035 return CR_INVALID_DEVINST;
2036
2037 if (ulFlags != 0)
2038 return CR_INVALID_FLAG;
2039
2040 if (hMachine != NULL)
2041 {
2042 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2043 if (BindingHandle == NULL)
2044 return CR_FAILURE;
2045
2046 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2047 if (StringTable == 0)
2048 return CR_FAILURE;
2049 }
2050 else
2051 {
2052 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2053 return CR_FAILURE;
2054 }
2055
2056 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2057 if (lpDevInst == NULL)
2058 return CR_INVALID_DEVNODE;
2059
2061 {
2063 PNP_DEVINST_ENABLE,
2064 ulFlags,
2065 lpDevInst,
2066 NULL);
2067 }
2069 {
2071 }
2073
2074 return ret;
2075}
2076
2077
2078/***********************************************************************
2079 * CM_Enumerate_Classes [SETUPAPI.@]
2080 */
2082WINAPI
2084 _In_ ULONG ulClassIndex,
2085 _Out_ LPGUID ClassGuid,
2086 _In_ ULONG ulFlags)
2087{
2088 TRACE("CM_Enumerate_Classes(%lx %p %lx)\n",
2089 ulClassIndex, ClassGuid, ulFlags);
2090
2091 return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
2092}
2093
2094
2095/***********************************************************************
2096 * CM_Enumerate_Classes_Ex [SETUPAPI.@]
2097 */
2099WINAPI
2101 _In_ ULONG ulClassIndex,
2102 _Out_ LPGUID ClassGuid,
2103 _In_ ULONG ulFlags,
2104 _In_opt_ HMACHINE hMachine)
2105{
2106 WCHAR szBuffer[MAX_GUID_STRING_LEN];
2109 ULONG ulLength = MAX_GUID_STRING_LEN;
2110
2111 TRACE("CM_Enumerate_Classes_Ex(%lx %p %lx %p)\n",
2112 ulClassIndex, ClassGuid, ulFlags, hMachine);
2113
2114 if (ClassGuid == NULL)
2115 return CR_INVALID_POINTER;
2116
2117 if (ulFlags != 0)
2118 return CR_INVALID_FLAG;
2119
2120 if (hMachine != NULL)
2121 {
2122 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2123 if (BindingHandle == NULL)
2124 return CR_FAILURE;
2125 }
2126 else
2127 {
2129 return CR_FAILURE;
2130 }
2131
2133 {
2135 PNP_CLASS_SUBKEYS,
2136 ulClassIndex,
2137 szBuffer,
2139 &ulLength,
2140 ulFlags);
2141 }
2143 {
2145 }
2147
2148 if (ret == CR_SUCCESS)
2149 {
2150 /* Remove the {} */
2151 szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
2152
2153 /* Convert the buffer to a GUID */
2154 if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
2155 return CR_FAILURE;
2156 }
2157
2158 return ret;
2159}
2160
2161
2162/***********************************************************************
2163 * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
2164 */
2166WINAPI
2168 _In_ ULONG ulEnumIndex,
2169 _Out_writes_(*pulLength) PCHAR Buffer,
2170 _Inout_ PULONG pulLength,
2171 _In_ ULONG ulFlags)
2172{
2173 TRACE("CM_Enumerate_EnumeratorsA(%lu %p %p %lx)\n",
2174 ulEnumIndex, Buffer, pulLength, ulFlags);
2175
2176 return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
2177 ulFlags, NULL);
2178}
2179
2180
2181/***********************************************************************
2182 * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
2183 */
2185WINAPI
2187 _In_ ULONG ulEnumIndex,
2188 _Out_writes_(*pulLength) PWCHAR Buffer,
2189 _Inout_ PULONG pulLength,
2190 _In_ ULONG ulFlags)
2191{
2192 TRACE("CM_Enumerate_EnumeratorsW(%lu %p %p %lx)\n",
2193 ulEnumIndex, Buffer, pulLength, ulFlags);
2194
2195 return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
2196 ulFlags, NULL);
2197}
2198
2199
2200/***********************************************************************
2201 * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
2202 */
2204WINAPI
2206 _In_ ULONG ulEnumIndex,
2207 _Out_writes_(*pulLength) PCHAR Buffer,
2208 _Inout_ PULONG pulLength,
2209 _In_ ULONG ulFlags,
2210 _In_opt_ HMACHINE hMachine)
2211{
2212 WCHAR szBuffer[MAX_DEVICE_ID_LEN];
2213 ULONG ulOrigLength;
2214 ULONG ulLength;
2216
2217 TRACE("CM_Enumerate_Enumerators_ExA(%lu %p %p %lx %p)\n",
2218 ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2219
2220 if (Buffer == NULL || pulLength == NULL)
2221 return CR_INVALID_POINTER;
2222
2223 if (ulFlags != 0)
2224 return CR_INVALID_FLAG;
2225
2226 ulOrigLength = *pulLength;
2227 *pulLength = 0;
2228
2229 ulLength = MAX_DEVICE_ID_LEN;
2230 ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
2231 ulFlags, hMachine);
2232 if (ret == CR_SUCCESS)
2233 {
2235 0,
2236 szBuffer,
2237 ulLength,
2238 Buffer,
2239 ulOrigLength,
2240 NULL,
2241 NULL) == 0)
2242 ret = CR_FAILURE;
2243 else
2244 *pulLength = lstrlenA(Buffer) + 1;
2245 }
2246
2247 return ret;
2248}
2249
2250
2251/***********************************************************************
2252 * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
2253 */
2255WINAPI
2257 _In_ ULONG ulEnumIndex,
2258 _Out_writes_(*pulLength) PWCHAR Buffer,
2259 _Inout_ PULONG pulLength,
2260 _In_ ULONG ulFlags,
2261 _In_opt_ HMACHINE hMachine)
2262{
2264 CONFIGRET ret;
2265
2266 TRACE("CM_Enumerate_Enumerators_ExW(%lu %p %p %lx %p)\n",
2267 ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2268
2269 if (Buffer == NULL || pulLength == NULL)
2270 return CR_INVALID_POINTER;
2271
2272 if (ulFlags != 0)
2273 return CR_INVALID_FLAG;
2274
2276
2277 if (hMachine != NULL)
2278 {
2279 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2280 if (BindingHandle == NULL)
2281 return CR_FAILURE;
2282 }
2283 else
2284 {
2286 return CR_FAILURE;
2287 }
2288
2290 {
2292 PNP_ENUMERATOR_SUBKEYS,
2293 ulEnumIndex,
2294 Buffer,
2295 *pulLength,
2296 pulLength,
2297 ulFlags);
2298 }
2300 {
2302 }
2304
2305 return ret;
2306}
2307
2308
2309/***********************************************************************
2310 * CM_Find_Range [SETUPAPI.@]
2311 */
2313WINAPI
2315 _Out_ PDWORDLONG pullStart,
2316 _In_ DWORDLONG ullStart,
2317 _In_ ULONG ulLength,
2318 _In_ DWORDLONG ullAlignment,
2319 _In_ DWORDLONG ullEnd,
2320 _In_ RANGE_LIST rlh,
2321 _In_ ULONG ulFlags)
2322{
2323 FIXME("CM_Find_Range(%p %I64u %lu %I64u %I64u %p %lx)\n",
2324 pullStart, ullStart, ulLength, ullAlignment, ullEnd, rlh, ulFlags);
2325
2327}
2328
2329
2330/***********************************************************************
2331 * CM_First_Range [SETUPAPI.@]
2332 */
2334WINAPI
2336 _In_ RANGE_LIST rlh,
2337 _Out_ PDWORDLONG pullStart,
2338 _Out_ PDWORDLONG pullEnd,
2339 _Out_ PRANGE_ELEMENT preElement,
2340 _In_ ULONG ulFlags)
2341{
2342 PINTERNAL_RANGE_LIST pRangeList;
2343 PINTERNAL_RANGE pRange;
2344 PLIST_ENTRY ListEntry;
2346
2347 FIXME("CM_First_Range(%p %p %p %p %lx)\n",
2348 rlh, pullStart, pullEnd, preElement, ulFlags);
2349
2350 pRangeList = (PINTERNAL_RANGE_LIST)rlh;
2351
2352 if (!IsValidRangeList(pRangeList))
2353 return CR_INVALID_RANGE_LIST;
2354
2355 if (pullStart == NULL || pullEnd == NULL || preElement == NULL)
2356 return CR_INVALID_POINTER;
2357
2358 if (ulFlags != 0)
2359 return CR_INVALID_FLAG;
2360
2361 /* Lock the range list */
2362 WaitForSingleObject(pRangeList->hMutex, INFINITE);
2363
2364 /* Fail, if the list is empty */
2365 if (IsListEmpty(&pRangeList->ListHead))
2366 {
2367 ret = CR_FAILURE;
2368 goto done;
2369 }
2370
2371 /* Get the first range */
2372 ListEntry = pRangeList->ListHead.Flink;
2373 pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2374
2375 /* Return the range data */
2376 *pullStart = pRange->ullStart;
2377 *pullEnd = pRange->ullEnd;
2378 *preElement = (RANGE_ELEMENT)pRange;
2379
2380done:
2381 /* Unlock the range list */
2382 ReleaseMutex(pRangeList->hMutex);
2383
2384 return ret;
2385}
2386
2387
2388/***********************************************************************
2389 * CM_Free_Log_Conf [SETUPAPI.@]
2390 */
2392WINAPI
2394 _In_ LOG_CONF lcLogConfToBeFreed,
2395 _In_ ULONG ulFlags)
2396{
2397 TRACE("CM_Free_Log_Conf(%lx %lx)\n",
2398 lcLogConfToBeFreed, ulFlags);
2399
2400 return CM_Free_Log_Conf_Ex(lcLogConfToBeFreed, ulFlags, NULL);
2401}
2402
2403
2404/***********************************************************************
2405 * CM_Free_Log_Conf_Ex [SETUPAPI.@]
2406 */
2408WINAPI
2410 _In_ LOG_CONF lcLogConfToBeFreed,
2411 _In_ ULONG ulFlags,
2412 _In_opt_ HMACHINE hMachine)
2413{
2415 HSTRING_TABLE StringTable = NULL;
2416 LPWSTR lpDevInst;
2417 PLOG_CONF_INFO pLogConfInfo;
2418 CONFIGRET ret;
2419
2420 TRACE("CM_Free_Log_Conf_Ex(%lx %lx %p)\n",
2421 lcLogConfToBeFreed, ulFlags, hMachine);
2422
2423 if (!pSetupIsUserAdmin())
2424 return CR_ACCESS_DENIED;
2425
2426 pLogConfInfo = (PLOG_CONF_INFO)lcLogConfToBeFreed;
2427 if (!IsValidLogConf(pLogConfInfo))
2428 return CR_INVALID_LOG_CONF;
2429
2430 if (ulFlags != 0)
2431 return CR_INVALID_FLAG;
2432
2433 if (hMachine != NULL)
2434 {
2435 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2436 if (BindingHandle == NULL)
2437 return CR_FAILURE;
2438
2439 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2440 if (StringTable == 0)
2441 return CR_FAILURE;
2442 }
2443 else
2444 {
2445 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2446 return CR_FAILURE;
2447 }
2448
2449 lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
2450 if (lpDevInst == NULL)
2451 return CR_INVALID_DEVNODE;
2452
2454 {
2456 lpDevInst,
2457 pLogConfInfo->ulType,
2458 pLogConfInfo->ulTag,
2459 0);
2460 }
2462 {
2464 }
2466
2467 return ret;
2468}
2469
2470
2471/***********************************************************************
2472 * CM_Free_Log_Conf_Handle [SETUPAPI.@]
2473 */
2475WINAPI
2477 _In_ LOG_CONF lcLogConf)
2478{
2479 PLOG_CONF_INFO pLogConfInfo;
2480
2481 TRACE("CM_Free_Log_Conf_Handle(%lx)\n", lcLogConf);
2482
2483 pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
2484 if (!IsValidLogConf(pLogConfInfo))
2485 return CR_INVALID_LOG_CONF;
2486
2487 HeapFree(GetProcessHeap(), 0, pLogConfInfo);
2488
2489 return CR_SUCCESS;
2490}
2491
2492
2493/***********************************************************************
2494 * CM_Free_Range_List [SETUPAPI.@]
2495 */
2497WINAPI
2499 _In_ RANGE_LIST RangeList,
2500 _In_ ULONG ulFlags)
2501{
2502 PINTERNAL_RANGE_LIST pRangeList;
2503 PINTERNAL_RANGE pRange;
2504 PLIST_ENTRY ListEntry;
2505
2506 FIXME("CM_Free_Range_List(%p %lx)\n",
2507 RangeList, ulFlags);
2508
2509 pRangeList = (PINTERNAL_RANGE_LIST)RangeList;
2510
2511 if (!IsValidRangeList(pRangeList))
2512 return CR_INVALID_RANGE_LIST;
2513
2514 if (ulFlags != 0)
2515 return CR_INVALID_FLAG;
2516
2517 /* Lock the range list */
2518 WaitForSingleObject(pRangeList->hMutex, INFINITE);
2519
2520 /* Free the list of ranges */
2521 while (!IsListEmpty(&pRangeList->ListHead))
2522 {
2523 ListEntry = RemoveHeadList(&pRangeList->ListHead);
2524 pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2525 HeapFree(GetProcessHeap(), 0, pRange);
2526 }
2527
2528 /* Unlock the range list */
2529 ReleaseMutex(pRangeList->hMutex);
2530
2531 /* Close the mutex */
2532 CloseHandle(pRangeList->hMutex);
2533
2534 /* Free the range list */
2535 HeapFree(GetProcessHeap(), 0, pRangeList);
2536
2537 return CR_SUCCESS;
2538}
2539
2540
2541/***********************************************************************
2542 * CM_Free_Res_Des [SETUPAPI.@]
2543 */
2545WINAPI
2547 _Out_ PRES_DES prdResDes,
2548 _In_ RES_DES rdResDes,
2549 _In_ ULONG ulFlags)
2550{
2551 TRACE("CM_Free_Res_Des(%p %p %lx)\n",
2552 prdResDes, rdResDes, ulFlags);
2553
2554 return CM_Free_Res_Des_Ex(prdResDes, rdResDes, ulFlags, NULL);
2555}
2556
2557
2558/***********************************************************************
2559 * CM_Free_Res_Des_Ex [SETUPAPI.@]
2560 */
2562WINAPI
2564 _Out_ PRES_DES prdResDes,
2565 _In_ RES_DES rdResDes,
2566 _In_ ULONG ulFlags,
2567 _In_opt_ HMACHINE hMachine)
2568{
2569 FIXME("CM_Free_Res_Des_Ex(%p %p %lx %p)\n",
2570 prdResDes, rdResDes, ulFlags, hMachine);
2571
2573}
2574
2575
2576/***********************************************************************
2577 * CM_Free_Res_Des_Handle [SETUPAPI.@]
2578 */
2580WINAPI
2582 _In_ RES_DES rdResDes)
2583{
2584 PRES_DES_INFO pResDesInfo;
2585
2586 FIXME("CM_Free_Res_Des_Handle(%p)\n", rdResDes);
2587
2588 pResDesInfo = (PRES_DES_INFO)rdResDes;
2589 if (!IsValidResDes(pResDesInfo))
2590 return CR_INVALID_RES_DES;
2591
2592 HeapFree(GetProcessHeap(), 0, pResDesInfo);
2593
2594 return CR_SUCCESS;
2595}
2596
2597
2598/***********************************************************************
2599 * CM_Free_Resource_Conflict_Handle [SETUPAPI.@]
2600 */
2602WINAPI
2604 _In_ CONFLICT_LIST clConflictList)
2605{
2606 PCONFLICT_DATA pConflictData;
2607
2608 FIXME("CM_Free_Resource_Conflict_Handle(%p)\n",
2609 clConflictList);
2610
2611 pConflictData = (PCONFLICT_DATA)clConflictList;
2612 if (!IsValidConflictData(pConflictData))
2614
2615 if (pConflictData->pConflictList != NULL)
2616 MyFree(pConflictData->pConflictList);
2617
2618 MyFree(pConflictData);
2619
2620 return CR_SUCCESS;
2621}
2622
2623
2624/***********************************************************************
2625 * CM_Get_Child [SETUPAPI.@]
2626 */
2628WINAPI
2630 _Out_ PDEVINST pdnDevInst,
2631 _In_ DEVINST dnDevInst,
2632 _In_ ULONG ulFlags)
2633{
2634 TRACE("CM_Get_Child(%p %p %lx)\n",
2635 pdnDevInst, dnDevInst, ulFlags);
2636
2637 return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
2638}
2639
2640
2641/***********************************************************************
2642 * CM_Get_Child_Ex [SETUPAPI.@]
2643 */
2645WINAPI
2647 _Out_ PDEVINST pdnDevInst,
2648 _In_ DEVINST dnDevInst,
2649 _In_ ULONG ulFlags,
2650 _In_opt_ HMACHINE hMachine)
2651{
2652 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
2654 HSTRING_TABLE StringTable = NULL;
2655 LPWSTR lpDevInst;
2656 DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
2657 CONFIGRET ret;
2658
2659 TRACE("CM_Get_Child_Ex(%p %lx %lx %p)\n",
2660 pdnDevInst, dnDevInst, ulFlags, hMachine);
2661
2662 if (pdnDevInst == NULL)
2663 return CR_INVALID_POINTER;
2664
2665 if (dnDevInst == 0)
2666 return CR_INVALID_DEVINST;
2667
2668 if (ulFlags != 0)
2669 return CR_INVALID_FLAG;
2670
2671 *pdnDevInst = -1;
2672
2673 if (hMachine != NULL)
2674 {
2675 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2676 if (BindingHandle == NULL)
2677 return CR_FAILURE;
2678
2679 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2680 if (StringTable == 0)
2681 return CR_FAILURE;
2682 }
2683 else
2684 {
2685 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2686 return CR_FAILURE;
2687 }
2688
2689 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2690 if (lpDevInst == NULL)
2691 return CR_INVALID_DEVNODE;
2692
2694 {
2696 PNP_GET_CHILD_DEVICE_INSTANCE,
2697 lpDevInst,
2698 szRelatedDevInst,
2699 &dwLength,
2700 0);
2701 }
2703 {
2705 }
2707
2708 if (ret != CR_SUCCESS)
2709 return ret;
2710
2711 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
2712
2713 dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
2714 if (dwIndex == -1)
2715 return CR_FAILURE;
2716
2717 *pdnDevInst = dwIndex;
2718
2719 return CR_SUCCESS;
2720}
2721
2722
2723/***********************************************************************
2724 * CM_Get_Class_Key_NameA [SETUPAPI.@]
2725 */
2727WINAPI
2729 _In_ LPGUID ClassGuid,
2730 _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2731 _Inout_ PULONG pulLength,
2732 _In_ ULONG ulFlags)
2733{
2734 TRACE("CM_Get_Class_Key_NameA(%p %p %p %lx)\n",
2735 ClassGuid, pszKeyName, pulLength, ulFlags);
2736
2737 return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
2738 ulFlags, NULL);
2739}
2740
2741
2742/***********************************************************************
2743 * CM_Get_Class_Key_NameW [SETUPAPI.@]
2744 */
2746WINAPI
2748 _In_ LPGUID ClassGuid,
2749 _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2750 _Inout_ PULONG pulLength,
2751 _In_ ULONG ulFlags)
2752{
2753 TRACE("CM_Get_Class_Key_NameW(%p %p %p %lx)\n",
2754 ClassGuid, pszKeyName, pulLength, ulFlags);
2755
2756 return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
2757 ulFlags, NULL);
2758}
2759
2760
2761/***********************************************************************
2762 * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
2763 */
2765WINAPI
2767 _In_ LPGUID ClassGuid,
2768 _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2769 _Inout_ PULONG pulLength,
2770 _In_ ULONG ulFlags,
2771 _In_opt_ HMACHINE hMachine)
2772{
2773 WCHAR szBuffer[MAX_GUID_STRING_LEN];
2775 ULONG ulLength;
2776 ULONG ulOrigLength;
2777
2778 TRACE("CM_Get_Class_Key_Name_ExA(%p %p %p %lx %p)\n",
2779 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2780
2781 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2782 return CR_INVALID_POINTER;
2783
2784 ulOrigLength = *pulLength;
2785 *pulLength = 0;
2786
2787 ulLength = MAX_GUID_STRING_LEN;
2788 ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
2789 ulFlags, hMachine);
2790 if (ret == CR_SUCCESS)
2791 {
2793 0,
2794 szBuffer,
2795 ulLength,
2796 pszKeyName,
2797 ulOrigLength,
2798 NULL,
2799 NULL) == 0)
2800 ret = CR_FAILURE;
2801 else
2802 *pulLength = lstrlenA(pszKeyName) + 1;
2803 }
2804
2805 return CR_SUCCESS;
2806}
2807
2808
2809/***********************************************************************
2810 * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
2811 */
2813WINAPI
2815 _In_ LPGUID ClassGuid,
2816 _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2817 _Inout_ PULONG pulLength,
2818 _In_ ULONG ulFlags,
2819 _In_opt_ HMACHINE hMachine)
2820{
2821 TRACE("CM_Get_Class_Key_Name_ExW(%p %p %p %lx %p)\n",
2822 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2823
2824 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2825 return CR_INVALID_POINTER;
2826
2827 if (ulFlags != 0)
2828 return CR_INVALID_FLAG;
2829
2830 if (*pulLength < MAX_GUID_STRING_LEN)
2831 {
2832 *pulLength = 0;
2833 return CR_BUFFER_SMALL;
2834 }
2835
2836 if (!GuidToString(ClassGuid, pszKeyName))
2837 return CR_INVALID_DATA;
2838
2839 *pulLength = MAX_GUID_STRING_LEN;
2840
2841 return CR_SUCCESS;
2842}
2843
2844
2845/***********************************************************************
2846 * CM_Get_Class_NameA [SETUPAPI.@]
2847 */
2849WINAPI
2851 _In_ LPGUID ClassGuid,
2852 _Out_writes_opt_(*pulLength) PCHAR Buffer,
2853 _Inout_ PULONG pulLength,
2854 _In_ ULONG ulFlags)
2855{
2856 TRACE("CM_Get_Class_NameA(%p %p %p %lx)\n",
2857 ClassGuid, Buffer, pulLength, ulFlags);
2858
2859 return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
2860 NULL);
2861}
2862
2863
2864/***********************************************************************
2865 * CM_Get_Class_NameW [SETUPAPI.@]
2866 */
2868WINAPI
2870 _In_ LPGUID ClassGuid,
2871 _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2872 _Inout_ PULONG pulLength,
2873 _In_ ULONG ulFlags)
2874{
2875 TRACE("CM_Get_Class_NameW(%p %p %p %lx)\n",
2876 ClassGuid, Buffer, pulLength, ulFlags);
2877
2878 return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
2879 NULL);
2880}
2881
2882
2883/***********************************************************************
2884 * CM_Get_Class_Name_ExA [SETUPAPI.@]
2885 */
2887WINAPI
2889 _In_ LPGUID ClassGuid,
2890 _Out_writes_opt_(*pulLength) PCHAR Buffer,
2891 _Inout_ PULONG pulLength,
2892 _In_ ULONG ulFlags,
2893 _In_opt_ HMACHINE hMachine)
2894{
2895 WCHAR szBuffer[MAX_CLASS_NAME_LEN];
2897 ULONG ulLength;
2898 ULONG ulOrigLength;
2899
2900 TRACE("CM_Get_Class_Name_ExA(%p %p %p %lx %p)\n",
2901 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2902
2903 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2904 return CR_INVALID_POINTER;
2905
2906 ulOrigLength = *pulLength;
2907 *pulLength = 0;
2908
2909 ulLength = MAX_CLASS_NAME_LEN;
2910 ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
2911 ulFlags, hMachine);
2912 if (ret == CR_SUCCESS)
2913 {
2915 0,
2916 szBuffer,
2917 ulLength,
2918 Buffer,
2919 ulOrigLength,
2920 NULL,
2921 NULL) == 0)
2922 ret = CR_FAILURE;
2923 else
2924 *pulLength = lstrlenA(Buffer) + 1;
2925 }
2926
2927 return ret;
2928}
2929
2930
2931/***********************************************************************
2932 * CM_Get_Class_Name_ExW [SETUPAPI.@]
2933 */
2935WINAPI
2937 _In_ LPGUID ClassGuid,
2938 _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2939 _Inout_ PULONG pulLength,
2940 _In_ ULONG ulFlags,
2941 _In_opt_ HMACHINE hMachine)
2942{
2943 WCHAR szGuidString[MAX_GUID_STRING_LEN];
2945 CONFIGRET ret;
2946
2947 TRACE("CM_Get_Class_Name_ExW(%p %p %p %lx %p\n",
2948 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2949
2950 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2951 return CR_INVALID_POINTER;
2952
2953 if (ulFlags != 0)
2954 return CR_INVALID_FLAG;
2955
2956 if (!GuidToString(ClassGuid, szGuidString))
2957 return CR_INVALID_DATA;
2958
2959 TRACE("Guid %s\n", debugstr_w(szGuidString));
2960
2961 if (hMachine != NULL)
2962 {
2963 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2964 if (BindingHandle == NULL)
2965 return CR_FAILURE;
2966 }
2967 else
2968 {
2970 return CR_FAILURE;
2971 }
2972
2974 {
2976 szGuidString,
2977 Buffer,
2978 pulLength,
2979 ulFlags);
2980 }
2982 {
2984 }
2986
2987 return ret;
2988}
2989
2990
2991/***********************************************************************
2992 * CM_Get_Class_Registry_PropertyA [SETUPAPI.@]
2993 */
2995WINAPI
2997 LPGUID ClassGuid,
2998 ULONG ulProperty,
2999 PULONG pulRegDataType,
3000 PVOID Buffer,
3001 PULONG pulLength,
3002 ULONG ulFlags,
3003 HMACHINE hMachine)
3004{
3005 PWSTR BufferW;
3006 ULONG ulLength = 0;
3007 ULONG ulType;
3008 CONFIGRET ret;
3009
3010 TRACE("CM_Get_Class_Registry_PropertyA(%p %lu %p %p %p %lx %p)\n",
3011 ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
3012 ulFlags, hMachine);
3013
3014 if (pulLength == NULL)
3015 return CR_INVALID_POINTER;
3016
3017 if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
3018 return CR_INVALID_PROPERTY;
3019
3020 ulType = GetRegistryPropertyType(ulProperty);
3021 if (ulType == REG_SZ || ulType == REG_MULTI_SZ)
3022 {
3023 /* Get the required buffer size */
3024 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
3025 NULL, &ulLength, ulFlags, hMachine);
3026 if (ret != CR_BUFFER_SMALL)
3027 return ret;
3028
3029 /* Allocate the unicode buffer */
3030 BufferW = HeapAlloc(GetProcessHeap(), 0, ulLength);
3031 if (BufferW == NULL)
3032 return CR_OUT_OF_MEMORY;
3033
3034 /* Get the property */
3035 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
3036 BufferW, &ulLength, ulFlags, hMachine);
3037 if (ret != CR_SUCCESS)
3038 {
3039 HeapFree(GetProcessHeap(), 0, BufferW);
3040 return ret;
3041 }
3042
3043 /* Do W->A conversion */
3044 *pulLength = WideCharToMultiByte(CP_ACP,
3045 0,
3046 BufferW,
3047 ulLength,
3048 Buffer,
3049 *pulLength,
3050 NULL,
3051 NULL);
3052
3053 /* Release the unicode buffer */
3054 HeapFree(GetProcessHeap(), 0, BufferW);
3055
3056 if (*pulLength == 0)
3057 ret = CR_FAILURE;
3058 }
3059 else
3060 {
3061 /* Get the property */
3062 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
3063 Buffer, pulLength, ulFlags, hMachine);
3064 }
3065
3066 return ret;
3067}
3068
3069
3070/***********************************************************************
3071 * CM_Get_Class_Registry_PropertyW [SETUPAPI.@]
3072 */
3074WINAPI
3076 LPGUID ClassGuid,
3077 ULONG ulProperty,
3078 PULONG pulRegDataType,
3079 PVOID Buffer,
3080 PULONG pulLength,
3081 ULONG ulFlags,
3082 HMACHINE hMachine)
3083{
3085 WCHAR szGuidString[PNP_MAX_GUID_STRING_LEN + 1];
3086 ULONG ulType = 0;
3087 ULONG ulTransferLength = 0;
3088 CONFIGRET ret;
3089
3090 TRACE("CM_Get_Class_Registry_PropertyW(%p %lu %p %p %p %lx %p)\n",
3091 ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
3092 ulFlags, hMachine);
3093
3094 if (ClassGuid == NULL || pulLength == NULL)
3095 return CR_INVALID_POINTER;
3096
3097 if (ulFlags != 0)
3098 return CR_INVALID_FLAG;
3099
3100 if (pSetupStringFromGuid(ClassGuid,
3101 szGuidString,
3103 return CR_INVALID_DATA;
3104
3105 if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
3106 return CR_INVALID_PROPERTY;
3107
3108 if (hMachine != NULL)
3109 {
3110 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3111 if (BindingHandle == NULL)
3112 return CR_FAILURE;
3113 }
3114 else
3115 {
3117 return CR_FAILURE;
3118 }
3119
3120 ulTransferLength = *pulLength;
3121
3123 {
3125 szGuidString,
3126 ulProperty,
3127 &ulType,
3128 Buffer,
3129 &ulTransferLength,
3130 pulLength,
3131 ulFlags);
3132 }
3134 {
3136 }
3138
3139 if (ret == CR_SUCCESS)
3140 {
3141 if (pulRegDataType != NULL)
3142 *pulRegDataType = ulType;
3143 }
3144
3145 return ret;
3146}
3147
3148
3149/***********************************************************************
3150 * CM_Get_Depth [SETUPAPI.@]
3151 */
3153WINAPI
3155 _Out_ PULONG pulDepth,
3156 _In_ DEVINST dnDevInst,
3157 _In_ ULONG ulFlags)
3158{
3159 TRACE("CM_Get_Depth(%p %lx %lx)\n",
3160 pulDepth, dnDevInst, ulFlags);
3161
3162 return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
3163}
3164
3165
3166/***********************************************************************
3167 * CM_Get_Depth_Ex [SETUPAPI.@]
3168 */
3170WINAPI
3172 _Out_ PULONG pulDepth,
3173 _In_ DEVINST dnDevInst,
3174 _In_ ULONG ulFlags,
3175 _In_opt_ HMACHINE hMachine)
3176{
3178 HSTRING_TABLE StringTable = NULL;
3179 LPWSTR lpDevInst;
3180 CONFIGRET ret;
3181
3182 TRACE("CM_Get_Depth_Ex(%p %lx %lx %p)\n",
3183 pulDepth, dnDevInst, ulFlags, hMachine);
3184
3185 if (pulDepth == NULL)
3186 return CR_INVALID_POINTER;
3187
3188 if (dnDevInst == 0)
3189 return CR_INVALID_DEVINST;
3190
3191 if (ulFlags != 0)
3192 return CR_INVALID_FLAG;
3193
3194 if (hMachine != NULL)
3195 {
3196 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3197 if (BindingHandle == NULL)
3198 return CR_FAILURE;
3199
3200 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3201 if (StringTable == 0)
3202 return CR_FAILURE;
3203 }
3204 else
3205 {
3206 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3207 return CR_FAILURE;
3208 }
3209
3210 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3211 if (lpDevInst == NULL)
3212 return CR_INVALID_DEVNODE;
3213
3215 {
3217 lpDevInst,
3218 pulDepth,
3219 ulFlags);
3220 }
3222 {
3224 }
3226
3227 return ret;
3228}
3229
3230
3231/***********************************************************************
3232 * CM_Get_DevNode_Custom_PropertyA [SETUPAPI.@]
3233 */
3235WINAPI
3237 _In_ DEVINST dnDevInst,
3238 _In_ PCSTR pszCustomPropertyName,
3239 _Out_opt_ PULONG pulRegDataType,
3241 _Inout_ PULONG pulLength,
3242 _In_ ULONG ulFlags)
3243{
3244 TRACE("CM_Get_DevNode_Custom_PropertyA(%lx %s %p %p %p %lx)\n",
3245 dnDevInst, pszCustomPropertyName, pulRegDataType,
3246 Buffer, pulLength, ulFlags);
3247
3248 return CM_Get_DevNode_Custom_Property_ExA(dnDevInst, pszCustomPropertyName,
3249 pulRegDataType, Buffer,
3250 pulLength, ulFlags, NULL);
3251}
3252
3253
3254/***********************************************************************
3255 * CM_Get_DevNode_Custom_PropertyW [SETUPAPI.@]
3256 */
3258WINAPI
3260 _In_ DEVINST dnDevInst,
3261 _In_ PCWSTR pszCustomPropertyName,
3262 _Out_opt_ PULONG pulRegDataType,
3264 _Inout_ PULONG pulLength,
3265 _In_ ULONG ulFlags)
3266{
3267 TRACE("CM_Get_DevNode_Custom_PropertyW(%lx %s %p %p %p %lx)\n",
3268 dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3269 Buffer, pulLength, ulFlags);
3270
3271 return CM_Get_DevNode_Custom_Property_ExW(dnDevInst, pszCustomPropertyName,
3272 pulRegDataType, Buffer,
3273 pulLength, ulFlags, NULL);
3274}
3275
3276
3277/***********************************************************************
3278 * CM_Get_DevNode_Custom_Property_ExA [SETUPAPI.@]
3279 */
3281WINAPI
3283 _In_ DEVINST dnDevInst,
3284 _In_ PCSTR pszCustomPropertyName,
3285 _Out_opt_ PULONG pulRegDataType,
3287 _Inout_ PULONG pulLength,
3288 _In_ ULONG ulFlags,
3289 _In_opt_ HMACHINE hMachine)
3290{
3291 LPWSTR pszPropertyNameW;
3292 PVOID BufferW;
3293 ULONG ulLengthW;
3294 ULONG ulDataType = REG_NONE;
3295 CONFIGRET ret;
3296
3297 TRACE("CM_Get_DevNode_Custom_Property_ExA(%lx %s %p %p %p %lx %p)\n",
3298 dnDevInst, pszCustomPropertyName, pulRegDataType,
3299 Buffer, pulLength, ulFlags, hMachine);
3300
3301 if (!pulLength)
3302 return CR_INVALID_POINTER;
3303
3304 ulLengthW = *pulLength * sizeof(WCHAR);
3305 BufferW = HeapAlloc(GetProcessHeap(), 0, ulLengthW);
3306 if (!BufferW)
3307 return CR_OUT_OF_MEMORY;
3308
3309 pszPropertyNameW = pSetupMultiByteToUnicode(pszCustomPropertyName,
3310 CP_ACP);
3311 if (pszPropertyNameW == NULL)
3312 {
3313 HeapFree(GetProcessHeap(), 0, BufferW);
3314 return CR_OUT_OF_MEMORY;
3315 }
3316
3318 pszPropertyNameW,
3319 &ulDataType,
3320 BufferW,
3321 &ulLengthW,
3322 ulFlags,
3323 hMachine);
3324 if (ret == CR_SUCCESS)
3325 {
3326 if (ulDataType == REG_SZ ||
3327 ulDataType == REG_EXPAND_SZ ||
3328 ulDataType == REG_MULTI_SZ)
3329 {
3330 /* Do W->A conversion */
3331 *pulLength = WideCharToMultiByte(CP_ACP,
3332 0,
3333 BufferW,
3334 lstrlenW(BufferW) + 1,
3335 Buffer,
3336 *pulLength,
3337 NULL,
3338 NULL);
3339 if (*pulLength == 0)
3340 ret = CR_FAILURE;
3341 }
3342 else
3343 {
3344 /* Directly copy the value */
3345 if (ulLengthW <= *pulLength)
3346 memcpy(Buffer, BufferW, ulLengthW);
3347 else
3348 {
3349 *pulLength = ulLengthW;
3351 }
3352 }
3353 }
3354
3355 if (pulRegDataType)
3356 *pulRegDataType = ulDataType;
3357
3358 HeapFree(GetProcessHeap(), 0, BufferW);
3359 MyFree(pszPropertyNameW);
3360
3361 return ret;
3362}
3363
3364
3365/***********************************************************************
3366 * CM_Get_DevNode_Custom_Property_ExW [SETUPAPI.@]
3367 */
3369WINAPI
3371 _In_ DEVINST dnDevInst,
3372 _In_ PCWSTR pszCustomPropertyName,
3373 _Out_opt_ PULONG pulRegDataType,
3375 _Inout_ PULONG pulLength,
3376 _In_ ULONG ulFlags,
3377 _In_opt_ HMACHINE hMachine)
3378{
3380 HSTRING_TABLE StringTable = NULL;
3381 LPWSTR lpDevInst;
3382 ULONG ulDataType = REG_NONE;
3383 ULONG ulTransferLength;
3385
3386 TRACE("CM_Get_DevNode_Custom_Property_ExW(%lx %s %p %p %p %lx %p)\n",
3387 dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3388 Buffer, pulLength, ulFlags, hMachine);
3389
3390 if (dnDevInst == 0)
3391 return CR_INVALID_DEVNODE;
3392
3393 if (pszCustomPropertyName == NULL ||
3394 pulLength == NULL ||
3395 *pulLength == 0)
3396 return CR_INVALID_POINTER;
3397
3398 if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
3399 return CR_INVALID_FLAG;
3400
3401 if (hMachine != NULL)
3402 {
3403 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3404 if (BindingHandle == NULL)
3405 return CR_FAILURE;
3406
3407 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3408 if (StringTable == 0)
3409 return CR_FAILURE;
3410 }
3411 else
3412 {
3413 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3414 return CR_FAILURE;
3415 }
3416
3417 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3418 if (lpDevInst == NULL)
3419 return CR_INVALID_DEVNODE;
3420
3421 ulTransferLength = *pulLength;
3422
3424 {
3426 lpDevInst,
3427 (LPWSTR)pszCustomPropertyName,
3428 &ulDataType,
3429 Buffer,
3430 &ulTransferLength,
3431 pulLength,
3432 ulFlags);
3433 }
3435 {
3437 }
3439
3440 if (ret == CR_SUCCESS)
3441 {
3442 if (pulRegDataType != NULL)
3443 *pulRegDataType = ulDataType;
3444 }
3445
3446 return ret;
3447}
3448
3449
3450/***********************************************************************
3451 * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
3452 */
3454WINAPI
3456 _In_ DEVINST dnDevInst,
3457 _In_ ULONG ulProperty,
3458 _Out_opt_ PULONG pulRegDataType,
3460 _Inout_ PULONG pulLength,
3461 _In_ ULONG ulFlags)
3462{
3463 TRACE("CM_Get_DevNode_Registry_PropertyA(%lx %lu %p %p %p %lx)\n",
3464 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3465
3466 return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
3467 pulRegDataType, Buffer,
3468 pulLength, ulFlags, NULL);
3469}
3470
3471
3472/***********************************************************************
3473 * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
3474 */
3476WINAPI
3478 _In_ DEVINST dnDevInst,
3479 _In_ ULONG ulProperty,
3480 _Out_opt_ PULONG pulRegDataType,
3482 _Inout_ PULONG pulLength,
3483 _In_ ULONG ulFlags)
3484{
3485 TRACE("CM_Get_DevNode_Registry_PropertyW(%lx %lu %p %p %p %lx)\n",
3486 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3487
3488 return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
3489 pulRegDataType, Buffer,
3490 pulLength, ulFlags, NULL);
3491}
3492
3493
3494/***********************************************************************
3495 * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
3496 */
3498WINAPI
3500 _In_ DEVINST dnDevInst,
3501 _In_ ULONG ulProperty,
3502 _Out_opt_ PULONG pulRegDataType,
3504 _Inout_ PULONG pulLength,
3505 _In_ ULONG ulFlags,
3506 _In_opt_ HMACHINE hMachine)
3507{
3508 PVOID BufferW;
3509 ULONG LengthW;
3510 ULONG ulDataType = REG_NONE;
3511 CONFIGRET ret;
3512
3513 TRACE("CM_Get_DevNode_Registry_Property_ExA(%lx %lu %p %p %p %lx %p)\n",
3514 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3515 ulFlags, hMachine);
3516
3517 if (!pulLength)
3518 return CR_INVALID_POINTER;
3519
3520 LengthW = *pulLength * sizeof(WCHAR);
3521 BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
3522 if (!BufferW)
3523 return CR_OUT_OF_MEMORY;
3524
3526 ulProperty,
3527 &ulDataType,
3528 BufferW,
3529 &LengthW,
3530 ulFlags,
3531 hMachine);
3532
3533 if (ret == CR_SUCCESS)
3534 {
3535 if (ulDataType == REG_SZ ||
3536 ulDataType == REG_EXPAND_SZ ||
3537 ulDataType == REG_MULTI_SZ)
3538 {
3539 /* Do W->A conversion */
3540 *pulLength = WideCharToMultiByte(CP_ACP,
3541 0,
3542 BufferW,
3543 lstrlenW(BufferW) + 1,
3544 Buffer,
3545 *pulLength,
3546 NULL,
3547 NULL);
3548 if (*pulLength == 0)
3549 ret = CR_FAILURE;
3550 }
3551 else
3552 {
3553 /* Directly copy the value */
3554 if (LengthW <= *pulLength)
3555 memcpy(Buffer, BufferW, LengthW);
3556 else
3557 {
3558 *pulLength = LengthW;
3560 }
3561 }
3562 }
3563
3564 if (pulRegDataType)
3565 *pulRegDataType = ulDataType;
3566
3567 HeapFree(GetProcessHeap(), 0, BufferW);
3568
3569 return ret;
3570}
3571
3572
3573/***********************************************************************
3574 * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
3575 */
3577WINAPI
3579 _In_ DEVINST dnDevInst,
3580 _In_ ULONG ulProperty,
3581 _Out_opt_ PULONG pulRegDataType,
3583 _Inout_ PULONG pulLength,
3584 _In_ ULONG ulFlags,
3585 _In_opt_ HMACHINE hMachine)
3586{
3588 HSTRING_TABLE StringTable = NULL;
3590 LPWSTR lpDevInst;
3591 ULONG ulDataType = REG_NONE;
3592 ULONG ulTransferLength = 0;
3593
3594 TRACE("CM_Get_DevNode_Registry_Property_ExW(%lx %lu %p %p %p %lx %p)\n",
3595 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3596 ulFlags, hMachine);
3597
3598 if (dnDevInst == 0)
3599 return CR_INVALID_DEVNODE;
3600
3601 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
3602 return CR_INVALID_PROPERTY;
3603
3604 /* pulRegDataType is optional */
3605
3606 /* Buffer is optional */
3607
3608 if (pulLength == NULL)
3609 return CR_INVALID_POINTER;
3610
3611 if (*pulLength == 0)
3612 return CR_INVALID_POINTER;
3613
3614 if (ulFlags != 0)
3615 return CR_INVALID_FLAG;
3616
3617 if (hMachine != NULL)
3618 {
3619 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3620 if (BindingHandle == NULL)
3621 return CR_FAILURE;
3622
3623 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3624 if (StringTable == 0)
3625 return CR_FAILURE;
3626 }
3627 else
3628 {
3629 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3630 return CR_FAILURE;
3631 }
3632
3633 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3634 if (lpDevInst == NULL)
3635 return CR_INVALID_DEVNODE;
3636
3637 ulTransferLength = *pulLength;
3638
3640 {
3642 lpDevInst,
3643 ulProperty,
3644 &ulDataType,
3645 Buffer,
3646 &ulTransferLength,
3647 pulLength,
3648 ulFlags);
3649 }
3651 {
3653 }
3655
3656 if (ret == CR_SUCCESS)
3657 {
3658 if (pulRegDataType != NULL)
3659 *pulRegDataType = ulDataType;
3660 }
3661
3662 return ret;
3663}
3664
3665
3666/***********************************************************************
3667 * CM_Get_DevNode_Status [SETUPAPI.@]
3668 */
3670WINAPI
3672 _Out_ PULONG pulStatus,
3673 _Out_ PULONG pulProblemNumber,
3674 _In_ DEVINST dnDevInst,
3675 _In_ ULONG ulFlags)
3676{
3677 TRACE("CM_Get_DevNode_Status(%p %p %lx %lx)\n",
3678 pulStatus, pulProblemNumber, dnDevInst, ulFlags);
3679
3680 return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
3681 ulFlags, NULL);
3682}
3683
3684
3685/***********************************************************************
3686 * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
3687 */
3689WINAPI
3691 _Out_ PULONG pulStatus,
3692 _Out_ PULONG pulProblemNumber,
3693 _In_ DEVINST dnDevInst,
3694 _In_ ULONG ulFlags,
3695 _In_opt_ HMACHINE hMachine)
3696{
3698 HSTRING_TABLE StringTable = NULL;
3699 LPWSTR lpDevInst;
3700 CONFIGRET ret;
3701
3702 TRACE("CM_Get_DevNode_Status_Ex(%p %p %lx %lx %p)\n",
3703 pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
3704
3705 if (pulStatus == NULL || pulProblemNumber == NULL)
3706 return CR_INVALID_POINTER;
3707
3708 if (dnDevInst == 0)
3709 return CR_INVALID_DEVINST;
3710
3711 if (ulFlags != 0)
3712 return CR_INVALID_FLAG;
3713
3714 if (hMachine != NULL)
3715 {
3716 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3717 if (BindingHandle == NULL)
3718 return CR_FAILURE;
3719
3720 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3721 if (StringTable == 0)
3722 return CR_FAILURE;
3723 }
3724 else
3725 {
3726 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3727 return CR_FAILURE;
3728 }
3729
3730 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3731 if (lpDevInst == NULL)
3732 return CR_INVALID_DEVNODE;
3733
3735 {
3737 lpDevInst,
3738 pulStatus,
3739 pulProblemNumber,
3740 ulFlags);
3741 }
3743 {
3745 }
3747
3748 return ret;
3749}
3750
3751
3752/***********************************************************************
3753 * CM_Get_Device_IDA [SETUPAPI.@]
3754 */
3756WINAPI
3758 _In_ DEVINST dnDevInst,
3759 _Out_writes_(BufferLen) PCHAR Buffer,
3760 _In_ ULONG BufferLen,
3761 _In_ ULONG ulFlags)
3762{
3763 TRACE("CM_Get_Device_IDA(%lx %p %lu %lx)\n",
3764 dnDevInst, Buffer, BufferLen, ulFlags);
3765
3766 return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3767}
3768
3769
3770/***********************************************************************
3771 * CM_Get_Device_IDW [SETUPAPI.@]
3772 */
3774WINAPI
3776 _In_ DEVINST dnDevInst,
3777 _Out_writes_(BufferLen) PWCHAR Buffer,
3778 _In_ ULONG BufferLen,
3779 _In_ ULONG ulFlags)
3780{
3781 TRACE("CM_Get_Device_IDW(%lx %p %lu %lx)\n",
3782 dnDevInst, Buffer, BufferLen, ulFlags);
3783
3784 return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3785}
3786
3787
3788/***********************************************************************
3789 * CM_Get_Device_ID_ExA [SETUPAPI.@]
3790 */
3792WINAPI
3794 _In_ DEVINST dnDevInst,
3795 _Out_writes_(BufferLen) PCHAR Buffer,
3796 _In_ ULONG BufferLen,
3797 _In_ ULONG ulFlags,
3798 _In_opt_ HMACHINE hMachine)
3799{
3800 WCHAR szBufferW[MAX_DEVICE_ID_LEN];
3802
3803 TRACE("CM_Get_Device_ID_ExA(%lx %p %lu %lx %p)\n",
3804 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3805
3806 if (Buffer == NULL)
3807 return CR_INVALID_POINTER;
3808
3809 ret = CM_Get_Device_ID_ExW(dnDevInst,
3810 szBufferW,
3812 ulFlags,
3813 hMachine);
3814 if (ret == CR_SUCCESS)
3815 {
3817 0,
3818 szBufferW,
3819 lstrlenW(szBufferW) + 1,
3820 Buffer,
3821 BufferLen,
3822 NULL,
3823 NULL) == 0)
3824 ret = CR_FAILURE;
3825 }
3826
3827 return ret;
3828}
3829
3830
3831/***********************************************************************
3832 * CM_Get_Device_ID_ExW [SETUPAPI.@]
3833 */
3835WINAPI
3837 _In_ DEVINST dnDevInst,
3838 _Out_writes_(BufferLen) PWCHAR Buffer,
3839 _In_ ULONG BufferLen,
3840 _In_ ULONG ulFlags,
3841 _In_opt_ HMACHINE hMachine)
3842{
3843 HSTRING_TABLE StringTable = NULL;
3844
3845 TRACE("CM_Get_Device_ID_ExW(%lx %p %lu %lx %p)\n",
3846 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3847
3848 if (dnDevInst == 0)
3849 return CR_INVALID_DEVINST;
3850
3851 if (Buffer == NULL)
3852 return CR_INVALID_POINTER;
3853
3854 if (ulFlags != 0)
3855 return CR_INVALID_FLAG;
3856
3857 if (hMachine != NULL)
3858 {
3859 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3860 if (StringTable == NULL)
3861 return CR_FAILURE;
3862 }
3863 else
3864 {
3865 if (!PnpGetLocalHandles(NULL, &StringTable))
3866 return CR_FAILURE;
3867 }
3868
3869 if (!pSetupStringTableStringFromIdEx(StringTable,
3870 dnDevInst,
3871 Buffer,
3872 &BufferLen))
3873 return CR_FAILURE;
3874
3875 return CR_SUCCESS;
3876}
3877
3878
3879/***********************************************************************
3880 * CM_Get_Device_ID_ListA [SETUPAPI.@]
3881 */
3883WINAPI
3885 _In_ PCSTR pszFilter,
3886 _Out_writes_(BufferLen) PCHAR Buffer,
3887 _In_ ULONG BufferLen,
3888 _In_ ULONG ulFlags)
3889{
3890 TRACE("CM_Get_Device_ID_ListA(%p %p %lu %lx)\n",
3891 pszFilter, Buffer, BufferLen, ulFlags);
3892
3893 return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
3894 ulFlags, NULL);
3895}
3896
3897
3898/***********************************************************************
3899 * CM_Get_Device_ID_ListW [SETUPAPI.@]
3900 */
3902WINAPI
3904 _In_ PCWSTR pszFilter,
3905 _Out_writes_(BufferLen) PWCHAR Buffer,
3906 _In_ ULONG BufferLen,
3907 _In_ ULONG ulFlags)
3908{
3909 TRACE("CM_Get_Device_ID_ListW(%p %p %lu %lx)\n",
3910 pszFilter, Buffer, BufferLen, ulFlags);
3911
3912 return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
3913 ulFlags, NULL);
3914}
3915
3916
3917/***********************************************************************
3918 * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
3919 */
3921WINAPI
3923 _In_ PCSTR pszFilter,
3924 _Out_writes_(BufferLen) PCHAR Buffer,
3925 _In_ ULONG BufferLen,
3926 _In_ ULONG ulFlags,
3927 _In_opt_ HMACHINE hMachine)
3928{
3929 LPWSTR BufferW = NULL;
3930 LPWSTR pszFilterW = NULL;
3932
3933 TRACE("CM_Get_Device_ID_List_ExA(%p %p %lu %lx %p)\n",
3934 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3935
3936 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
3937 if (BufferW == NULL)
3938 return CR_OUT_OF_MEMORY;
3939
3940 if (pszFilter == NULL)
3941 {
3943 BufferW,
3944 BufferLen,
3945 ulFlags,
3946 hMachine);
3947 }
3948 else
3949 {
3950 if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3951 {
3953 goto Done;
3954 }
3955
3956 ret = CM_Get_Device_ID_List_ExW(pszFilterW,
3957 BufferW,
3958 BufferLen,
3959 ulFlags,
3960 hMachine);
3961
3962 MyFree(pszFilterW);
3963 }
3964
3966 0,
3967 BufferW,
3968 BufferLen,
3969 Buffer,
3970 BufferLen,
3971 NULL,
3972 NULL) == 0)
3973 ret = CR_FAILURE;
3974
3975Done:
3976 MyFree(BufferW);
3977
3978 return ret;
3979}
3980
3981
3982/***********************************************************************
3983 * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
3984 */
3986WINAPI
3988 _In_ PCWSTR pszFilter,
3989 _Out_writes_(BufferLen) PWCHAR Buffer,
3990 _In_ ULONG BufferLen,
3991 _In_ ULONG ulFlags,
3992 _In_opt_ HMACHINE hMachine)
3993{
3995 CONFIGRET ret;
3996
3997 TRACE("CM_Get_Device_ID_List_ExW(%p %p %lu %lx %p)\n",
3998 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3999
4000 if (Buffer == NULL || BufferLen == 0)
4001 return CR_INVALID_POINTER;
4002
4003 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
4004 return CR_INVALID_FLAG;
4005
4006 if (hMachine != NULL)
4007 {
4008 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4009 if (BindingHandle == NULL)
4010 return CR_FAILURE;
4011 }
4012 else
4013 {
4015 return CR_FAILURE;
4016 }
4017
4018 *Buffer = 0;
4019
4021 {
4023 (LPWSTR)pszFilter,
4024 Buffer,
4025 &BufferLen,
4026 ulFlags);
4027 }
4029 {
4031 }
4033
4034 return ret;
4035}
4036
4037
4038/***********************************************************************
4039 * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
4040 */
4042WINAPI
4044 _Out_ PULONG pulLen,
4045 _In_opt_ PCSTR pszFilter,
4046 _In_ ULONG ulFlags)
4047{
4048 TRACE("CM_Get_Device_ID_List_SizeA(%p %s %lx)\n",
4049 pulLen, debugstr_a(pszFilter), ulFlags);
4050
4051 return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
4052}
4053
4054
4055/***********************************************************************
4056 * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
4057 */
4059WINAPI
4061 _Out_ PULONG pulLen,
4062 _In_opt_ PCWSTR pszFilter,
4063 _In_ ULONG ulFlags)
4064{
4065 TRACE("CM_Get_Device_ID_List_SizeW(%p %s %lx)\n",
4066 pulLen, debugstr_w(pszFilter), ulFlags);
4067
4068 return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
4069}
4070
4071
4072/***********************************************************************
4073 * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
4074 */
4076WINAPI
4078 _Out_ PULONG pulLen,
4079 _In_opt_ PCSTR pszFilter,
4080 _In_ ULONG ulFlags,
4081 _In_opt_ HMACHINE hMachine)
4082{
4083 LPWSTR pszFilterW = NULL;
4085
4086 FIXME("CM_Get_Device_ID_List_Size_ExA(%p %s %lx %p)\n",
4087 pulLen, debugstr_a(pszFilter), ulFlags, hMachine);
4088
4089 if (pszFilter == NULL)
4090 {
4092 NULL,
4093 ulFlags,
4094 hMachine);
4095 }
4096 else
4097 {
4098 if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
4099 return CR_INVALID_DEVICE_ID;
4100
4102 pszFilterW,
4103 ulFlags,
4104 hMachine);
4105
4106 MyFree(pszFilterW);
4107 }
4108
4109 return ret;
4110}
4111
4112
4113/***********************************************************************
4114 * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
4115 */
4117WINAPI
4119 _Out_ PULONG pulLen,
4120 _In_opt_ PCWSTR pszFilter,
4121 _In_ ULONG ulFlags,
4122 _In_opt_ HMACHINE hMachine)
4123{
4125 CONFIGRET ret;
4126
4127 FIXME("CM_Get_Device_ID_List_Size_ExW(%p %s %lx %p)\n",
4128 pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
4129
4130 if (pulLen == NULL)
4131 return CR_INVALID_POINTER;
4132
4133 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
4134 return CR_INVALID_FLAG;
4135
4136 if (hMachine != NULL)
4137 {
4138 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4139 if (BindingHandle == NULL)
4140 return CR_FAILURE;
4141 }
4142 else
4143 {
4145 return CR_FAILURE;
4146 }
4147
4148 *pulLen = 0;
4149
4151 {
4153 (LPWSTR)pszFilter,
4154 pulLen,
4155 ulFlags);
4156 }
4158 {
4160 }
4162
4163 return ret;
4164}
4165
4166
4167/***********************************************************************
4168 * CM_Get_Device_ID_Size [SETUPAPI.@]
4169 */
4171WINAPI
4173 _Out_ PULONG pulLen,
4174 _In_ DEVINST dnDevInst,
4175 _In_ ULONG ulFlags)
4176{
4177 TRACE("CM_Get_Device_ID_Size(%p %lx %lx)\n",
4178 pulLen, dnDevInst, ulFlags);
4179
4180 return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
4181}
4182
4183
4184/***********************************************************************
4185 * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
4186 */
4188WINAPI
4190 _Out_ PULONG pulLen,
4191 _In_ DEVINST dnDevInst,
4192 _In_ ULONG ulFlags,
4193 _In_opt_ HMACHINE hMachine)
4194{
4195 HSTRING_TABLE StringTable = NULL;
4196 LPWSTR DeviceId;
4197
4198 TRACE("CM_Get_Device_ID_Size_Ex(%p %lx %lx %p)\n",
4199 pulLen, dnDevInst, ulFlags, hMachine);
4200
4201 if (pulLen == NULL)
4202 return CR_INVALID_POINTER;
4203
4204 if (dnDevInst == 0)
4205 return CR_INVALID_DEVINST;
4206
4207 if (ulFlags != 0)
4208 return CR_INVALID_FLAG;
4209
4210 if (hMachine != NULL)
4211 {
4212 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4213 if (StringTable == NULL)
4214 return CR_FAILURE;
4215 }
4216 else
4217 {
4218 if (!PnpGetLocalHandles(NULL, &StringTable))
4219 return CR_FAILURE;
4220 }
4221
4222 DeviceId = pSetupStringTableStringFromId(StringTable, dnDevInst);
4223 if (DeviceId == NULL)
4224 {
4225 *pulLen = 0;
4226 return CR_SUCCESS;
4227 }
4228
4229 *pulLen = lstrlenW(DeviceId);
4230
4231 return CR_SUCCESS;
4232}
4233
4234
4235/***********************************************************************
4236 * CM_Get_Device_Interface_AliasA [SETUPAPI.@]
4237 */
4239WINAPI
4241 _In_ LPCSTR pszDeviceInterface,
4242 _In_ LPGUID AliasInterfaceGuid,
4243 _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4244 _Inout_ PULONG pulLength,
4245 _In_ ULONG ulFlags)
4246{
4247 TRACE("CM_Get_Device_Interface_AliasA(%p %p %p %p %lx)\n",
4248 pszDeviceInterface, AliasInterfaceGuid,
4249 pszAliasDeviceInterface, pulLength, ulFlags);
4250
4251 return CM_Get_Device_Interface_Alias_ExA(pszDeviceInterface,
4252 AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4253 ulFlags, NULL);
4254}
4255
4256
4257/***********************************************************************
4258 * CM_Get_Device_Interface_AliasW [SETUPAPI.@]
4259 */
4261WINAPI
4263 _In_ LPCWSTR pszDeviceInterface,
4264 _In_ LPGUID AliasInterfaceGuid,
4265 _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4266 _Inout_ PULONG pulLength,
4267 _In_ ULONG ulFlags)
4268{
4269 TRACE("CM_Get_Device_Interface_AliasW(%p %p %p %p %lx)\n",
4270 pszDeviceInterface, AliasInterfaceGuid,
4271 pszAliasDeviceInterface, pulLength, ulFlags);
4272
4273 return CM_Get_Device_Interface_Alias_ExW(pszDeviceInterface,
4274 AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4275 ulFlags, NULL);
4276}
4277
4278
4279/***********************************************************************
4280 * CM_Get_Device_Interface_Alias_ExA [SETUPAPI.@]
4281 */
4283WINAPI
4285 _In_ LPCSTR pszDeviceInterface,
4286 _In_ LPGUID AliasInterfaceGuid,
4287 _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4288 _Inout_ PULONG pulLength,
4289 _In_ ULONG ulFlags,
4290 _In_opt_ HMACHINE hMachine)
4291{
4292 FIXME("CM_Get_Device_Interface_Alias_ExA(%p %p %p %p %lx %p)\n",
4293 pszDeviceInterface, AliasInterfaceGuid,
4294 pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4295
4297}
4298
4299
4300/***********************************************************************
4301 * CM_Get_Device_Interface_Alias_ExW [SETUPAPI.@]
4302 */
4304WINAPI
4306 _In_ LPCWSTR pszDeviceInterface,
4307 _In_ LPGUID AliasInterfaceGuid,
4308 _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4309 _Inout_ PULONG pulLength,
4310 _In_ ULONG ulFlags,
4311 _In_opt_ HMACHINE hMachine)
4312{
4314 ULONG ulTransferLength;
4316
4317 TRACE("CM_Get_Device_Interface_Alias_ExW(%p %p %p %p %lx %p)\n",
4318 pszDeviceInterface, AliasInterfaceGuid,
4319 pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4320
4321 if (pszDeviceInterface == NULL ||
4322 AliasInterfaceGuid == NULL ||
4323 pszAliasDeviceInterface == NULL ||
4324 pulLength == NULL)
4325 return CR_INVALID_POINTER;
4326
4327 if (ulFlags != 0)
4328 return CR_INVALID_FLAG;
4329
4330 if (hMachine != NULL)
4331 {
4332 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4333 if (BindingHandle == NULL)
4334 return CR_FAILURE;
4335 }
4336 else
4337 {
4339 return CR_FAILURE;
4340 }
4341
4342 ulTransferLength = *pulLength;
4343
4345 {
4347 (LPWSTR)pszDeviceInterface,
4348 AliasInterfaceGuid,
4349 pszAliasDeviceInterface,
4350 pulLength,
4351 &ulTransferLength,
4352 0);
4353 }
4355 {
4357 }
4359
4360 return ret;
4361}
4362
4363
4364/***********************************************************************
4365 * CM_Get_Device_Interface_ListA (SETUPAPI.@)
4366 */
4368WINAPI
4371 _In_opt_ DEVINSTID_A pDeviceID,
4372 _Out_writes_(BufferLen) PCHAR Buffer,
4373 _In_ ULONG BufferLen,
4374 _In_ ULONG ulFlags)
4375{
4376 TRACE("CM_Get_Device_Interface_ListA(%s %s %p %lu 0x%08lx)\n",
4378 Buffer, BufferLen, ulFlags);
4379
4381 Buffer, BufferLen, ulFlags, NULL);
4382}
4383
4384
4385/***********************************************************************
4386 * CM_Get_Device_Interface_ListW (SETUPAPI.@)
4387 */
4389WINAPI
4392 _In_opt_ DEVINSTID_W pDeviceID,
4393 _Out_writes_(BufferLen) PWCHAR Buffer,
4394 _In_ ULONG BufferLen,
4395 _In_ ULONG ulFlags)
4396{
4397 TRACE("CM_Get_Device_Interface_ListW(%s %s %p %lu 0x%08lx)\n",
4399 Buffer, BufferLen, ulFlags);
4400
4402 Buffer, BufferLen, ulFlags, NULL);
4403}
4404
4405
4406/***********************************************************************
4407 * CM_Get_Device_Interface_List_ExA (SETUPAPI.@)
4408 */
4410WINAPI
4413 _In_opt_ DEVINSTID_A pDeviceID,
4414 _Out_writes_(BufferLen) PCHAR Buffer,
4415 _In_ ULONG BufferLen,
4416 _In_ ULONG ulFlags,
4417 _In_opt_ HMACHINE hMachine)
4418{
4419 DEVINSTID_W pDeviceIdW = NULL;
4420 PWCHAR BufferW = NULL;
4422
4423 TRACE("CM_Get_Device_Interface_List_ExA(%s %s %p %lu 0x%08lx %p)\n",
4425 Buffer, BufferLen, ulFlags, hMachine);
4426
4427 if (Buffer == NULL ||
4428 BufferLen == 0)
4429 return CR_INVALID_POINTER;
4430
4431 if (pDeviceID != NULL)
4432 {
4433 if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4434 return CR_INVALID_DEVICE_ID;
4435 }
4436
4437 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
4438 if (BufferW == NULL)
4439 {
4441 goto Done;
4442 }
4443
4445 BufferW, BufferLen, ulFlags,
4446 hMachine);
4447 if (ret != CR_SUCCESS)
4448 goto Done;
4449
4451 0,
4452 BufferW,
4453 BufferLen,
4454 Buffer,
4455 BufferLen,
4456 NULL,
4457 NULL) == 0)
4458 ret = CR_FAILURE;
4459
4460Done:
4461 if (BufferW != NULL)
4462 MyFree(BufferW);
4463
4464 if (pDeviceIdW != NULL)
4465 MyFree(pDeviceIdW);
4466
4467 return ret;
4468}
4469
4470
4471/***********************************************************************
4472 * CM_Get_Device_Interface_List_ExW (SETUPAPI.@)
4473 */
4475WINAPI
4478 _In_opt_ DEVINSTID_W pDeviceID,
4479 _Out_writes_(BufferLen) PWCHAR Buffer,
4480 _In_ ULONG BufferLen,
4481 _In_ ULONG ulFlags,
4482 _In_opt_ HMACHINE hMachine)
4483{
4487
4488 TRACE("CM_Get_Device_Interface_List_ExW(%s %s %p %lu 0x%08lx %p)\n",
4490 Buffer, BufferLen, ulFlags, hMachine);
4491
4492 if (Buffer == NULL ||
4493 BufferLen == 0)
4494 return CR_INVALID_POINTER;
4495
4496 if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4497 return CR_INVALID_FLAG;
4498
4499 if (hMachine != NULL)
4500 {
4501 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4502 if (BindingHandle == NULL)
4503 return CR_FAILURE;
4504 }
4505 else
4506 {
4508 return CR_FAILURE;
4509 }
4510
4511 *Buffer = 0;
4512 BufferSize = BufferLen;
4513
4515 {
4518 pDeviceID,
4519 (LPBYTE)Buffer,
4520 &BufferSize,
4521 ulFlags);
4522 }
4524 {
4526 }
4528
4529 return ret;
4530}
4531
4532
4533/***********************************************************************
4534 * CM_Get_Device_Interface_List_SizeA (SETUPAPI.@)
4535 */
4537WINAPI
4539 _Out_ PULONG pulLen,
4541 _In_opt_ DEVINSTID_A pDeviceID,
4542 _In_ ULONG ulFlags)
4543{
4544 TRACE("CM_Get_Device_Interface_List_SizeA(%p %p %s 0x%08lx)\n",
4545 pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags);
4546
4548 pDeviceID, ulFlags, NULL);
4549}
4550
4551
4552/***********************************************************************
4553 * CM_Get_Device_Interface_List_SizeW (SETUPAPI.@)
4554 */
4556WINAPI
4558 _Out_ PULONG pulLen,
4560 _In_opt_ DEVINSTID_W pDeviceID,
4561 _In_ ULONG ulFlags)
4562{
4563 TRACE("CM_Get_Device_Interface_List_SizeW(%p %p %s 0x%08lx)\n",
4564 pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags);
4565
4567 pDeviceID, ulFlags, NULL);
4568}
4569
4570
4571/***********************************************************************
4572 * CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@)
4573 */
4575WINAPI
4577 _Out_ PULONG pulLen,
4579 _In_opt_ DEVINSTID_A pDeviceID,
4580 _In_ ULONG ulFlags,
4581 _In_opt_ HMACHINE hMachine)
4582{
4583 DEVINSTID_W pDeviceIdW = NULL;
4585
4586 TRACE("CM_Get_Device_Interface_List_Size_ExA(%p %p %s 0x%08lx %p)\n",
4587 pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags, hMachine);
4588
4589 if (pulLen == NULL)
4590 return CR_INVALID_POINTER;
4591
4592 if (pDeviceID != NULL)
4593 {
4594 if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4595 return CR_INVALID_DEVICE_ID;
4596 }
4597
4598 *pulLen = 0;
4599
4601 pDeviceIdW, ulFlags, hMachine);
4602
4603 if (pDeviceIdW != NULL)
4604 MyFree(pDeviceIdW);
4605
4606 return ret;
4607}
4608
4609
4610/***********************************************************************
4611 * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@)
4612 */
4614WINAPI
4616 _Out_ PULONG pulLen,
4618 _In_opt_ DEVINSTID_W pDeviceID,
4619 _In_ ULONG ulFlags,
4620 _In_opt_ HMACHINE hMachine)
4621{
4624
4625 TRACE("CM_Get_Device_Interface_List_Size_ExW(%p %p %s 0x%08lx %p)\n",
4626 pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags, hMachine);
4627
4628 if (pulLen == NULL)
4629 return CR_INVALID_POINTER;
4630
4631 if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4632 return CR_INVALID_FLAG;
4633
4634 if (hMachine != NULL)
4635 {
4636 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4637 if (BindingHandle == NULL)
4638 return CR_FAILURE;
4639 }
4640 else
4641 {
4643 return CR_FAILURE;
4644 }
4645
4646 *pulLen = 0;
4647
4649 {
4651 pulLen,
4653 pDeviceID,
4654 ulFlags);
4655 }
4657 {
4659 }
4661
4662 return ret;
4663}
4664
4665
4666/***********************************************************************
4667 * CM_Get_First_Log_Conf [SETUPAPI.@]
4668 */
4670WINAPI
4672 _Out_opt_ PLOG_CONF plcLogConf,
4673 _In_ DEVINST dnDevInst,
4674 _In_ ULONG ulFlags)
4675{
4676 TRACE("CM_Get_First_Log_Conf(%p %lx %lx)\n",
4677 plcLogConf, dnDevInst, ulFlags);
4678
4679 return CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, NULL);
4680}
4681
4682
4683/***********************************************************************
4684 * CM_Get_First_Log_Conf_Ex [SETUPAPI.@]
4685 */
4687WINAPI
4689 _Out_opt_ PLOG_CONF plcLogConf,
4690 _In_ DEVINST dnDevInst,
4691 _In_ ULONG ulFlags,
4692 _In_opt_ HMACHINE hMachine)
4693{
4695 HSTRING_TABLE StringTable = NULL;
4696 LPWSTR lpDevInst = NULL;
4698 ULONG ulTag;
4699 PLOG_CONF_INFO pLogConfInfo;
4700
4701 FIXME("CM_Get_First_Log_Conf_Ex(%p %lx %lx %p)\n",
4702 plcLogConf, dnDevInst, ulFlags, hMachine);
4703
4704 if (dnDevInst == 0)
4705 return CR_INVALID_DEVINST;
4706
4707 if (ulFlags & ~LOG_CONF_BITS)
4708 return CR_INVALID_FLAG;
4709
4710 if (plcLogConf)
4711 *plcLogConf = 0;
4712
4713 if (hMachine != NULL)
4714 {
4715 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4716 if (BindingHandle == NULL)
4717 return CR_FAILURE;
4718
4719 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4720 if (StringTable == 0)
4721 return CR_FAILURE;
4722 }
4723 else
4724 {
4725 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
4726 return CR_FAILURE;
4727 }
4728
4729 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
4730 if (lpDevInst == NULL)
4731 return CR_INVALID_DEVNODE;
4732
4734 {
4736 lpDevInst,
4737 ulFlags,
4738 &ulTag,
4739 ulFlags);
4740 }
4742 {
4744 }
4746
4747 if (ret != CR_SUCCESS)
4748 return ret;
4749
4750 if (plcLogConf)
4751 {
4752 pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
4753 if (pLogConfInfo == NULL)
4754 return CR_OUT_OF_MEMORY;
4755
4756 pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
4757 pLogConfInfo->dnDevInst = dnDevInst;
4758 pLogConfInfo->ulType = ulFlags;
4759 pLogConfInfo->ulTag = ulTag;
4760
4761 *plcLogConf = (LOG_CONF)pLogConfInfo;
4762 }
4763
4764 return CR_SUCCESS;
4765}
4766
4767
4768/***********************************************************************
4769 * CM_Get_Global_State [SETUPAPI.@]
4770 */
4772WINAPI
4774 _Out_ PULONG pulState,
4775 _In_ ULONG ulFlags)
4776{
4777 TRACE("CM_Get_Global_State(%p %lx)\n",
4778 pulState, ulFlags);
4779
4780 return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
4781}
4782
4783
4784/***********************************************************************
4785 * CM_Get_Global_State_Ex [SETUPAPI.@]
4786 */
4788WINAPI
4790 _Out_ PULONG pulState,
4791 _In_ ULONG ulFlags,
4792 _In_opt_ HMACHINE hMachine)
4793{
4795 CONFIGRET ret;
4796
4797 TRACE("CM_Get_Global_State_Ex(%p %lx %p)\n",
4798 pulState, ulFlags, hMachine);
4799
4800 if (pulState == NULL)
4801 return CR_INVALID_POINTER;
4802
4803 if (ulFlags != 0)
4804 return CR_INVALID_FLAG;
4805
4806 if (hMachine != NULL)
4807 {
4808 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4809 if (BindingHandle == NULL)
4810 return CR_FAILURE;
4811 }
4812 else
4813 {
4815 return CR_FAILURE;
4816 }
4817
4819 {
4820 ret = PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
4821 }
4823 {
4825 }
4827
4828 return ret;
4829}
4830
4831
4832/***********************************************************************
4833 * CM_Get_HW_Prof_FlagsA [SETUPAPI.@]
4834 */
4836WINAPI
4838 _In_ DEVINSTID_A szDevInstName,
4839 _In_ ULONG ulHardwareProfile,
4840 _Out_ PULONG pulValue,
4841 _In_ ULONG ulFlags)
4842{
4843 TRACE("CM_Get_HW_Prof_FlagsA(%s %lu %p %lx)\n",
4844 debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4845
4846 return CM_Get_HW_Prof_Flags_ExA(szDevInstName, ulHardwareProfile,
4847 pulValue, ulFlags, NULL);
4848}
4849
4850
4851/***********************************************************************
4852 * CM_Get_HW_Prof_FlagsW [SETUPAPI.@]
4853 */
4855WINAPI
4857 _In_ DEVINSTID_W szDevInstName,
4858 _In_ ULONG ulHardwareProfile,
4859 _Out_ PULONG pulValue,
4860 _In_ ULONG ulFlags)
4861{
4862 TRACE("CM_Get_HW_Prof_FlagsW(%s %lu %p %lx)\n",
4863 debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4864
4865 return CM_Get_HW_Prof_Flags_ExW(szDevInstName, ulHardwareProfile,
4866 pulValue, ulFlags, NULL);
4867}
4868
4869
4870/***********************************************************************
4871 * CM_Get_HW_Prof_Flags_ExA [SETUPAPI.@]
4872 */
4874WINAPI
4876 _In_ DEVINSTID_A szDevInstName,
4877 _In_ ULONG ulHardwareProfile,
4878 _Out_ PULONG pulValue,
4879 _In_ ULONG ulFlags,
4880 _In_opt_ HMACHINE hMachine)
4881{
4882 DEVINSTID_W pszDevIdW = NULL;
4884
4885 TRACE("CM_Get_HW_Prof_Flags_ExA(%s %lu %p %lx %p)\n",
4886 debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4887
4888 if (szDevInstName != NULL)
4889 {
4890 if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
4891 return CR_INVALID_DEVICE_ID;
4892 }
4893
4894 ret = CM_Get_HW_Prof_Flags_ExW(pszDevIdW, ulHardwareProfile,
4895 pulValue, ulFlags, hMachine);
4896
4897 if (pszDevIdW != NULL)
4898 MyFree(pszDevIdW);
4899
4900 return ret;
4901}
4902
4903
4904/***********************************************************************
4905 * CM_Get_HW_Prof_Flags_ExW [SETUPAPI.@]
4906 */
4908WINAPI
4910 _In_ DEVINSTID_W szDevInstName,
4911 _In_ ULONG ulHardwareProfile,
4912 _Out_ PULONG pulValue,
4913 _In_