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