ReactOS 0.4.15-dev-6694-g4ba8af9
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 = NULL;
607 WCHAR szNameBuffer[256];
608 INT nLength;
609 DWORD ulUnknown9 = 0;
610 DWORD dwError;
612
613 FIXME("CMP_RegisterNotification(%p %p %lu %p)\n",
614 hRecipient, lpvNotificationFilter, ulFlags, phDevNotify);
615
616 if ((hRecipient == NULL) ||
617 (lpvNotificationFilter == NULL) ||
618 (phDevNotify == NULL))
619 return CR_INVALID_POINTER;
620
621 if (ulFlags & ~0x7)
622 return CR_INVALID_FLAG;
623
624 if (((PDEV_BROADCAST_HDR)lpvNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR))
625 return CR_INVALID_DATA;
626
628 return CR_FAILURE;
629
630 pNotifyData = HeapAlloc(GetProcessHeap(),
632 sizeof(NOTIFY_DATA));
633 if (pNotifyData == NULL)
634 return CR_OUT_OF_MEMORY;
635
636 pNotifyData->ulMagic = NOTIFY_MAGIC;
637 pNotifyData->hNotifyHandle = NULL;
638
639 if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
640 {
641 FIXME("Register a window\n");
642
643 nLength = GetWindowTextW((HWND)hRecipient,
644 szNameBuffer,
645 ARRAYSIZE(szNameBuffer));
646 if (nLength == 0)
647 {
648 HeapFree(GetProcessHeap(), 0, pNotifyData);
649 return CR_INVALID_DATA;
650 }
651
652 FIXME("Register window: %S\n", szNameBuffer);
653 }
654 else if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_SERVICE_HANDLE)
655 {
656 FIXME("Register a service\n");
657
658 dwError = I_ScPnPGetServiceName((SERVICE_STATUS_HANDLE)hRecipient,
659 szNameBuffer,
660 ARRAYSIZE(szNameBuffer));
661 if (dwError != ERROR_SUCCESS)
662 {
663 HeapFree(GetProcessHeap(), 0, pNotifyData);
664 return CR_INVALID_DATA;
665 }
666
667 FIXME("Register service: %S\n", szNameBuffer);
668 }
669
671 {
673 0, /* ??? */
674 szNameBuffer,
675 (BYTE*)lpvNotificationFilter,
676 ((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size,
677 ulFlags,
678 &pNotifyData->hNotifyHandle,
680 &ulUnknown9); /* ??? */
681 }
683 {
685 }
687
688 if (ret == CR_SUCCESS)
689 {
690 TRACE("hNotifyHandle: %p\n", pNotifyData->hNotifyHandle);
691 *phDevNotify = (HDEVNOTIFY)pNotifyData;
692 }
693 else
694 {
695 if (pNotifyData->hNotifyHandle == NULL)
696 HeapFree(GetProcessHeap(), 0, pNotifyData);
697
698 *phDevNotify = (HDEVNOTIFY)NULL;
699 }
700
701 return ret;
702}
703
704
705/***********************************************************************
706 * CMP_Report_LogOn [SETUPAPI.@]
707 */
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 = NULL;
1468
1469 FIXME("CM_Create_Range_List(%p %lx)\n",
1470 prlh, ulFlags);
1471
1472 if (ulFlags != 0)
1473 return CR_INVALID_FLAG;
1474
1475 if (prlh == NULL)
1476 return CR_INVALID_POINTER;
1477
1478 /* Allocate the range list */
1480 if (pRangeList == NULL)
1481 return CR_OUT_OF_MEMORY;
1482
1483 /* Set the magic value */
1484 pRangeList->ulMagic = RANGE_LIST_MAGIC;
1485
1486 /* Initialize the mutex for synchonized access */
1487 pRangeList->hMutex = CreateMutex(NULL, FALSE, NULL);
1488 if (pRangeList->hMutex == NULL)
1489 {
1490 HeapFree(GetProcessHeap(), 0, pRangeList);
1491 return CR_FAILURE;
1492 }
1493
1494 InitializeListHead(&pRangeList->ListHead);
1495
1496 *prlh = (RANGE_LIST)pRangeList;
1497
1498 return CR_SUCCESS;
1499}
1500
1501
1502/***********************************************************************
1503 * CM_Delete_Class_Key [SETUPAPI.@]
1504 */
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 = NULL;
2907 ULONG ulLength = 0;
2908 ULONG ulType;
2909 CONFIGRET ret;
2910
2911 TRACE("CM_Get_Class_Registry_PropertyA(%p %lu %p %p %p %lx %p)\n",
2912 ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
2913 ulFlags, hMachine);
2914
2915 if (pulLength == NULL)
2916 return CR_INVALID_POINTER;
2917
2918 if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
2919 return CR_INVALID_PROPERTY;
2920
2921 ulType = GetRegistryPropertyType(ulProperty);
2922 if (ulType == REG_SZ || ulType == REG_MULTI_SZ)
2923 {
2924 /* Get the required buffer size */
2925 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2926 NULL, &ulLength, ulFlags, hMachine);
2927 if (ret != CR_BUFFER_SMALL)
2928 return ret;
2929
2930 /* Allocate the unicode buffer */
2931 BufferW = HeapAlloc(GetProcessHeap(), 0, ulLength);
2932 if (BufferW == NULL)
2933 return CR_OUT_OF_MEMORY;
2934
2935 /* Get the property */
2936 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2937 BufferW, &ulLength, ulFlags, hMachine);
2938 if (ret != CR_SUCCESS)
2939 {
2940 HeapFree(GetProcessHeap(), 0, BufferW);
2941 return ret;
2942 }
2943
2944 /* Do W->A conversion */
2945 *pulLength = WideCharToMultiByte(CP_ACP,
2946 0,
2947 BufferW,
2948 ulLength,
2949 Buffer,
2950 *pulLength,
2951 NULL,
2952 NULL);
2953
2954 /* Release the unicode buffer */
2955 HeapFree(GetProcessHeap(), 0, BufferW);
2956
2957 if (*pulLength == 0)
2958 ret = CR_FAILURE;
2959 }
2960 else
2961 {
2962 /* Get the property */
2963 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2964 Buffer, pulLength, ulFlags, hMachine);
2965 }
2966
2967 return ret;
2968}
2969
2970
2971/***********************************************************************
2972 * CM_Get_Class_Registry_PropertyW [SETUPAPI.@]
2973 */
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 = NULL;
3193 PVOID BufferW;
3194 ULONG ulLengthW;
3195 ULONG ulDataType = REG_NONE;
3196 CONFIGRET ret;
3197
3198 TRACE("CM_Get_DevNode_Custom_Property_ExA(%lx %s %p %p %p %lx %p)\n",
3199 dnDevInst, pszCustomPropertyName, pulRegDataType,
3200 Buffer, pulLength, ulFlags, hMachine);
3201
3202 if (!pulLength)
3203 return CR_INVALID_POINTER;
3204
3205 ulLengthW = *pulLength * sizeof(WCHAR);
3206 BufferW = HeapAlloc(GetProcessHeap(), 0, ulLengthW);
3207 if (!BufferW)
3208 return CR_OUT_OF_MEMORY;
3209
3210 pszPropertyNameW = pSetupMultiByteToUnicode(pszCustomPropertyName,
3211 CP_ACP);
3212 if (pszPropertyNameW == NULL)
3213 {
3214 HeapFree(GetProcessHeap(), 0, BufferW);
3215 return CR_OUT_OF_MEMORY;
3216 }
3217
3219 pszPropertyNameW,
3220 &ulDataType,
3221 BufferW,
3222 &ulLengthW,
3223 ulFlags,
3224 hMachine);
3225 if (ret == CR_SUCCESS)
3226 {
3227 if (ulDataType == REG_SZ ||
3228 ulDataType == REG_EXPAND_SZ ||
3229 ulDataType == REG_MULTI_SZ)
3230 {
3231 /* Do W->A conversion */
3232 *pulLength = WideCharToMultiByte(CP_ACP,
3233 0,
3234 BufferW,
3235 lstrlenW(BufferW) + 1,
3236 Buffer,
3237 *pulLength,
3238 NULL,
3239 NULL);
3240 if (*pulLength == 0)
3241 ret = CR_FAILURE;
3242 }
3243 else
3244 {
3245 /* Directly copy the value */
3246 if (ulLengthW <= *pulLength)
3247 memcpy(Buffer, BufferW, ulLengthW);
3248 else
3249 {
3250 *pulLength = ulLengthW;
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
3424 if (!BufferW)
3425 return CR_OUT_OF_MEMORY;
3426
3428 ulProperty,
3429 &ulDataType,
3430 BufferW,
3431 &LengthW,
3432 ulFlags,
3433 hMachine);
3434
3435 if (ret == CR_SUCCESS)
3436 {
3437 if (ulDataType == REG_SZ ||
3438 ulDataType == REG_EXPAND_SZ ||
3439 ulDataType == REG_MULTI_SZ)
3440 {
3441 /* Do W->A conversion */
3442 *pulLength = WideCharToMultiByte(CP_ACP,
3443 0,
3444 BufferW,
3445 lstrlenW(BufferW) + 1,
3446 Buffer,
3447 *pulLength,
3448 NULL,
3449 NULL);
3450 if (*pulLength == 0)
3451 ret = CR_FAILURE;
3452 }
3453 else
3454 {
3455 /* Directly copy the value */
3456 if (LengthW <= *pulLength)
3457 memcpy(Buffer, BufferW, LengthW);
3458 else
3459 {
3460 *pulLength = LengthW;
3462 }
3463 }
3464 }
3465
3466 if (pulRegDataType)
3467 *pulRegDataType = ulDataType;
3468
3469 HeapFree(GetProcessHeap(), 0, BufferW);
3470
3471 return ret;
3472}
3473
3474
3475/***********************************************************************
3476 * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
3477 */
3479WINAPI
3481 _In_ DEVINST dnDevInst,
3482 _In_ ULONG ulProperty,
3483 _Out_opt_ PULONG pulRegDataType,
3485 _Inout_ PULONG pulLength,
3486 _In_ ULONG ulFlags,
3487 _In_opt_ HMACHINE hMachine)
3488{
3490 HSTRING_TABLE StringTable = NULL;
3492 LPWSTR lpDevInst;
3493 ULONG ulDataType = REG_NONE;
3494 ULONG ulTransferLength = 0;
3495
3496 TRACE("CM_Get_DevNode_Registry_Property_ExW(%lx %lu %p %p %p %lx %p)\n",
3497 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3498 ulFlags, hMachine);
3499
3500 if (dnDevInst == 0)
3501 return CR_INVALID_DEVNODE;
3502
3503 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
3504 return CR_INVALID_PROPERTY;
3505
3506 /* pulRegDataType is optional */
3507
3508 /* Buffer is optional */
3509
3510 if (pulLength == NULL)
3511 return CR_INVALID_POINTER;
3512
3513 if (*pulLength == 0)
3514 return CR_INVALID_POINTER;
3515
3516 if (ulFlags != 0)
3517 return CR_INVALID_FLAG;
3518
3519 if (hMachine != NULL)
3520 {
3521 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3522 if (BindingHandle == NULL)
3523 return CR_FAILURE;
3524
3525 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3526 if (StringTable == 0)
3527 return CR_FAILURE;
3528 }
3529 else
3530 {
3531 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3532 return CR_FAILURE;
3533 }
3534
3535 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3536 if (lpDevInst == NULL)
3537 return CR_INVALID_DEVNODE;
3538
3539 ulTransferLength = *pulLength;
3540
3542 {
3544 lpDevInst,
3545 ulProperty,
3546 &ulDataType,
3547 Buffer,
3548 &ulTransferLength,
3549 pulLength,
3550 ulFlags);
3551 }
3553 {
3555 }
3557
3558 if (ret == CR_SUCCESS)
3559 {
3560 if (pulRegDataType != NULL)
3561 *pulRegDataType = ulDataType;
3562 }
3563
3564 return ret;
3565}
3566
3567
3568/***********************************************************************
3569 * CM_Get_DevNode_Status [SETUPAPI.@]
3570 */
3572WINAPI
3574 _Out_ PULONG pulStatus,
3575 _Out_ PULONG pulProblemNumber,
3576 _In_ DEVINST dnDevInst,
3577 _In_ ULONG ulFlags)
3578{
3579 TRACE("CM_Get_DevNode_Status(%p %p %lx %lx)\n",
3580 pulStatus, pulProblemNumber, dnDevInst, ulFlags);
3581
3582 return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
3583 ulFlags, NULL);
3584}
3585
3586
3587/***********************************************************************
3588 * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
3589 */
3591WINAPI
3593 _Out_ PULONG pulStatus,
3594 _Out_ PULONG pulProblemNumber,
3595 _In_ DEVINST dnDevInst,
3596 _In_ ULONG ulFlags,
3597 _In_opt_ HMACHINE hMachine)
3598{
3600 HSTRING_TABLE StringTable = NULL;
3601 LPWSTR lpDevInst;
3602 CONFIGRET ret;
3603
3604 TRACE("CM_Get_DevNode_Status_Ex(%p %p %lx %lx %p)\n",
3605 pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
3606
3607 if (pulStatus == NULL || pulProblemNumber == NULL)
3608 return CR_INVALID_POINTER;
3609
3610 if (dnDevInst == 0)
3611 return CR_INVALID_DEVINST;
3612
3613 if (ulFlags != 0)
3614 return CR_INVALID_FLAG;
3615
3616 if (hMachine != NULL)
3617 {
3618 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3619 if (BindingHandle == NULL)
3620 return CR_FAILURE;
3621
3622 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3623 if (StringTable == 0)
3624 return CR_FAILURE;
3625 }
3626 else
3627 {
3628 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3629 return CR_FAILURE;
3630 }
3631
3632 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3633 if (lpDevInst == NULL)
3634 return CR_INVALID_DEVNODE;
3635
3637 {
3639 lpDevInst,
3640 pulStatus,
3641 pulProblemNumber,
3642 ulFlags);
3643 }
3645 {
3647 }
3649
3650 return ret;
3651}
3652
3653
3654/***********************************************************************
3655 * CM_Get_Device_IDA [SETUPAPI.@]
3656 */
3658WINAPI
3660 _In_ DEVINST dnDevInst,
3661 _Out_writes_(BufferLen) PCHAR Buffer,
3662 _In_ ULONG BufferLen,
3663 _In_ ULONG ulFlags)
3664{
3665 TRACE("CM_Get_Device_IDA(%lx %p %lu %lx)\n",
3666 dnDevInst, Buffer, BufferLen, ulFlags);
3667
3668 return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3669}
3670
3671
3672/***********************************************************************
3673 * CM_Get_Device_IDW [SETUPAPI.@]
3674 */
3676WINAPI
3678 _In_ DEVINST dnDevInst,
3679 _Out_writes_(BufferLen) PWCHAR Buffer,
3680 _In_ ULONG BufferLen,
3681 _In_ ULONG ulFlags)
3682{
3683 TRACE("CM_Get_Device_IDW(%lx %p %lu %lx)\n",
3684 dnDevInst, Buffer, BufferLen, ulFlags);
3685
3686 return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3687}
3688
3689
3690/***********************************************************************
3691 * CM_Get_Device_ID_ExA [SETUPAPI.@]
3692 */
3694WINAPI
3696 _In_ DEVINST dnDevInst,
3697 _Out_writes_(BufferLen) PCHAR Buffer,
3698 _In_ ULONG BufferLen,
3699 _In_ ULONG ulFlags,
3700 _In_opt_ HMACHINE hMachine)
3701{
3702 WCHAR szBufferW[MAX_DEVICE_ID_LEN];
3704
3705 TRACE("CM_Get_Device_ID_ExA(%lx %p %lu %lx %p)\n",
3706 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3707
3708 if (Buffer == NULL)
3709 return CR_INVALID_POINTER;
3710
3711 ret = CM_Get_Device_ID_ExW(dnDevInst,
3712 szBufferW,
3714 ulFlags,
3715 hMachine);
3716 if (ret == CR_SUCCESS)
3717 {
3719 0,
3720 szBufferW,
3721 lstrlenW(szBufferW) + 1,
3722 Buffer,
3723 BufferLen,
3724 NULL,
3725 NULL) == 0)
3726 ret = CR_FAILURE;
3727 }
3728
3729 return ret;
3730}
3731
3732
3733/***********************************************************************
3734 * CM_Get_Device_ID_ExW [SETUPAPI.@]
3735 */
3737WINAPI
3739 _In_ DEVINST dnDevInst,
3740 _Out_writes_(BufferLen) PWCHAR Buffer,
3741 _In_ ULONG BufferLen,
3742 _In_ ULONG ulFlags,
3743 _In_opt_ HMACHINE hMachine)
3744{
3745 HSTRING_TABLE StringTable = NULL;
3746
3747 TRACE("CM_Get_Device_ID_ExW(%lx %p %lu %lx %p)\n",
3748 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3749
3750 if (dnDevInst == 0)
3751 return CR_INVALID_DEVINST;
3752
3753 if (Buffer == NULL)
3754 return CR_INVALID_POINTER;
3755
3756 if (ulFlags != 0)
3757 return CR_INVALID_FLAG;
3758
3759 if (hMachine != NULL)
3760 {
3761 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3762 if (StringTable == NULL)
3763 return CR_FAILURE;
3764 }
3765 else
3766 {
3767 if (!PnpGetLocalHandles(NULL, &StringTable))
3768 return CR_FAILURE;
3769 }
3770
3771 if (!pSetupStringTableStringFromIdEx(StringTable,
3772 dnDevInst,
3773 Buffer,
3774 &BufferLen))
3775 return CR_FAILURE;
3776
3777 return CR_SUCCESS;
3778}
3779
3780
3781/***********************************************************************
3782 * CM_Get_Device_ID_ListA [SETUPAPI.@]
3783 */
3785WINAPI
3787 _In_ PCSTR pszFilter,
3788 _Out_writes_(BufferLen) PCHAR Buffer,
3789 _In_ ULONG BufferLen,
3790 _In_ ULONG ulFlags)
3791{
3792 TRACE("CM_Get_Device_ID_ListA(%p %p %lu %lx)\n",
3793 pszFilter, Buffer, BufferLen, ulFlags);
3794
3795 return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
3796 ulFlags, NULL);
3797}
3798
3799
3800/***********************************************************************
3801 * CM_Get_Device_ID_ListW [SETUPAPI.@]
3802 */
3804WINAPI
3806 _In_ PCWSTR pszFilter,
3807 _Out_writes_(BufferLen) PWCHAR Buffer,
3808 _In_ ULONG BufferLen,
3809 _In_ ULONG ulFlags)
3810{
3811 TRACE("CM_Get_Device_ID_ListW(%p %p %lu %lx)\n",
3812 pszFilter, Buffer, BufferLen, ulFlags);
3813
3814 return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
3815 ulFlags, NULL);
3816}
3817
3818
3819/***********************************************************************
3820 * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
3821 */
3823WINAPI
3825 _In_ PCSTR pszFilter,
3826 _Out_writes_(BufferLen) PCHAR Buffer,
3827 _In_ ULONG BufferLen,
3828 _In_ ULONG ulFlags,
3829 _In_opt_ HMACHINE hMachine)
3830{
3831 LPWSTR BufferW = NULL;
3832 LPWSTR pszFilterW = NULL;
3834
3835 TRACE("CM_Get_Device_ID_List_ExA(%p %p %lu %lx %p)\n",
3836 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3837
3838 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
3839 if (BufferW == NULL)
3840 return CR_OUT_OF_MEMORY;
3841
3842 if (pszFilter == NULL)
3843 {
3845 BufferW,
3846 BufferLen,
3847 ulFlags,
3848 hMachine);
3849 }
3850 else
3851 {
3852 if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3853 {
3855 goto Done;
3856 }
3857
3858 ret = CM_Get_Device_ID_List_ExW(pszFilterW,
3859 BufferW,
3860 BufferLen,
3861 ulFlags,
3862 hMachine);
3863
3864 MyFree(pszFilterW);
3865 }
3866
3868 0,
3869 BufferW,
3870 BufferLen,
3871 Buffer,
3872 BufferLen,
3873 NULL,
3874 NULL) == 0)
3875 ret = CR_FAILURE;
3876
3877Done:
3878 MyFree(BufferW);
3879
3880 return ret;
3881}
3882
3883
3884/***********************************************************************
3885 * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
3886 */
3888WINAPI
3890 _In_ PCWSTR pszFilter,
3891 _Out_writes_(BufferLen) PWCHAR Buffer,
3892 _In_ ULONG BufferLen,
3893 _In_ ULONG ulFlags,
3894 _In_opt_ HMACHINE hMachine)
3895{
3897 CONFIGRET ret;
3898
3899 TRACE("CM_Get_Device_ID_List_ExW(%p %p %lu %lx %p)\n",
3900 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3901
3902 if (Buffer == NULL || BufferLen == 0)
3903 return CR_INVALID_POINTER;
3904
3905 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
3906 return CR_INVALID_FLAG;
3907
3908 if (hMachine != NULL)
3909 {
3910 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3911 if (BindingHandle == NULL)
3912 return CR_FAILURE;
3913 }
3914 else
3915 {
3917 return CR_FAILURE;
3918 }
3919
3920 *Buffer = 0;
3921
3923 {
3925 (LPWSTR)pszFilter,
3926 Buffer,
3927 &BufferLen,
3928 ulFlags);
3929 }
3931 {
3933 }
3935
3936 return ret;
3937}
3938
3939
3940/***********************************************************************
3941 * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
3942 */
3944WINAPI
3946 _Out_ PULONG pulLen,
3947 _In_opt_ PCSTR pszFilter,
3948 _In_ ULONG ulFlags)
3949{
3950 TRACE("CM_Get_Device_ID_List_SizeA(%p %s %lx)\n",
3951 pulLen, debugstr_a(pszFilter), ulFlags);
3952
3953 return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
3954}
3955
3956
3957/***********************************************************************
3958 * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
3959 */
3961WINAPI
3963 _Out_ PULONG pulLen,
3964 _In_opt_ PCWSTR pszFilter,
3965 _In_ ULONG ulFlags)
3966{
3967 TRACE("CM_Get_Device_ID_List_SizeW(%p %s %lx)\n",
3968 pulLen, debugstr_w(pszFilter), ulFlags);
3969
3970 return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
3971}
3972
3973
3974/***********************************************************************
3975 * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
3976 */
3978WINAPI
3980 _Out_ PULONG pulLen,
3981 _In_opt_ PCSTR pszFilter,
3982 _In_ ULONG ulFlags,
3983 _In_opt_ HMACHINE hMachine)
3984{
3985 LPWSTR pszFilterW = NULL;
3987
3988 FIXME("CM_Get_Device_ID_List_Size_ExA(%p %s %lx %p)\n",
3989 pulLen, debugstr_a(pszFilter), ulFlags, hMachine);
3990
3991 if (pszFilter == NULL)
3992 {
3994 NULL,
3995 ulFlags,
3996 hMachine);
3997 }
3998 else
3999 {
4000 if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
4001 return CR_INVALID_DEVICE_ID;
4002
4004 pszFilterW,
4005 ulFlags,
4006 hMachine);
4007
4008 MyFree(pszFilterW);
4009 }
4010
4011 return ret;
4012}
4013
4014
4015/***********************************************************************
4016 * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
4017 */
4019WINAPI
4021 _Out_ PULONG pulLen,
4022 _In_opt_ PCWSTR pszFilter,
4023 _In_ ULONG ulFlags,
4024 _In_opt_ HMACHINE hMachine)
4025{
4027 CONFIGRET ret;
4028
4029 FIXME("CM_Get_Device_ID_List_Size_ExW(%p %s %lx %p)\n",
4030 pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
4031
4032 if (pulLen == NULL)
4033 return CR_INVALID_POINTER;
4034
4035 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
4036 return CR_INVALID_FLAG;
4037
4038 if (hMachine != NULL)
4039 {
4040 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4041 if (BindingHandle == NULL)
4042 return CR_FAILURE;
4043 }
4044 else
4045 {
4047 return CR_FAILURE;
4048 }
4049
4050 *pulLen = 0;
4051
4053 {
4055 (LPWSTR)pszFilter,
4056 pulLen,
4057 ulFlags);
4058 }
4060 {
4062 }
4064
4065 return ret;
4066}
4067
4068
4069/***********************************************************************
4070 * CM_Get_Device_ID_Size [SETUPAPI.@]
4071 */
4073WINAPI
4075 _Out_ PULONG pulLen,
4076 _In_ DEVINST dnDevInst,
4077 _In_ ULONG ulFlags)
4078{
4079 TRACE("CM_Get_Device_ID_Size(%p %lx %lx)\n",
4080 pulLen, dnDevInst, ulFlags);
4081
4082 return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
4083}
4084
4085
4086/***********************************************************************
4087 * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
4088 */
4090WINAPI
4092 _Out_ PULONG pulLen,
4093 _In_ DEVINST dnDevInst,
4094 _In_ ULONG ulFlags,
4095 _In_opt_ HMACHINE hMachine)
4096{
4097 HSTRING_TABLE StringTable = NULL;
4098 LPWSTR DeviceId;
4099
4100 TRACE("CM_Get_Device_ID_Size_Ex(%p %lx %lx %p)\n",
4101 pulLen, dnDevInst, ulFlags, hMachine);
4102
4103 if (pulLen == NULL)
4104 return CR_INVALID_POINTER;
4105
4106 if (dnDevInst == 0)
4107 return CR_INVALID_DEVINST;
4108
4109 if (ulFlags != 0)
4110 return CR_INVALID_FLAG;
4111
4112 if (hMachine != NULL)
4113 {
4114 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4115 if (StringTable == NULL)
4116 return CR_FAILURE;
4117 }
4118 else
4119 {
4120 if (!PnpGetLocalHandles(NULL, &StringTable))
4121 return CR_FAILURE;
4122 }
4123
4124 DeviceId = pSetupStringTableStringFromId(StringTable, dnDevInst);
4125 if (DeviceId == NULL)
4126 {
4127 *pulLen = 0;
4128 return CR_SUCCESS;
4129 }
4130
4131 *pulLen = lstrlenW(DeviceId);
4132
4133 return CR_SUCCESS;
4134}
4135
4136
4137/***********************************************************************
4138 * CM_Get_Device_Interface_AliasA [SETUPAPI.@]
4139 */
4141WINAPI
4143 _In_ LPCSTR pszDeviceInterface,
4144 _In_ LPGUID AliasInterfaceGuid,
4145 _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4146 _Inout_ PULONG pulLength,
4147 _In_ ULONG ulFlags)
4148{
4149 TRACE("CM_Get_Device_Interface_AliasA(%p %p %p %p %lx)\n",
4150 pszDeviceInterface, AliasInterfaceGuid,
4151 pszAliasDeviceInterface, pulLength, ulFlags);
4152
4153 return CM_Get_Device_Interface_Alias_ExA(pszDeviceInterface,
4154 AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4155 ulFlags, NULL);
4156}
4157
4158
4159/***********************************************************************
4160 * CM_Get_Device_Interface_AliasW [SETUPAPI.@]
4161 */
4163WINAPI
4165 _In_ LPCWSTR pszDeviceInterface,
4166 _In_ LPGUID AliasInterfaceGuid,
4167 _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4168 _Inout_ PULONG pulLength,
4169 _In_ ULONG ulFlags)
4170{
4171 TRACE("CM_Get_Device_Interface_AliasW(%p %p %p %p %lx)\n",
4172 pszDeviceInterface, AliasInterfaceGuid,
4173 pszAliasDeviceInterface, pulLength, ulFlags);
4174
4175 return CM_Get_Device_Interface_Alias_ExW(pszDeviceInterface,
4176 AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4177 ulFlags, NULL);
4178}
4179
4180
4181/***********************************************************************
4182 * CM_Get_Device_Interface_Alias_ExA [SETUPAPI.@]
4183 */
4185WINAPI
4187 _In_ LPCSTR pszDeviceInterface,
4188 _In_ LPGUID AliasInterfaceGuid,
4189 _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4190 _Inout_ PULONG pulLength,
4191 _In_ ULONG ulFlags,
4192 _In_opt_ HMACHINE hMachine)
4193{
4194 FIXME("CM_Get_Device_Interface_Alias_ExA(%p %p %p %p %lx %p)\n",
4195 pszDeviceInterface, AliasInterfaceGuid,
4196 pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4197
4199}
4200
4201
4202/***********************************************************************
4203 * CM_Get_Device_Interface_Alias_ExW [SETUPAPI.@]
4204 */
4206WINAPI
4208 _In_ LPCWSTR pszDeviceInterface,
4209 _In_ LPGUID AliasInterfaceGuid,
4210 _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4211 _Inout_ PULONG pulLength,
4212 _In_ ULONG ulFlags,
4213 _In_opt_ HMACHINE hMachine)
4214{
4216 ULONG ulTransferLength;
4218
4219 TRACE("CM_Get_Device_Interface_Alias_ExW(%p %p %p %p %lx %p)\n",
4220 pszDeviceInterface, AliasInterfaceGuid,
4221 pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4222
4223 if (pszDeviceInterface == NULL ||
4224 AliasInterfaceGuid == NULL ||
4225 pszAliasDeviceInterface == NULL ||
4226 pulLength == NULL)
4227 return CR_INVALID_POINTER;
4228
4229 if (ulFlags != 0)
4230 return CR_INVALID_FLAG;
4231
4232 if (hMachine != NULL)
4233 {
4234 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4235 if (BindingHandle == NULL)
4236 return CR_FAILURE;
4237 }
4238 else
4239 {
4241 return CR_FAILURE;
4242 }
4243
4244 ulTransferLength = *pulLength;
4245
4247 {
4249 (LPWSTR)pszDeviceInterface,
4250 AliasInterfaceGuid,
4251 pszAliasDeviceInterface,
4252 pulLength,
4253 &ulTransferLength,
4254 0);
4255 }
4257 {
4259 }
4261
4262 return ret;
4263}
4264
4265
4266/***********************************************************************
4267 * CM_Get_Device_Interface_ListA (SETUPAPI.@)
4268 */
4270WINAPI
4273 _In_opt_ DEVINSTID_A pDeviceID,
4274 _Out_writes_(BufferLen) PCHAR Buffer,
4275 _In_ ULONG BufferLen,
4276 _In_ ULONG ulFlags)
4277{
4278 TRACE("CM_Get_Device_Interface_ListA(%s %s %p %lu 0x%08lx)\n",
4280 Buffer, BufferLen, ulFlags);
4281
4283 Buffer, BufferLen, ulFlags, NULL);
4284}
4285
4286
4287/***********************************************************************
4288 * CM_Get_Device_Interface_ListW (SETUPAPI.@)
4289 */
4291WINAPI
4294 _In_opt_ DEVINSTID_W pDeviceID,
4295 _Out_writes_(BufferLen) PWCHAR Buffer,
4296 _In_ ULONG BufferLen,
4297 _In_ ULONG ulFlags)
4298{
4299 TRACE("CM_Get_Device_Interface_ListW(%s %s %p %lu 0x%08lx)\n",
4301 Buffer, BufferLen, ulFlags);
4302
4304 Buffer, BufferLen, ulFlags, NULL);
4305}
4306
4307
4308/***********************************************************************
4309 * CM_Get_Device_Interface_List_ExA (SETUPAPI.@)
4310 */
4312WINAPI
4315 _In_opt_ DEVINSTID_A pDeviceID,
4316 _Out_writes_(BufferLen) PCHAR Buffer,
4317 _In_ ULONG BufferLen,
4318 _In_ ULONG ulFlags,
4319 _In_opt_ HMACHINE hMachine)
4320{
4321 DEVINSTID_W pDeviceIdW = NULL;
4322 PWCHAR BufferW = NULL;
4324
4325 TRACE("CM_Get_Device_Interface_List_ExA(%s %s %p %lu 0x%08lx %p)\n",
4327 Buffer, BufferLen, ulFlags, hMachine);
4328
4329 if (Buffer == NULL ||
4330 BufferLen == 0)
4331 return CR_INVALID_POINTER;
4332
4333 if (pDeviceID != NULL)
4334 {
4335 if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4336 return CR_INVALID_DEVICE_ID;
4337 }
4338
4339 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
4340 if (BufferW == NULL)
4341 {
4343 goto Done;
4344 }
4345
4347 BufferW, BufferLen, ulFlags,
4348 hMachine);
4349 if (ret != CR_SUCCESS)
4350 goto Done;
4351
4353 0,
4354 BufferW,
4355 BufferLen,
4356 Buffer,
4357 BufferLen,
4358 NULL,
4359 NULL) == 0)
4360 ret = CR_FAILURE;
4361
4362Done:
4363 if (BufferW != NULL)
4364 MyFree(BufferW);
4365
4366 if (pDeviceIdW != NULL)
4367 MyFree(pDeviceIdW);
4368
4369 return ret;
4370}
4371
4372
4373/***********************************************************************
4374 * CM_Get_Device_Interface_List_ExW (SETUPAPI.@)
4375 */
4377WINAPI
4380 _In_opt_ DEVINSTID_W pDeviceID,
4381 _Out_writes_(BufferLen) PWCHAR Buffer,
4382 _In_ ULONG BufferLen,
4383 _In_ ULONG ulFlags,
4384 _In_opt_ HMACHINE hMachine)
4385{
4389
4390 TRACE("CM_Get_Device_Interface_List_ExW(%s %s %p %lu 0x%08lx %p)\n",
4392 Buffer, BufferLen, ulFlags, hMachine);
4393
4394 if (Buffer == NULL ||
4395 BufferLen == 0)
4396 return CR_INVALID_POINTER;
4397
4398 if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4399 return CR_INVALID_FLAG;
4400
4401 if (hMachine != NULL)
4402 {
4403 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4404 if (BindingHandle == NULL)
4405 return CR_FAILURE;
4406 }
4407 else
4408 {
4410 return CR_FAILURE;
4411 }
4412
4413 *Buffer = 0;
4414 BufferSize = BufferLen;
4415
4417 {
4420 pDeviceID,
4421 (LPBYTE)Buffer,
4422 &BufferSize,
4423 ulFlags);
4424 }
4426 {
4428 }
4430
4431 return ret;
4432}
4433
4434
4435/***********************************************************************
4436 * CM_Get_Device_Interface_List_SizeA (SETUPAPI.@)
4437 */
4439WINAPI
4441 _Out_ PULONG pulLen,
4443 _In_opt_ DEVINSTID_A pDeviceID,
4444 _In_ ULONG ulFlags)
4445{
4446 TRACE("CM_Get_Device_Interface_List_SizeA(%p %p %s 0x%08lx)\n",
4447 pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags);
4448
4450 pDeviceID, ulFlags, NULL);
4451}
4452
4453
4454/***********************************************************************
4455 * CM_Get_Device_Interface_List_SizeW (SETUPAPI.@)
4456 */
4458WINAPI
4460 _Out_ PULONG pulLen,
4462 _In_opt_ DEVINSTID_W pDeviceID,
4463 _In_ ULONG ulFlags)
4464{
4465 TRACE("CM_Get_Device_Interface_List_SizeW(%p %p %s 0x%08lx)\n",
4466 pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags);
4467
4469 pDeviceID, ulFlags, NULL);
4470}
4471
4472
4473/***********************************************************************
4474 * CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@)
4475 */
4477WINAPI
4479 _Out_ PULONG pulLen,
4481 _In_opt_ DEVINSTID_A pDeviceID,
4482 _In_ ULONG ulFlags,
4483 _In_opt_ HMACHINE hMachine)
4484{
4485 DEVINSTID_W pDeviceIdW = NULL;
4487
4488 TRACE("CM_Get_Device_Interface_List_Size_ExA(%p %p %s 0x%08lx %p)\n",
4489 pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags, hMachine);
4490
4491 if (pulLen == NULL)
4492 return CR_INVALID_POINTER;
4493
4494 if (pDeviceID != NULL)
4495 {
4496 if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4497 return CR_INVALID_DEVICE_ID;
4498 }
4499
4500 *pulLen = 0;
4501
4503 pDeviceIdW, ulFlags, hMachine);
4504
4505 if (pDeviceIdW != NULL)
4506 MyFree(pDeviceIdW);
4507
4508 return ret;
4509}
4510
4511
4512/***********************************************************************
4513 * CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@)
4514 */
4516WINAPI
4518 _Out_ PULONG pulLen,
4520 _In_opt_ DEVINSTID_W pDeviceID,
4521 _In_ ULONG ulFlags,
4522 _In_opt_ HMACHINE hMachine)
4523{
4526
4527 TRACE("CM_Get_Device_Interface_List_Size_ExW(%p %p %s 0x%08lx %p)\n",
4528 pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags, hMachine);
4529
4530 if (pulLen == NULL)
4531 return CR_INVALID_POINTER;
4532
4533 if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4534 return CR_INVALID_FLAG;
4535
4536 if (hMachine != NULL)
4537 {
4538 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4539 if (BindingHandle == NULL)
4540 return CR_FAILURE;
4541 }
4542 else
4543 {
4545 return CR_FAILURE;
4546 }
4547
4548 *pulLen = 0;
4549
4551 {
4553 pulLen,
4555 pDeviceID,
4556 ulFlags);
4557 }
4559 {
4561 }
4563
4564 return ret;
4565}
4566
4567
4568/***********************************************************************
4569 * CM_Get_First_Log_Conf [SETUPAPI.@]
4570 */
4572WINAPI
4574 _Out_opt_ PLOG_CONF plcLogConf,
4575 _In_ DEVINST dnDevInst,
4576 _In_ ULONG ulFlags)
4577{
4578 TRACE("CM_Get_First_Log_Conf(%p %lx %lx)\n",
4579 plcLogConf, dnDevInst, ulFlags);
4580
4581 return CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, NULL);
4582}
4583
4584
4585/***********************************************************************
4586 * CM_Get_First_Log_Conf_Ex [SETUPAPI.@]
4587 */
4589WINAPI
4591 _Out_opt_ PLOG_CONF plcLogConf,
4592 _In_ DEVINST dnDevInst,
4593 _In_ ULONG ulFlags,
4594 _In_opt_ HMACHINE hMachine)
4595{
4597 HSTRING_TABLE StringTable = NULL;
4598 LPWSTR lpDevInst = NULL;
4600 ULONG ulTag;
4601 PLOG_CONF_INFO pLogConfInfo;
4602
4603 FIXME("CM_Get_First_Log_Conf_Ex(%p %lx %lx %p)\n",
4604 plcLogConf, dnDevInst, ulFlags, hMachine);
4605
4606 if (dnDevInst == 0)
4607 return CR_INVALID_DEVINST;
4608
4609 if (ulFlags & ~LOG_CONF_BITS)
4610 return CR_INVALID_FLAG;
4611
4612 if (plcLogConf)
4613 *plcLogConf = 0;
4614
4615 if (hMachine != NULL)
4616 {
4617 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4618 if (BindingHandle == NULL)
4619 return CR_FAILURE;
4620
4621 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4622 if (StringTable == 0)
4623 return CR_FAILURE;
4624 }
4625 else
4626 {
4627 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
4628 return CR_FAILURE;
4629 }
4630
4631 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
4632 if (lpDevInst == NULL)
4633 return CR_INVALID_DEVNODE;
4634
4636 {
4638 lpDevInst,
4639 ulFlags,
4640 &ulTag,
4641 ulFlags);
4642 }
4644 {
4646 }
4648
4649 if (ret != CR_SUCCESS)
4650 return ret;
4651
4652 if (plcLogConf)
4653 {
4654 pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
4655 if (pLogConfInfo == NULL)
4656 return CR_OUT_OF_MEMORY;
4657
4658 pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
4659 pLogConfInfo->dnDevInst = dnDevInst;
4660 pLogConfInfo->ulType = ulFlags;
4661 pLogConfInfo->ulTag = ulTag;
4662
4663 *plcLogConf = (LOG_CONF)pLogConfInfo;
4664 }
4665
4666 return CR_SUCCESS;
4667}
4668
4669
4670/***********************************************************************
4671 * CM_Get_Global_State [SETUPAPI.@]
4672 */
4674WINAPI
4676 _Out_ PULONG pulState,
4677 _In_ ULONG ulFlags)
4678{
4679 TRACE("CM_Get_Global_State(%p %lx)\n",
4680 pulState, ulFlags);
4681
4682 return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
4683}
4684
4685
4686/***********************************************************************
4687 * CM_Get_Global_State_Ex [SETUPAPI.@]
4688 */
4690WINAPI
4692 _Out_ PULONG pulState,
4693 _In_ ULONG ulFlags,
4694 _In_opt_ HMACHINE hMachine)
4695{
4697 CONFIGRET ret;
4698
4699 TRACE("CM_Get_Global_State_Ex(%p %lx %p)\n",
4700 pulState, ulFlags, hMachine);
4701
4702 if (pulState == NULL)
4703 return CR_INVALID_POINTER;
4704
4705 if (ulFlags != 0)
4706 return CR_INVALID_FLAG;
4707
4708 if (hMachine != NULL)
4709 {
4710 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4711 if (BindingHandle == NULL)
4712 return CR_FAILURE;
4713 }
4714 else
4715 {
4717 return CR_FAILURE;
4718 }
4719
4721 {
4722 ret = PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
4723 }
4725 {
4727 }
4729
4730 return ret;
4731}
4732
4733
4734/***********************************************************************
4735 * CM_Get_HW_Prof_FlagsA [SETUPAPI.@]
4736 */
4738WINAPI
4740 _In_ DEVINSTID_A szDevInstName,
4741 _In_ ULONG ulHardwareProfile,
4742 _Out_ PULONG pulValue,
4743 _In_ ULONG ulFlags)
4744{
4745 TRACE("CM_Get_HW_Prof_FlagsA(%s %lu %p %lx)\n",
4746 debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4747
4748 return CM_Get_HW_Prof_Flags_ExA(szDevInstName, ulHardwareProfile,
4749 pulValue, ulFlags, NULL);
4750}
4751
4752
4753/***********************************************************************
4754 * CM_Get_HW_Prof_FlagsW [SETUPAPI.@]
4755 */
4757WINAPI
4759 _In_ DEVINSTID_W szDevInstName,
4760 _In_ ULONG ulHardwareProfile,
4761 _Out_ PULONG pulValue,
4762 _In_ ULONG ulFlags)
4763{
4764 TRACE("CM_Get_HW_Prof_FlagsW(%s %lu %p %lx)\n",
4765 debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4766
4767 return CM_Get_HW_Prof_Flags_ExW(szDevInstName, ulHardwareProfile,
4768 pulValue, ulFlags, NULL);
4769}
4770
4771
4772/***********************************************************************
4773 * CM_Get_HW_Prof_Flags_ExA [SETUPAPI.@]
4774 */
4776WINAPI
4778 _In_ DEVINSTID_A szDevInstName,
4779 _In_ ULONG ulHardwareProfile,
4780 _Out_ PULONG pulValue,
4781 _In_ ULONG ulFlags,
4782 _In_opt_ HMACHINE hMachine)
4783{
4784 DEVINSTID_W pszDevIdW = NULL;
4786
4787 TRACE("CM_Get_HW_Prof_Flags_ExA(%s %lu %p %lx %p)\n",
4788 debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4789
4790 if (szDevInstName != NULL)
4791 {
4792 if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
4793 return CR_INVALID_DEVICE_ID;
4794 }
4795
4796 ret = CM_Get_HW_Prof_Flags_ExW(pszDevIdW, ulHardwareProfile,
4797 pulValue, ulFlags, hMachine);
4798
4799 if (pszDevIdW != NULL)
4800 MyFree(pszDevIdW);
4801
4802 return ret;
4803}
4804
4805
4806/***********************************************************************
4807 * CM_Get_HW_Prof_Flags_ExW [SETUPAPI.@]
4808 */
4810WINAPI
4812 _In_ DEVINSTID_W szDevInstName,
4813 _In_ ULONG ulHardwareProfile,
4814 _Out_ PULONG pulValue,
4815 _In_ ULONG ulFlags,
4816 _In_opt_ HMACHINE hMachine)
4817{
4819 CONFIGRET ret;
4820
4821 FIXME("CM_Get_HW_Prof_Flags_ExW(%s %lu %p %lx %p)\n",
4822 debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4823
4824 if ((szDevInstName == NULL) || (pulValue == NULL))
4825 return CR_INVALID_POINTER;
4826
4827 if (ulFlags != 0)
4828 return CR_INVALID_FLAG;
4829
4830 /* FIXME: Check whether szDevInstName is valid */
4831
4832 if (hMachine != NULL)
4833 {
4834 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4835 if (BindingHandle == NULL)
4836 return CR_FAILURE;
4837 }
4838 else
4839 {
4841 return CR_FAILURE;
4842 }
4843
4845 {
4846 ret = PNP_HwProfFlags(BindingHandle, PNP_GET_HWPROFFLAGS, szDevInstName,
4847 ulHardwareProfile, pulValue, NULL, NULL, 0, 0);
4848 }
4850 {
4852 }
4854
4855 return ret;
4856}
4857
4858
4859/***********************************************************************
4860 * CM_Get_Hardware_Profile_InfoA [SETUPAPI.@]
4861 */
4863WINAPI
4865 _In_ ULONG ulIndex,
4866 _Out_ PHWPROFILEINFO_A pHWProfileInfo,
4867 _In_ ULONG ulFlags)
4868{
4869 TRACE("CM_Get_Hardware_Profile_InfoA(%lu %p %lx)\n",
4870 ulIndex, pHWProfileInfo, ulFlags);
4871
4872 return CM_Get_Hardware_Profile_Info_ExA(ulIndex, pHWProfileInfo,
4873 ulFlags, NULL);
4874}
4875
4876
4877/***********************************************************************
4878 * CM_Get_Hardware_Profile_InfoW [SETUPAPI.@]
4879 */
4881WINAPI
4883 _In_ ULONG ulIndex,
4884 _Out_ PHWPROFILEINFO_W pHWProfileInfo,
4885 _In_ ULONG ulFlags)
4886{
4887 TRACE("CM_Get_Hardware_Profile_InfoW(%lu %p %lx)\n",
4888 ulIndex, pHWProfileInfo, ulFlags);
4889
4890 return CM_Get_Hardware_Profile_Info_ExW(ulIndex, pHWProfileInfo,
4891 ulFlags, NULL);
4892}
4893
4894
4895/***********************************************************************
4896 * CM_Get_Hardware_Profile_Info_ExA [SETUPAPI.@]
4897 */
4899WINAPI
4901 _In_ ULONG ulIndex,
4902 _Out_ PHWPROFILEINFO_A pHWProfileInfo,
4903 _In_ ULONG ulFlags,
4904 _In_opt_ HMACHINE hMachine)
4905{
4906 HWPROFILEINFO_W LocalProfileInfo;
4907 CONFIGRET ret;
4908
4909 TRACE("CM_Get_Hardware_Profile_Info_ExA(%lu %p %lx %p)\n",
4910 ulIndex, pHWProfileInfo, ulFlags, hMachine);
4911
4912 if (pHWProfileInfo == NULL)
4913 return CR_INVALID_POINTER;
4914
4915 ret = CM_Get_Hardware_Profile_Info_ExW(ulIndex, &LocalProfileInfo,
4916 ulFlags, hMachine);
4917 if (ret == CR_SUCCESS)
4918</