[SETUPAPI] Fix the coding style, annotations and debug messages
[reactos.git] / dll / win32 / setupapi / cfgmgr.c
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
27 #include "rpc_private.h"
28
29 /* Registry key and value names */
30 static const WCHAR Backslash[] = {'\\', 0};
31 static const WCHAR Class[] = {'C','l','a','s','s',0};
32
33 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
34 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
35 'C','o','n','t','r','o','l','\\',
36 'C','l','a','s','s',0};
37
38 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
39 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
40 'C','o','n','t','r','o','l','\\',
41 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
42
43 typedef struct _MACHINE_INFO
44 {
45 WCHAR szMachineName[SP_MAX_MACHINENAME_LENGTH];
46 RPC_BINDING_HANDLE BindingHandle;
47 HSTRING_TABLE StringTable;
48 BOOL bLocal;
49 } MACHINE_INFO, *PMACHINE_INFO;
50
51
52 typedef struct _LOG_CONF_INFO
53 {
54 ULONG ulMagic;
55 DEVINST dnDevInst;
56 ULONG ulFlags;
57 ULONG ulTag;
58 } LOG_CONF_INFO, *PLOG_CONF_INFO;
59
60 #define LOG_CONF_MAGIC 0x464E434C /* "LCNF" */
61
62
63 typedef struct _NOTIFY_DATA
64 {
65 ULONG ulMagic;
66 ULONG ulNotifyData;
67 } NOTIFY_DATA, *PNOTIFY_DATA;
68
69 #define NOTIFY_MAGIC 0x44556677
70
71
72 typedef struct _INTERNAL_RANGE
73 {
74 LIST_ENTRY ListEntry;
75 DWORDLONG ullStart;
76 DWORDLONG ullEnd;
77 } INTERNAL_RANGE, *PINTERNAL_RANGE;
78
79 typedef struct _INTERNAL_RANGE_LIST
80 {
81 ULONG ulMagic;
82 HANDLE hMutex;
83 LIST_ENTRY ListHead;
84 } INTERNAL_RANGE_LIST, *PINTERNAL_RANGE_LIST;
85
86 #define RANGE_LIST_MAGIC 0x33445566
87
88
89 static
90 BOOL
91 GuidToString(
92 _In_ LPGUID Guid,
93 _Out_ LPWSTR String)
94 {
95 LPWSTR lpString;
96
97 if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
98 return FALSE;
99
100 lstrcpyW(&String[1], lpString);
101
102 String[0] = '{';
103 String[MAX_GUID_STRING_LEN - 2] = '}';
104 String[MAX_GUID_STRING_LEN - 1] = UNICODE_NULL;
105
106 RpcStringFreeW(&lpString);
107
108 return TRUE;
109 }
110
111
112 static
113 CONFIGRET
114 RpcStatusToCmStatus(
115 _In_ RPC_STATUS Status)
116 {
117 return CR_FAILURE;
118 }
119
120
121 static
122 ULONG
123 GetRegistryPropertyType(
124 _In_ ULONG ulProperty)
125 {
126 switch (ulProperty)
127 {
128 case CM_DRP_DEVICEDESC:
129 case CM_DRP_SERVICE:
130 case CM_DRP_CLASS:
131 case CM_DRP_CLASSGUID:
132 case CM_DRP_DRIVER:
133 case CM_DRP_MFG:
134 case CM_DRP_FRIENDLYNAME:
135 case CM_DRP_LOCATION_INFORMATION:
136 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
137 case CM_DRP_ENUMERATOR_NAME:
138 case CM_DRP_SECURITY_SDS:
139 case CM_DRP_UI_NUMBER_DESC_FORMAT:
140 return REG_SZ;
141
142 case CM_DRP_HARDWAREID:
143 case CM_DRP_COMPATIBLEIDS:
144 case CM_DRP_UPPERFILTERS:
145 case CM_DRP_LOWERFILTERS:
146 return REG_MULTI_SZ;
147
148 case CM_DRP_CONFIGFLAGS:
149 case CM_DRP_CAPABILITIES:
150 case CM_DRP_UI_NUMBER:
151 case CM_DRP_LEGACYBUSTYPE:
152 case CM_DRP_BUSNUMBER:
153 case CM_DRP_DEVTYPE:
154 case CM_DRP_EXCLUSIVE:
155 case CM_DRP_CHARACTERISTICS:
156 case CM_DRP_ADDRESS:
157 case CM_DRP_REMOVAL_POLICY:
158 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT:
159 case CM_DRP_REMOVAL_POLICY_OVERRIDE:
160 case CM_DRP_INSTALL_STATE:
161 return REG_DWORD;
162
163 case CM_DRP_BUSTYPEGUID:
164 case CM_DRP_SECURITY:
165 case CM_DRP_DEVICE_POWER_DATA:
166 default:
167 return REG_BINARY;
168 }
169
170 return REG_NONE;
171 }
172
173
174 static
175 VOID
176 SplitDeviceInstanceId(
177 _In_ PWSTR pszDeviceInstanceId,
178 _Out_ PWSTR pszDeviceId,
179 _Out_ PWSTR pszInstanceId)
180 {
181 PWCHAR ptr;
182
183 wcscpy(pszDeviceId, pszDeviceInstanceId);
184
185 ptr = wcschr(pszDeviceId, L'\\');
186 if (ptr != NULL)
187 {
188 *ptr = UNICODE_NULL;
189 ptr++;
190
191 wcscpy(pszInstanceId, ptr);
192 }
193 else
194 {
195 *pszInstanceId = UNICODE_NULL;
196 }
197 }
198
199
200 static
201 CONFIGRET
202 GetDeviceInstanceKeyPath(
203 _In_ RPC_BINDING_HANDLE BindingHandle,
204 _In_ PWSTR pszDeviceInst,
205 _Out_ PWSTR pszKeyPath,
206 _Out_ PWSTR pszInstancePath,
207 _In_ ULONG ulHardwareProfile,
208 _In_ ULONG ulFlags)
209 {
210 PWSTR pszBuffer = NULL;
211 ULONG ulType = 0;
212 ULONG ulTransferLength, ulLength;
213 CONFIGRET ret = CR_SUCCESS;
214
215 TRACE("GetDeviceInstanceKeyPath()\n");
216
217 /* Allocate a buffer for the device id */
218 pszBuffer = MyMalloc(300 * sizeof(WCHAR));
219 if (pszBuffer == NULL)
220 {
221 ERR("MyMalloc() failed\n");
222 return CR_OUT_OF_MEMORY;
223 }
224
225 if (ulFlags & CM_REGISTRY_SOFTWARE)
226 {
227 /* Software Key Path */
228
229 if (ulFlags & CM_REGISTRY_CONFIG)
230 {
231 SplitDeviceInstanceId(pszDeviceInst,
232 pszBuffer,
233 pszInstancePath);
234
235 if (ulHardwareProfile == 0)
236 {
237 wsprintfW(pszKeyPath,
238 L"%s\\%s\\%s\\%s",
239 L"System\\CurrentControlSet\\Hardware Profiles",
240 L"Current",
241 L"System\\CurrentControlSet\\Enum",
242 pszBuffer);
243 }
244 else
245 {
246 wsprintfW(pszKeyPath,
247 L"%s\\%04lu\\%s\\%s",
248 L"System\\CurrentControlSet\\Hardware Profiles",
249 ulHardwareProfile,
250 L"System\\CurrentControlSet\\Enum",
251 pszBuffer);
252 }
253 }
254 else if (ulFlags & CM_REGISTRY_USER)
255 {
256 wsprintfW(pszKeyPath,
257 L"%s\\%s",
258 L"System\\CurrentControlSet\\Enum",
259 pszDeviceInst);
260
261 wcscpy(pszInstancePath,
262 L"Device Parameters");
263 }
264 else
265 {
266 SplitDeviceInstanceId(pszDeviceInst,
267 pszBuffer,
268 pszInstancePath);
269
270 wsprintfW(pszKeyPath,
271 L"%s\\%s",
272 L"System\\CurrentControlSet\\Enum",
273 pszBuffer);
274 }
275 }
276 else
277 {
278 /* Hardware Key Path */
279
280 ulTransferLength = 300 * sizeof(WCHAR);
281 ulLength = 300 * sizeof(WCHAR);
282 ret = PNP_GetDeviceRegProp(BindingHandle,
283 pszDeviceInst,
284 CM_DRP_DRIVER,
285 &ulType,
286 (PVOID)pszBuffer,
287 &ulTransferLength,
288 &ulLength,
289 0);
290 if (ret != CR_SUCCESS)
291 {
292 ERR("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret);
293 goto done;
294 }
295
296 TRACE("szBuffer: %S\n", pszBuffer);
297
298 SplitDeviceInstanceId(pszBuffer,
299 pszBuffer,
300 pszInstancePath);
301
302 TRACE("szBuffer: %S\n", pszBuffer);
303
304 if (ulFlags & CM_REGISTRY_CONFIG)
305 {
306 if (ulHardwareProfile == 0)
307 {
308 wsprintfW(pszKeyPath,
309 L"%s\\%s\\%s\\%s",
310 L"System\\CurrentControlSet\\Hardware Profiles",
311 L"Current",
312 L"System\\CurrentControlSet\\Control\\Class",
313 pszBuffer);
314 }
315 else
316 {
317 wsprintfW(pszKeyPath,
318 L"%s\\%04lu\\%s\\%s",
319 L"System\\CurrentControlSet\\Hardware Profiles",
320 ulHardwareProfile,
321 L"System\\CurrentControlSet\\Control\\Class",
322 pszBuffer);
323 }
324 }
325 else
326 {
327 wsprintfW(pszKeyPath,
328 L"%s\\%s",
329 L"System\\CurrentControlSet\\Control\\Class",
330 pszBuffer);
331 }
332 }
333
334 done:
335 if (pszBuffer != NULL)
336 MyFree(pszBuffer);
337
338 return ret;
339 }
340
341
342 BOOL
343 IsValidRangeList(
344 _In_ PINTERNAL_RANGE_LIST pRangeList)
345 {
346 BOOL bValid = TRUE;
347
348 if (pRangeList == NULL)
349 return FALSE;
350
351 _SEH2_TRY
352 {
353 if (pRangeList->ulMagic != RANGE_LIST_MAGIC)
354 bValid = FALSE;
355 }
356 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
357 {
358 bValid = FALSE;
359 }
360 _SEH2_END;
361
362 return bValid;
363 }
364
365
366 /***********************************************************************
367 * CMP_GetBlockedDriverInfo [SETUPAPI.@]
368 */
369 CONFIGRET
370 WINAPI
371 CMP_GetBlockedDriverInfo(
372 _Out_opt_ LPWSTR pszNames,
373 _Inout_ PULONG pulLength,
374 _In_ ULONG ulFlags,
375 _In_opt_ HMACHINE hMachine)
376 {
377 RPC_BINDING_HANDLE BindingHandle = NULL;
378 ULONG ulTransferLength;
379 CONFIGRET ret;
380
381 TRACE("CMP_GetBlockedDriverInfo(%p %p %lx %p)\n",
382 pszNames, pulLength, ulFlags, hMachine);
383
384 if (hMachine != NULL)
385 {
386 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
387 if (BindingHandle == NULL)
388 return CR_FAILURE;
389 }
390 else
391 {
392 if (!PnpGetLocalHandles(&BindingHandle, NULL))
393 return CR_FAILURE;
394 }
395
396 ulTransferLength = *pulLength;
397
398 RpcTryExcept
399 {
400 ret = PNP_GetBlockedDriverInfo(BindingHandle,
401 (PBYTE)pszNames,
402 &ulTransferLength,
403 pulLength,
404 ulFlags);
405 }
406 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
407 {
408 ret = RpcStatusToCmStatus(RpcExceptionCode());
409 }
410 RpcEndExcept;
411
412 return ret;
413 }
414
415
416 /***********************************************************************
417 * CMP_GetServerSideDeviceInstallFlags [SETUPAPI.@]
418 */
419 CONFIGRET
420 WINAPI
421 CMP_GetServerSideDeviceInstallFlags(
422 _Out_ PULONG pulSSDIFlags,
423 _In_ ULONG ulFlags,
424 _In_opt_ HMACHINE hMachine)
425 {
426 RPC_BINDING_HANDLE BindingHandle = NULL;
427 CONFIGRET ret;
428
429 TRACE("CMP_GetServerSideDeviceInstallFlags(%p %lx %p)\n",
430 pulSSDIFlags, ulFlags, hMachine);
431
432 if (pulSSDIFlags == NULL)
433 return CR_INVALID_POINTER;
434
435 if (ulFlags != 0)
436 return CR_INVALID_FLAG;
437
438 if (hMachine != NULL)
439 {
440 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
441 if (BindingHandle == NULL)
442 return CR_FAILURE;
443 }
444 else
445 {
446 if (!PnpGetLocalHandles(&BindingHandle, NULL))
447 return CR_FAILURE;
448 }
449
450 RpcTryExcept
451 {
452 ret = PNP_GetServerSideDeviceInstallFlags(BindingHandle,
453 pulSSDIFlags,
454 ulFlags);
455 }
456 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
457 {
458 ret = RpcStatusToCmStatus(RpcExceptionCode());
459 }
460 RpcEndExcept;
461
462 return ret;
463 }
464
465
466 /***********************************************************************
467 * CMP_Init_Detection [SETUPAPI.@]
468 */
469 CONFIGRET
470 WINAPI
471 CMP_Init_Detection(
472 _In_ ULONG ulMagic)
473 {
474 RPC_BINDING_HANDLE BindingHandle = NULL;
475 CONFIGRET ret;
476
477 TRACE("CMP_Init_Detection(%lu)\n", ulMagic);
478
479 if (ulMagic != CMP_MAGIC)
480 return CR_INVALID_DATA;
481
482 if (!PnpGetLocalHandles(&BindingHandle, NULL))
483 return CR_FAILURE;
484
485 RpcTryExcept
486 {
487 ret = PNP_InitDetection(BindingHandle);
488 }
489 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
490 {
491 ret = RpcStatusToCmStatus(RpcExceptionCode());
492 }
493 RpcEndExcept;
494
495 return ret;
496 }
497
498
499 /***********************************************************************
500 * CMP_RegisterNotification [SETUPAPI.@]
501 */
502 CONFIGRET
503 WINAPI
504 CMP_RegisterNotification(
505 _In_ HANDLE hRecipient,
506 _In_ LPVOID lpvNotificationFilter,
507 _In_ ULONG ulFlags,
508 _Out_ PHDEVNOTIFY phDevNotify)
509 {
510 RPC_BINDING_HANDLE BindingHandle = NULL;
511 PNOTIFY_DATA pNotifyData = NULL;
512 CONFIGRET ret = CR_SUCCESS;
513
514 TRACE("CMP_RegisterNotification(%p %p %lu %p)\n",
515 hRecipient, lpvNotificationFilter, ulFlags, phDevNotify);
516
517 if ((hRecipient == NULL) ||
518 (lpvNotificationFilter == NULL) ||
519 (phDevNotify == NULL))
520 return CR_INVALID_POINTER;
521
522 if (ulFlags & ~0x7)
523 return CR_INVALID_FLAG;
524
525 if (((PDEV_BROADCAST_HDR)lpvNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR))
526 return CR_INVALID_DATA;
527
528 if (!PnpGetLocalHandles(&BindingHandle, NULL))
529 return CR_FAILURE;
530
531 pNotifyData = HeapAlloc(GetProcessHeap(),
532 HEAP_ZERO_MEMORY,
533 sizeof(NOTIFY_DATA));
534 if (pNotifyData == NULL)
535 return CR_OUT_OF_MEMORY;
536
537 pNotifyData->ulMagic = NOTIFY_MAGIC;
538
539 /*
540 if (dwFlags & DEVICE_NOTIFY_SERVICE_HANDLE == DEVICE_NOTYFY_WINDOW_HANDLE)
541 {
542
543 }
544 else if (dwFlags & DEVICE_NOTIFY_SERVICE_HANDLE == DEVICE_NOTYFY_SERVICE_HANDLE)
545 {
546
547 }
548 */
549
550 RpcTryExcept
551 {
552 ret = PNP_RegisterNotification(BindingHandle,
553 ulFlags,
554 &pNotifyData->ulNotifyData);
555 }
556 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
557 {
558 ret = RpcStatusToCmStatus(RpcExceptionCode());
559 }
560 RpcEndExcept;
561
562 if (ret == CR_SUCCESS)
563 {
564 *phDevNotify = (HDEVNOTIFY)pNotifyData;
565 }
566 else
567 {
568 if (pNotifyData != NULL)
569 HeapFree(GetProcessHeap(), 0, pNotifyData);
570
571 *phDevNotify = (HDEVNOTIFY)NULL;
572 }
573
574 return ret;
575 }
576
577
578 /***********************************************************************
579 * CMP_Report_LogOn [SETUPAPI.@]
580 */
581 CONFIGRET
582 WINAPI
583 CMP_Report_LogOn(
584 _In_ DWORD dwMagic,
585 _In_ DWORD dwProcessId)
586 {
587 RPC_BINDING_HANDLE BindingHandle = NULL;
588 CONFIGRET ret = CR_SUCCESS;
589 BOOL bAdmin;
590 DWORD i;
591
592 TRACE("CMP_Report_LogOn(%lu %lu)\n", dwMagic, dwProcessId);
593
594 if (dwMagic != CMP_MAGIC)
595 return CR_INVALID_DATA;
596
597 if (!PnpGetLocalHandles(&BindingHandle, NULL))
598 return CR_FAILURE;
599
600 bAdmin = pSetupIsUserAdmin();
601
602 for (i = 0; i < 30; i++)
603 {
604 RpcTryExcept
605 {
606 ret = PNP_ReportLogOn(BindingHandle,
607 bAdmin,
608 dwProcessId);
609 }
610 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
611 {
612 ret = RpcStatusToCmStatus(RpcExceptionCode());
613 }
614 RpcEndExcept;
615
616 if (ret == CR_SUCCESS)
617 break;
618
619 Sleep(5000);
620 }
621
622 return ret;
623 }
624
625
626 /***********************************************************************
627 * CMP_UnregisterNotification [SETUPAPI.@]
628 */
629 CONFIGRET
630 WINAPI
631 CMP_UnregisterNotification(
632 _In_ HDEVNOTIFY hDevNotify)
633 {
634 RPC_BINDING_HANDLE BindingHandle = NULL;
635 PNOTIFY_DATA pNotifyData;
636 CONFIGRET ret = CR_SUCCESS;
637
638 TRACE("CMP_UnregisterNotification(%p)\n", hDevNotify);
639
640 pNotifyData = (PNOTIFY_DATA)hDevNotify;
641
642 if ((pNotifyData == NULL) ||
643 (pNotifyData->ulMagic != NOTIFY_MAGIC))
644 return CR_INVALID_POINTER;
645
646 if (!PnpGetLocalHandles(&BindingHandle, NULL))
647 return CR_FAILURE;
648
649 RpcTryExcept
650 {
651 ret = PNP_UnregisterNotification(BindingHandle,
652 pNotifyData->ulNotifyData);
653 }
654 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
655 {
656 ret = RpcStatusToCmStatus(RpcExceptionCode());
657 }
658 RpcEndExcept;
659
660 if (ret == CR_SUCCESS)
661 HeapFree(GetProcessHeap(), 0, pNotifyData);
662
663 return ret;
664 }
665
666
667 /***********************************************************************
668 * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
669 */
670 DWORD
671 WINAPI
672 CMP_WaitNoPendingInstallEvents(
673 _In_ DWORD dwTimeout)
674 {
675 HANDLE hEvent;
676 DWORD ret;
677
678 TRACE("CMP_WaitNoPendingInstallEvents(%lu)\n", dwTimeout);
679
680 hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
681 if (hEvent == NULL)
682 return WAIT_FAILED;
683
684 ret = WaitForSingleObject(hEvent, dwTimeout);
685 CloseHandle(hEvent);
686 return ret;
687 }
688
689
690 /***********************************************************************
691 * CMP_WaitServicesAvailable [SETUPAPI.@]
692 */
693 CONFIGRET
694 WINAPI
695 CMP_WaitServicesAvailable(
696 _In_opt_ HMACHINE hMachine)
697 {
698 RPC_BINDING_HANDLE BindingHandle = NULL;
699 CONFIGRET ret = CR_SUCCESS;
700 WORD Version;
701
702 TRACE("CMP_WaitServicesAvailable(%p)\n", hMachine);
703
704 if (hMachine != NULL)
705 {
706 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
707 if (BindingHandle == NULL)
708 return CR_FAILURE;
709 }
710 else
711 {
712 if (!PnpGetLocalHandles(&BindingHandle, NULL))
713 return CR_FAILURE;
714 }
715
716 RpcTryExcept
717 {
718 ret = PNP_GetVersion(BindingHandle, &Version);
719 }
720 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
721 {
722 ret = RpcStatusToCmStatus(RpcExceptionCode());
723 }
724 RpcEndExcept;
725
726 return ret;
727 }
728
729
730 /***********************************************************************
731 * CM_Add_Empty_Log_Conf [SETUPAPI.@]
732 */
733 CONFIGRET
734 WINAPI
735 CM_Add_Empty_Log_Conf(
736 _Out_ PLOG_CONF plcLogConf,
737 _In_ DEVINST dnDevInst,
738 _In_ PRIORITY Priority,
739 _In_ ULONG ulFlags)
740 {
741 TRACE("CM_Add_Empty_Log_Conf(%p %p %lu %lx)\n",
742 plcLogConf, dnDevInst, Priority, ulFlags);
743
744 return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
745 ulFlags, NULL);
746 }
747
748
749 /***********************************************************************
750 * CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
751 */
752 CONFIGRET
753 WINAPI CM_Add_Empty_Log_Conf_Ex(
754 _Out_ PLOG_CONF plcLogConf,
755 _In_ DEVINST dnDevInst,
756 _In_ PRIORITY Priority,
757 _In_ ULONG ulFlags,
758 _In_opt_ HMACHINE hMachine)
759 {
760 RPC_BINDING_HANDLE BindingHandle = NULL;
761 HSTRING_TABLE StringTable = NULL;
762 ULONG ulLogConfTag = 0;
763 LPWSTR lpDevInst;
764 PLOG_CONF_INFO pLogConfInfo;
765 CONFIGRET ret = CR_SUCCESS;
766
767 FIXME("CM_Add_Empty_Log_Conf_Ex(%p %p %lu %lx %p)\n",
768 plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
769
770 if (!pSetupIsUserAdmin())
771 return CR_ACCESS_DENIED;
772
773 if (plcLogConf == NULL)
774 return CR_INVALID_POINTER;
775
776 if (dnDevInst == 0)
777 return CR_INVALID_DEVINST;
778
779 if (Priority > 0xFFFF)
780 return CR_INVALID_PRIORITY;
781
782 if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
783 return CR_INVALID_FLAG;
784
785 if (hMachine != NULL)
786 {
787 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
788 if (BindingHandle == NULL)
789 return CR_FAILURE;
790
791 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
792 if (StringTable == 0)
793 return CR_FAILURE;
794 }
795 else
796 {
797 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
798 return CR_FAILURE;
799 }
800
801 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
802 if (lpDevInst == NULL)
803 return CR_INVALID_DEVNODE;
804
805 RpcTryExcept
806 {
807 ret = PNP_AddEmptyLogConf(BindingHandle, lpDevInst, Priority,
808 &ulLogConfTag, ulFlags);
809 }
810 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
811 {
812 ret = RpcStatusToCmStatus(RpcExceptionCode());
813 }
814 RpcEndExcept;
815
816 if (ret == CR_SUCCESS)
817 {
818 pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
819 if (pLogConfInfo == NULL)
820 {
821 ret = CR_OUT_OF_MEMORY;
822 }
823 else
824 {
825 pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
826 pLogConfInfo->dnDevInst = dnDevInst;
827 pLogConfInfo->ulFlags = ulFlags;
828 pLogConfInfo->ulTag = ulLogConfTag;
829
830 *plcLogConf = (LOG_CONF)pLogConfInfo;
831
832 ret = CR_SUCCESS;
833 }
834 }
835
836 return ret;
837 }
838
839
840 /***********************************************************************
841 * CM_Add_IDA [SETUPAPI.@]
842 */
843 CONFIGRET
844 WINAPI
845 CM_Add_IDA(
846 _In_ DEVINST dnDevInst,
847 _In_ PSTR pszID,
848 _In_ ULONG ulFlags)
849 {
850 TRACE("CM_Add_IDA(%p %s %lx)\n",
851 dnDevInst, debugstr_a(pszID), ulFlags);
852
853 return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
854 }
855
856
857 /***********************************************************************
858 * CM_Add_IDW [SETUPAPI.@]
859 */
860 CONFIGRET
861 WINAPI
862 CM_Add_IDW(
863 _In_ DEVINST dnDevInst,
864 _In_ PWSTR pszID,
865 _In_ ULONG ulFlags)
866 {
867 TRACE("CM_Add_IDW(%p %s %lx)\n",
868 dnDevInst, debugstr_w(pszID), ulFlags);
869
870 return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
871 }
872
873
874 /***********************************************************************
875 * CM_Add_ID_ExA [SETUPAPI.@]
876 */
877 CONFIGRET
878 WINAPI
879 CM_Add_ID_ExA(
880 _In_ DEVINST dnDevInst,
881 _In_ PSTR pszID,
882 _In_ ULONG ulFlags,
883 _In_opt_ HMACHINE hMachine)
884 {
885 PWSTR pszIDW;
886 CONFIGRET ret;
887
888 TRACE("CM_Add_ID_ExA(%p %s %lx %p)\n",
889 dnDevInst, debugstr_a(pszID), ulFlags, hMachine);
890
891 if (pSetupCaptureAndConvertAnsiArg(pszID, &pszIDW))
892 return CR_INVALID_DATA;
893
894 ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);
895
896 MyFree(pszIDW);
897
898 return ret;
899 }
900
901
902 /***********************************************************************
903 * CM_Add_ID_ExW [SETUPAPI.@]
904 */
905 CONFIGRET
906 WINAPI
907 CM_Add_ID_ExW(
908 _In_ DEVINST dnDevInst,
909 _In_ PWSTR pszID,
910 _In_ ULONG ulFlags,
911 _In_opt_ HMACHINE hMachine)
912 {
913 RPC_BINDING_HANDLE BindingHandle = NULL;
914 HSTRING_TABLE StringTable = NULL;
915 LPWSTR lpDevInst;
916 CONFIGRET ret;
917
918 TRACE("CM_Add_ID_ExW(%p %s %lx %p)\n",
919 dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
920
921 if (!pSetupIsUserAdmin())
922 return CR_ACCESS_DENIED;
923
924 if (dnDevInst == 0)
925 return CR_INVALID_DEVINST;
926
927 if (pszID == NULL)
928 return CR_INVALID_POINTER;
929
930 if (ulFlags & ~CM_ADD_ID_BITS)
931 return CR_INVALID_FLAG;
932
933 if (hMachine != NULL)
934 {
935 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
936 if (BindingHandle == NULL)
937 return CR_FAILURE;
938
939 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
940 if (StringTable == 0)
941 return CR_FAILURE;
942 }
943 else
944 {
945 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
946 return CR_FAILURE;
947 }
948
949 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
950 if (lpDevInst == NULL)
951 return CR_INVALID_DEVNODE;
952
953 RpcTryExcept
954 {
955 ret = PNP_AddID(BindingHandle,
956 lpDevInst,
957 pszID,
958 ulFlags);
959 }
960 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
961 {
962 ret = RpcStatusToCmStatus(RpcExceptionCode());
963 }
964 RpcEndExcept;
965
966 return ret;
967 }
968
969
970 /***********************************************************************
971 * CM_Add_Range [SETUPAPI.@]
972 */
973 CONFIGRET
974 WINAPI
975 CM_Add_Range(
976 _In_ DWORDLONG ullStartValue,
977 _In_ DWORDLONG ullEndValue,
978 _In_ RANGE_LIST rlh,
979 _In_ ULONG ulFlags)
980 {
981 PINTERNAL_RANGE_LIST pRangeList;
982 PINTERNAL_RANGE pRange;
983 CONFIGRET ret = CR_SUCCESS;
984
985 FIXME("CM_Add_Range(%I64u %I64u %p %lx)\n",
986 ullStartValue, ullEndValue, rlh, ulFlags);
987
988 pRangeList = (PINTERNAL_RANGE_LIST)rlh;
989
990 if (!IsValidRangeList(pRangeList))
991 return CR_INVALID_RANGE_LIST;
992
993 if (ulFlags & ~CM_ADD_RANGE_BITS)
994 return CR_INVALID_FLAG;
995
996 if (ullEndValue < ullStartValue)
997 return CR_INVALID_RANGE;
998
999 /* Lock the range list */
1000 WaitForSingleObject(pRangeList->hMutex, INFINITE);
1001
1002 /* Allocate the new range */
1003 pRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
1004 if (pRange == NULL)
1005 {
1006 ret = CR_OUT_OF_MEMORY;
1007 goto done;
1008 }
1009
1010 pRange->ullStart = ullStartValue;
1011 pRange->ullEnd = ullEndValue;
1012
1013 /* Insert the range */
1014 if (IsListEmpty(&pRangeList->ListHead))
1015 {
1016 InsertTailList(&pRangeList->ListHead, &pRange->ListEntry);
1017 }
1018 else
1019 {
1020
1021 }
1022
1023 done:
1024 /* Unlock the range list */
1025 ReleaseMutex(pRangeList->hMutex);
1026
1027 return ret;
1028 }
1029
1030
1031 /***********************************************************************
1032 * CM_Add_Res_Des [SETUPAPI.@]
1033 */
1034 CONFIGRET
1035 WINAPI
1036 CM_Add_Res_Des(
1037 _Out_opt_ PRES_DES prdResDes,
1038 _In_ LOG_CONF lcLogConf,
1039 _In_ RESOURCEID ResourceID,
1040 _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1041 _In_ ULONG ResourceLen,
1042 _In_ ULONG ulFlags)
1043 {
1044 TRACE("CM_Add_Res_Des(%p %p %lu %p %lu %lx)\n",
1045 prdResDes, lcLogConf, ResourceID, ResourceData, ResourceLen, ulFlags);
1046
1047 return CM_Add_Res_Des_Ex(prdResDes, lcLogConf, ResourceID, ResourceData,
1048 ResourceLen, ulFlags, NULL);
1049 }
1050
1051
1052 /***********************************************************************
1053 * CM_Add_Res_Des_Ex [SETUPAPI.@]
1054 */
1055 CONFIGRET
1056 WINAPI
1057 CM_Add_Res_Des_Ex(
1058 _Out_opt_ PRES_DES prdResDes,
1059 _In_ LOG_CONF lcLogConf,
1060 _In_ RESOURCEID ResourceID,
1061 _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1062 _In_ ULONG ResourceLen,
1063 _In_ ULONG ulFlags,
1064 _In_opt_ HMACHINE hMachine)
1065 {
1066 FIXME("CM_Add_Res_Des_Ex(%p %p %lu %p %lu %lx %p)\n",
1067 prdResDes, lcLogConf, ResourceID,
1068 ResourceData, ResourceLen, ulFlags, hMachine);
1069
1070 return CR_CALL_NOT_IMPLEMENTED;
1071 }
1072
1073
1074 /***********************************************************************
1075 * CM_Connect_MachineA [SETUPAPI.@]
1076 */
1077 CONFIGRET
1078 WINAPI
1079 CM_Connect_MachineA(
1080 _In_opt_ PCSTR UNCServerName,
1081 _Out_ PHMACHINE phMachine)
1082 {
1083 PWSTR pServerNameW;
1084 CONFIGRET ret;
1085
1086 TRACE("CM_Connect_MachineA(%s %p)\n",
1087 debugstr_a(UNCServerName), phMachine);
1088
1089 if (UNCServerName == NULL || *UNCServerName == 0)
1090 return CM_Connect_MachineW(NULL, phMachine);
1091
1092 if (pSetupCaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
1093 return CR_INVALID_DATA;
1094
1095 ret = CM_Connect_MachineW(pServerNameW, phMachine);
1096
1097 MyFree(pServerNameW);
1098
1099 return ret;
1100 }
1101
1102
1103 /***********************************************************************
1104 * CM_Connect_MachineW [SETUPAPI.@]
1105 */
1106 CONFIGRET
1107 WINAPI
1108 CM_Connect_MachineW(
1109 _In_opt_ PCWSTR UNCServerName,
1110 _Out_ PHMACHINE phMachine)
1111 {
1112 PMACHINE_INFO pMachine;
1113
1114 TRACE("CM_Connect_MachineW(%s %p)\n",
1115 debugstr_w(UNCServerName), phMachine);
1116
1117 if (phMachine == NULL)
1118 return CR_INVALID_POINTER;
1119
1120 *phMachine = NULL;
1121
1122 pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
1123 if (pMachine == NULL)
1124 return CR_OUT_OF_MEMORY;
1125
1126 if (UNCServerName == NULL || *UNCServerName == 0)
1127 {
1128 pMachine->bLocal = TRUE;
1129
1130 /* FIXME: store the computers name in pMachine->szMachineName */
1131
1132 if (!PnpGetLocalHandles(&pMachine->BindingHandle,
1133 &pMachine->StringTable))
1134 {
1135 HeapFree(GetProcessHeap(), 0, pMachine);
1136 return CR_FAILURE;
1137 }
1138 }
1139 else
1140 {
1141 pMachine->bLocal = FALSE;
1142 if (wcslen(UNCServerName) >= SP_MAX_MACHINENAME_LENGTH - 1)
1143 {
1144 HeapFree(GetProcessHeap(), 0, pMachine);
1145 return CR_INVALID_MACHINENAME;
1146 }
1147 lstrcpyW(pMachine->szMachineName, UNCServerName);
1148
1149 pMachine->StringTable = pSetupStringTableInitialize();
1150 if (pMachine->StringTable == NULL)
1151 {
1152 HeapFree(GetProcessHeap(), 0, pMachine);
1153 return CR_FAILURE;
1154 }
1155
1156 pSetupStringTableAddString(pMachine->StringTable, L"PLT", 1);
1157
1158 if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
1159 {
1160 pSetupStringTableDestroy(pMachine->StringTable);
1161 HeapFree(GetProcessHeap(), 0, pMachine);
1162 return CR_INVALID_MACHINENAME;
1163 }
1164 }
1165
1166 *phMachine = (PHMACHINE)pMachine;
1167
1168 return CR_SUCCESS;
1169 }
1170
1171
1172 /***********************************************************************
1173 * CM_Create_DevNodeA [SETUPAPI.@]
1174 */
1175 CONFIGRET
1176 WINAPI
1177 CM_Create_DevNodeA(
1178 _Out_ PDEVINST pdnDevInst,
1179 _In_ DEVINSTID_A pDeviceID,
1180 _In_ DEVINST dnParent,
1181 _In_ ULONG ulFlags)
1182 {
1183 TRACE("CM_Create_DevNodeA(%p %s %p %lx)\n",
1184 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
1185
1186 return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
1187 ulFlags, NULL);
1188 }
1189
1190
1191 /***********************************************************************
1192 * CM_Create_DevNodeW [SETUPAPI.@]
1193 */
1194 CONFIGRET
1195 WINAPI
1196 CM_Create_DevNodeW(
1197 _Out_ PDEVINST pdnDevInst,
1198 _In_ DEVINSTID_W pDeviceID,
1199 _In_ DEVINST dnParent,
1200 _In_ ULONG ulFlags)
1201 {
1202 TRACE("CM_Create_DevNodeW(%p %s %p %lx)\n",
1203 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
1204
1205 return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
1206 ulFlags, NULL);
1207 }
1208
1209
1210 /***********************************************************************
1211 * CM_Create_DevNode_ExA [SETUPAPI.@]
1212 */
1213 CONFIGRET
1214 WINAPI
1215 CM_Create_DevNode_ExA(
1216 _Out_ PDEVINST pdnDevInst,
1217 _In_ DEVINSTID_A pDeviceID,
1218 _In_ DEVINST dnParent,
1219 _In_ ULONG ulFlags,
1220 _In_opt_ HANDLE hMachine)
1221 {
1222 DEVINSTID_W pDeviceIDW;
1223 CONFIGRET ret;
1224
1225 TRACE("CM_Create_DevNode_ExA(%p %s %p %lx %p)\n",
1226 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
1227
1228 if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
1229 return CR_INVALID_DATA;
1230
1231 ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
1232 hMachine);
1233
1234 MyFree(pDeviceIDW);
1235
1236 return ret;
1237 }
1238
1239
1240 /***********************************************************************
1241 * CM_Create_DevNode_ExW [SETUPAPI.@]
1242 */
1243 CONFIGRET
1244 WINAPI
1245 CM_Create_DevNode_ExW(
1246 _Out_ PDEVINST pdnDevInst,
1247 _In_ DEVINSTID_W pDeviceID,
1248 _In_ DEVINST dnParent,
1249 _In_ ULONG ulFlags,
1250 _In_opt_ HANDLE hMachine)
1251 {
1252 RPC_BINDING_HANDLE BindingHandle = NULL;
1253 HSTRING_TABLE StringTable = NULL;
1254 LPWSTR lpParentDevInst;
1255 CONFIGRET ret = CR_SUCCESS;
1256 WCHAR szLocalDeviceID[MAX_DEVICE_ID_LEN];
1257
1258 TRACE("CM_Create_DevNode_ExW(%p %s %p %lx %p)\n",
1259 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
1260
1261 if (!pSetupIsUserAdmin())
1262 return CR_ACCESS_DENIED;
1263
1264 if (pdnDevInst == NULL)
1265 return CR_INVALID_POINTER;
1266
1267 if (pDeviceID == NULL || wcslen(pDeviceID) == 0 || wcslen(pDeviceID) >= MAX_DEVICE_ID_LEN)
1268 return CR_INVALID_DEVICE_ID;
1269
1270 if (dnParent == 0)
1271 return CR_INVALID_DEVNODE;
1272
1273 if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
1274 return CR_INVALID_FLAG;
1275
1276 if (hMachine != NULL)
1277 {
1278 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1279 if (BindingHandle == NULL)
1280 return CR_FAILURE;
1281
1282 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1283 if (StringTable == 0)
1284 return CR_FAILURE;
1285 }
1286 else
1287 {
1288 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1289 return CR_FAILURE;
1290 }
1291
1292 lpParentDevInst = pSetupStringTableStringFromId(StringTable, dnParent);
1293 if (lpParentDevInst == NULL)
1294 return CR_INVALID_DEVNODE;
1295
1296 wcscpy(szLocalDeviceID, pDeviceID);
1297
1298 RpcTryExcept
1299 {
1300 ret = PNP_CreateDevInst(BindingHandle,
1301 szLocalDeviceID,
1302 lpParentDevInst,
1303 MAX_DEVICE_ID_LEN,
1304 ulFlags);
1305 }
1306 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1307 {
1308 ret = RpcStatusToCmStatus(RpcExceptionCode());
1309 }
1310 RpcEndExcept;
1311
1312 if (ret == CR_SUCCESS)
1313 {
1314 /* If CM_CREATE_DEVINST_GENERATE_ID was passed in, PNP_CreateDevInst
1315 * will return the generated device ID in szLocalDeviceID */
1316 *pdnDevInst = pSetupStringTableAddString(StringTable, szLocalDeviceID, 1);
1317 if (*pdnDevInst == 0)
1318 ret = CR_NO_SUCH_DEVNODE;
1319 }
1320
1321 return ret;
1322 }
1323
1324
1325 /***********************************************************************
1326 * CM_Create_Range_List [SETUPAPI.@]
1327 */
1328 CONFIGRET
1329 WINAPI
1330 CM_Create_Range_List(
1331 _Out_ PRANGE_LIST prlh,
1332 _In_ ULONG ulFlags)
1333 {
1334 PINTERNAL_RANGE_LIST pRangeList = NULL;
1335
1336 FIXME("CM_Create_Range_List(%p %lx)\n",
1337 prlh, ulFlags);
1338
1339 if (ulFlags != 0)
1340 return CR_INVALID_FLAG;
1341
1342 if (prlh == NULL)
1343 return CR_INVALID_POINTER;
1344
1345 /* Allocate the range list */
1346 pRangeList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(INTERNAL_RANGE_LIST));
1347 if (pRangeList == NULL)
1348 return CR_OUT_OF_MEMORY;
1349
1350 /* Set the magic value */
1351 pRangeList->ulMagic = RANGE_LIST_MAGIC;
1352
1353 /* Initialize the mutex for synchonized access */
1354 pRangeList->hMutex = CreateMutex(NULL, FALSE, NULL);
1355 if (pRangeList->hMutex == NULL)
1356 {
1357 HeapFree(GetProcessHeap(), 0, pRangeList);
1358 return CR_FAILURE;
1359 }
1360
1361 InitializeListHead(&pRangeList->ListHead);
1362
1363 *prlh = (RANGE_LIST)pRangeList;
1364
1365 return CR_SUCCESS;
1366 }
1367
1368
1369 /***********************************************************************
1370 * CM_Delete_Class_Key [SETUPAPI.@]
1371 */
1372 CONFIGRET
1373 WINAPI
1374 CM_Delete_Class_Key(
1375 _In_ LPGUID ClassGuid,
1376 _In_ ULONG ulFlags)
1377 {
1378 TRACE("CM_Delete_Class_Key(%p %lx)\n",
1379 ClassGuid, ulFlags);
1380
1381 return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
1382 }
1383
1384
1385 /***********************************************************************
1386 * CM_Delete_Class_Key_Ex [SETUPAPI.@]
1387 */
1388 CONFIGRET
1389 WINAPI
1390 CM_Delete_Class_Key_Ex(
1391 _In_ LPGUID ClassGuid,
1392 _In_ ULONG ulFlags,
1393 _In_opt_ HANDLE hMachine)
1394 {
1395 WCHAR szGuidString[MAX_GUID_STRING_LEN];
1396 RPC_BINDING_HANDLE BindingHandle = NULL;
1397 CONFIGRET ret;
1398
1399 TRACE("CM_Delete_Class_Key_Ex(%p %lx %p)\n",
1400 ClassGuid, ulFlags, hMachine);
1401
1402 if (ClassGuid == NULL)
1403 return CR_INVALID_POINTER;
1404
1405 if (ulFlags & ~CM_DELETE_CLASS_BITS)
1406 return CR_INVALID_FLAG;
1407
1408 if (!GuidToString(ClassGuid, szGuidString))
1409 return CR_INVALID_DATA;
1410
1411 if (hMachine != NULL)
1412 {
1413 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1414 if (BindingHandle == NULL)
1415 return CR_FAILURE;
1416 }
1417 else
1418 {
1419 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1420 return CR_FAILURE;
1421 }
1422
1423 RpcTryExcept
1424 {
1425 ret = PNP_DeleteClassKey(BindingHandle,
1426 szGuidString,
1427 ulFlags);
1428 }
1429 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1430 {
1431 ret = RpcStatusToCmStatus(RpcExceptionCode());
1432 }
1433 RpcEndExcept;
1434
1435 return ret;
1436 }
1437
1438
1439 /***********************************************************************
1440 * CM_Delete_DevNode_Key [SETUPAPI.@]
1441 */
1442 CONFIGRET
1443 WINAPI
1444 CM_Delete_DevNode_Key(
1445 _In_ DEVNODE dnDevNode,
1446 _In_ ULONG ulHardwareProfile,
1447 _In_ ULONG ulFlags)
1448 {
1449 TRACE("CM_Delete_DevNode_Key(%p %lu %lx)\n",
1450 dnDevNode, ulHardwareProfile, ulFlags);
1451
1452 return CM_Delete_DevNode_Key_Ex(dnDevNode, ulHardwareProfile, ulFlags,
1453 NULL);
1454 }
1455
1456
1457 /***********************************************************************
1458 * CM_Delete_DevNode_Key_Ex [SETUPAPI.@]
1459 */
1460 CONFIGRET
1461 WINAPI
1462 CM_Delete_DevNode_Key_Ex(
1463 _In_ DEVNODE dnDevNode,
1464 _In_ ULONG ulHardwareProfile,
1465 _In_ ULONG ulFlags,
1466 _In_opt_ HANDLE hMachine)
1467 {
1468 FIXME("CM_Delete_DevNode_Key_Ex(%p %lu %lx %p)\n",
1469 dnDevNode, ulHardwareProfile, ulFlags, hMachine);
1470
1471 return CR_CALL_NOT_IMPLEMENTED;
1472 }
1473
1474
1475 /***********************************************************************
1476 * CM_Delete_Range [SETUPAPI.@]
1477 */
1478 CONFIGRET
1479 WINAPI
1480 CM_Delete_Range(
1481 _In_ DWORDLONG ullStartValue,
1482 _In_ DWORDLONG ullEndValue,
1483 _In_ RANGE_LIST rlh,
1484 _In_ ULONG ulFlags)
1485 {
1486 FIXME("CM_Delete_Range(%I64u %I64u %p %lx)\n",
1487 ullStartValue, ullEndValue, rlh, ulFlags);
1488
1489 return CR_CALL_NOT_IMPLEMENTED;
1490 }
1491
1492
1493 /***********************************************************************
1494 * CM_Disable_DevNode [SETUPAPI.@]
1495 */
1496 CONFIGRET
1497 WINAPI
1498 CM_Disable_DevNode(
1499 _In_ DEVINST dnDevInst,
1500 _In_ ULONG ulFlags)
1501 {
1502 TRACE("CM_Disable_DevNode(%p %lx)\n",
1503 dnDevInst, ulFlags);
1504
1505 return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1506 }
1507
1508
1509 /***********************************************************************
1510 * CM_Disable_DevNode_Ex [SETUPAPI.@]
1511 */
1512 CONFIGRET
1513 WINAPI
1514 CM_Disable_DevNode_Ex(
1515 _In_ DEVINST dnDevInst,
1516 _In_ ULONG ulFlags,
1517 _In_opt_ HMACHINE hMachine)
1518 {
1519 RPC_BINDING_HANDLE BindingHandle = NULL;
1520 HSTRING_TABLE StringTable = NULL;
1521 LPWSTR lpDevInst;
1522 CONFIGRET ret;
1523
1524 FIXME("CM_Disable_DevNode_Ex(%p %lx %p)\n",
1525 dnDevInst, ulFlags, hMachine);
1526
1527 if (!pSetupIsUserAdmin())
1528 return CR_ACCESS_DENIED;
1529
1530 if (dnDevInst == 0)
1531 return CR_INVALID_DEVINST;
1532
1533 if (ulFlags != 0)
1534 return CR_INVALID_FLAG;
1535
1536 if (hMachine != NULL)
1537 {
1538 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1539 if (BindingHandle == NULL)
1540 return CR_FAILURE;
1541
1542 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1543 if (StringTable == 0)
1544 return CR_FAILURE;
1545 }
1546 else
1547 {
1548 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1549 return CR_FAILURE;
1550 }
1551
1552 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1553 if (lpDevInst == NULL)
1554 return CR_INVALID_DEVNODE;
1555
1556 RpcTryExcept
1557 {
1558 ret = PNP_DeviceInstanceAction(BindingHandle,
1559 PNP_DEVINST_DISABLE,
1560 ulFlags,
1561 lpDevInst,
1562 NULL);
1563 }
1564 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1565 {
1566 ret = RpcStatusToCmStatus(RpcExceptionCode());
1567 }
1568 RpcEndExcept;
1569
1570 return ret;
1571 }
1572
1573
1574 /***********************************************************************
1575 * CM_Disconnect_Machine [SETUPAPI.@]
1576 */
1577 CONFIGRET
1578 WINAPI
1579 CM_Disconnect_Machine(
1580 _In_opt_ HMACHINE hMachine)
1581 {
1582 PMACHINE_INFO pMachine;
1583
1584 TRACE("CM_Disconnect_Machine(%p)\n", hMachine);
1585
1586 pMachine = (PMACHINE_INFO)hMachine;
1587 if (pMachine == NULL)
1588 return CR_SUCCESS;
1589
1590 if (pMachine->bLocal == FALSE)
1591 {
1592 if (pMachine->StringTable != NULL)
1593 pSetupStringTableDestroy(pMachine->StringTable);
1594
1595 if (!PnpUnbindRpc(pMachine->BindingHandle))
1596 return CR_ACCESS_DENIED;
1597 }
1598
1599 HeapFree(GetProcessHeap(), 0, pMachine);
1600
1601 return CR_SUCCESS;
1602 }
1603
1604
1605 /***********************************************************************
1606 * CM_Dup_Range_List [SETUPAPI.@]
1607 */
1608 CONFIGRET
1609 WINAPI
1610 CM_Dup_Range_List(
1611 _In_ RANGE_LIST rlhOld,
1612 _In_ RANGE_LIST rlhNew,
1613 _In_ ULONG ulFlags)
1614 {
1615 FIXME("CM_Dup_Range_List(%p %p %lx)\n",
1616 rlhOld, rlhNew, ulFlags);
1617
1618 return CR_CALL_NOT_IMPLEMENTED;
1619 }
1620
1621
1622 /***********************************************************************
1623 * CM_Enable_DevNode [SETUPAPI.@]
1624 */
1625 CONFIGRET
1626 WINAPI
1627 CM_Enable_DevNode(
1628 _In_ DEVINST dnDevInst,
1629 _In_ ULONG ulFlags)
1630 {
1631 TRACE("CM_Enable_DevNode(%p %lx)\n",
1632 dnDevInst, ulFlags);
1633
1634 return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1635 }
1636
1637
1638 /***********************************************************************
1639 * CM_Enable_DevNode_Ex [SETUPAPI.@]
1640 */
1641 CONFIGRET
1642 WINAPI
1643 CM_Enable_DevNode_Ex(
1644 _In_ DEVINST dnDevInst,
1645 _In_ ULONG ulFlags,
1646 _In_opt_ HMACHINE hMachine)
1647 {
1648 RPC_BINDING_HANDLE BindingHandle = NULL;
1649 HSTRING_TABLE StringTable = NULL;
1650 LPWSTR lpDevInst;
1651 CONFIGRET ret;
1652
1653 TRACE("CM_Enable_DevNode_Ex(%p %lx %p)\n",
1654 dnDevInst, ulFlags, hMachine);
1655
1656 if (!pSetupIsUserAdmin())
1657 return CR_ACCESS_DENIED;
1658
1659 if (dnDevInst == 0)
1660 return CR_INVALID_DEVINST;
1661
1662 if (ulFlags != 0)
1663 return CR_INVALID_FLAG;
1664
1665 if (hMachine != NULL)
1666 {
1667 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1668 if (BindingHandle == NULL)
1669 return CR_FAILURE;
1670
1671 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1672 if (StringTable == 0)
1673 return CR_FAILURE;
1674 }
1675 else
1676 {
1677 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1678 return CR_FAILURE;
1679 }
1680
1681 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1682 if (lpDevInst == NULL)
1683 return CR_INVALID_DEVNODE;
1684
1685 RpcTryExcept
1686 {
1687 ret = PNP_DeviceInstanceAction(BindingHandle,
1688 PNP_DEVINST_ENABLE,
1689 ulFlags,
1690 lpDevInst,
1691 NULL);
1692 }
1693 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1694 {
1695 ret = RpcStatusToCmStatus(RpcExceptionCode());
1696 }
1697 RpcEndExcept;
1698
1699 return ret;
1700 }
1701
1702
1703 /***********************************************************************
1704 * CM_Enumerate_Classes [SETUPAPI.@]
1705 */
1706 CONFIGRET
1707 WINAPI
1708 CM_Enumerate_Classes(
1709 _In_ ULONG ulClassIndex,
1710 _Out_ LPGUID ClassGuid,
1711 _In_ ULONG ulFlags)
1712 {
1713 TRACE("CM_Enumerate_Classes(%lx %p %lx)\n",
1714 ulClassIndex, ClassGuid, ulFlags);
1715
1716 return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
1717 }
1718
1719
1720 /***********************************************************************
1721 * CM_Enumerate_Classes_Ex [SETUPAPI.@]
1722 */
1723 CONFIGRET
1724 WINAPI
1725 CM_Enumerate_Classes_Ex(
1726 _In_ ULONG ulClassIndex,
1727 _Out_ LPGUID ClassGuid,
1728 _In_ ULONG ulFlags,
1729 _In_opt_ HMACHINE hMachine)
1730 {
1731 WCHAR szBuffer[MAX_GUID_STRING_LEN];
1732 RPC_BINDING_HANDLE BindingHandle = NULL;
1733 CONFIGRET ret = CR_SUCCESS;
1734 ULONG ulLength = MAX_GUID_STRING_LEN;
1735
1736 TRACE("CM_Enumerate_Classes_Ex(%lx %p %lx %p)\n",
1737 ulClassIndex, ClassGuid, ulFlags, hMachine);
1738
1739 if (ClassGuid == NULL)
1740 return CR_INVALID_POINTER;
1741
1742 if (ulFlags != 0)
1743 return CR_INVALID_FLAG;
1744
1745 if (hMachine != NULL)
1746 {
1747 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1748 if (BindingHandle == NULL)
1749 return CR_FAILURE;
1750 }
1751 else
1752 {
1753 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1754 return CR_FAILURE;
1755 }
1756
1757 RpcTryExcept
1758 {
1759 ret = PNP_EnumerateSubKeys(BindingHandle,
1760 PNP_CLASS_SUBKEYS,
1761 ulClassIndex,
1762 szBuffer,
1763 MAX_GUID_STRING_LEN,
1764 &ulLength,
1765 ulFlags);
1766 }
1767 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1768 {
1769 ret = RpcStatusToCmStatus(RpcExceptionCode());
1770 }
1771 RpcEndExcept;
1772
1773 if (ret == CR_SUCCESS)
1774 {
1775 /* Remove the {} */
1776 szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
1777
1778 /* Convert the buffer to a GUID */
1779 if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
1780 return CR_FAILURE;
1781 }
1782
1783 return ret;
1784 }
1785
1786
1787 /***********************************************************************
1788 * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
1789 */
1790 CONFIGRET
1791 WINAPI
1792 CM_Enumerate_EnumeratorsA(
1793 _In_ ULONG ulEnumIndex,
1794 _Out_writes_(*pulLength) PCHAR Buffer,
1795 _Inout_ PULONG pulLength,
1796 _In_ ULONG ulFlags)
1797 {
1798 TRACE("CM_Enumerate_EnumeratorsA(%lu %p %p %lx)\n",
1799 ulEnumIndex, Buffer, pulLength, ulFlags);
1800
1801 return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
1802 ulFlags, NULL);
1803 }
1804
1805
1806 /***********************************************************************
1807 * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
1808 */
1809 CONFIGRET
1810 WINAPI
1811 CM_Enumerate_EnumeratorsW(
1812 _In_ ULONG ulEnumIndex,
1813 _Out_writes_(*pulLength) PWCHAR Buffer,
1814 _Inout_ PULONG pulLength,
1815 _In_ ULONG ulFlags)
1816 {
1817 TRACE("CM_Enumerate_EnumeratorsW(%lu %p %p %lx)\n",
1818 ulEnumIndex, Buffer, pulLength, ulFlags);
1819
1820 return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
1821 ulFlags, NULL);
1822 }
1823
1824
1825 /***********************************************************************
1826 * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
1827 */
1828 CONFIGRET
1829 WINAPI
1830 CM_Enumerate_Enumerators_ExA(
1831 _In_ ULONG ulEnumIndex,
1832 _Out_writes_(*pulLength) PCHAR Buffer,
1833 _Inout_ PULONG pulLength,
1834 _In_ ULONG ulFlags,
1835 _In_opt_ HMACHINE hMachine)
1836 {
1837 WCHAR szBuffer[MAX_DEVICE_ID_LEN];
1838 ULONG ulOrigLength;
1839 ULONG ulLength;
1840 CONFIGRET ret = CR_SUCCESS;
1841
1842 TRACE("CM_Enumerate_Enumerators_ExA(%lu %p %p %lx %p)\n",
1843 ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
1844
1845 if (Buffer == NULL || pulLength == NULL)
1846 return CR_INVALID_POINTER;
1847
1848 if (ulFlags != 0)
1849 return CR_INVALID_FLAG;
1850
1851 ulOrigLength = *pulLength;
1852 *pulLength = 0;
1853
1854 ulLength = MAX_DEVICE_ID_LEN;
1855 ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
1856 ulFlags, hMachine);
1857 if (ret == CR_SUCCESS)
1858 {
1859 if (WideCharToMultiByte(CP_ACP,
1860 0,
1861 szBuffer,
1862 ulLength,
1863 Buffer,
1864 ulOrigLength,
1865 NULL,
1866 NULL) == 0)
1867 ret = CR_FAILURE;
1868 else
1869 *pulLength = lstrlenA(Buffer) + 1;
1870 }
1871
1872 return ret;
1873 }
1874
1875
1876 /***********************************************************************
1877 * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
1878 */
1879 CONFIGRET
1880 WINAPI
1881 CM_Enumerate_Enumerators_ExW(
1882 _In_ ULONG ulEnumIndex,
1883 _Out_writes_(*pulLength) PWCHAR Buffer,
1884 _Inout_ PULONG pulLength,
1885 _In_ ULONG ulFlags,
1886 _In_opt_ HMACHINE hMachine)
1887 {
1888 RPC_BINDING_HANDLE BindingHandle = NULL;
1889 CONFIGRET ret;
1890
1891 TRACE("CM_Enumerate_Enumerators_ExW(%lu %p %p %lx %p)\n",
1892 ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
1893
1894 if (Buffer == NULL || pulLength == NULL)
1895 return CR_INVALID_POINTER;
1896
1897 if (ulFlags != 0)
1898 return CR_INVALID_FLAG;
1899
1900 *Buffer = UNICODE_NULL;
1901
1902 if (hMachine != NULL)
1903 {
1904 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1905 if (BindingHandle == NULL)
1906 return CR_FAILURE;
1907 }
1908 else
1909 {
1910 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1911 return CR_FAILURE;
1912 }
1913
1914 RpcTryExcept
1915 {
1916 ret = PNP_EnumerateSubKeys(BindingHandle,
1917 PNP_ENUMERATOR_SUBKEYS,
1918 ulEnumIndex,
1919 Buffer,
1920 *pulLength,
1921 pulLength,
1922 ulFlags);
1923 }
1924 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1925 {
1926 ret = RpcStatusToCmStatus(RpcExceptionCode());
1927 }
1928 RpcEndExcept;
1929
1930 return ret;
1931 }
1932
1933
1934 /***********************************************************************
1935 * CM_Find_Range [SETUPAPI.@]
1936 */
1937 CONFIGRET
1938 WINAPI
1939 CM_Find_Range(
1940 _Out_ PDWORDLONG pullStart,
1941 _In_ DWORDLONG ullStart,
1942 _In_ ULONG ulLength,
1943 _In_ DWORDLONG ullAlignment,
1944 _In_ DWORDLONG ullEnd,
1945 _In_ RANGE_LIST rlh,
1946 _In_ ULONG ulFlags)
1947 {
1948 FIXME("CM_Find_Range(%p %I64u %lu %I64u %I64u %p %lx)\n",
1949 pullStart, ullStart, ulLength, ullAlignment, ullEnd, rlh, ulFlags);
1950
1951 return CR_CALL_NOT_IMPLEMENTED;
1952 }
1953
1954
1955 /***********************************************************************
1956 * CM_First_Range [SETUPAPI.@]
1957 */
1958 CONFIGRET
1959 WINAPI
1960 CM_First_Range(
1961 _In_ RANGE_LIST rlh,
1962 _Out_ PDWORDLONG pullStart,
1963 _Out_ PDWORDLONG pullEnd,
1964 _Out_ PRANGE_ELEMENT preElement,
1965 _In_ ULONG ulFlags)
1966 {
1967 PINTERNAL_RANGE_LIST pRangeList;
1968 PINTERNAL_RANGE pRange;
1969 PLIST_ENTRY ListEntry;
1970 CONFIGRET ret = CR_SUCCESS;
1971
1972 FIXME("CM_First_Range(%p %p %p %p %lx)\n",
1973 rlh, pullStart, pullEnd, preElement, ulFlags);
1974
1975 pRangeList = (PINTERNAL_RANGE_LIST)rlh;
1976
1977 if (!IsValidRangeList(pRangeList))
1978 return CR_INVALID_RANGE_LIST;
1979
1980 if (pullStart == NULL || pullEnd == NULL || preElement == NULL)
1981 return CR_INVALID_POINTER;
1982
1983 if (ulFlags != 0)
1984 return CR_INVALID_FLAG;
1985
1986 /* Lock the range list */
1987 WaitForSingleObject(pRangeList->hMutex, INFINITE);
1988
1989 /* Fail, if the list is empty */
1990 if (IsListEmpty(&pRangeList->ListHead))
1991 {
1992 ret = CR_FAILURE;
1993 goto done;
1994 }
1995
1996 /* Get the first range */
1997 ListEntry = pRangeList->ListHead.Flink;
1998 pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
1999
2000 /* Return the range data */
2001 *pullStart = pRange->ullStart;
2002 *pullEnd = pRange->ullEnd;
2003 *preElement = (RANGE_ELEMENT)pRange;
2004
2005 done:
2006 /* Unlock the range list */
2007 ReleaseMutex(pRangeList->hMutex);
2008
2009 return ret;
2010 }
2011
2012
2013 /***********************************************************************
2014 * CM_Free_Log_Conf [SETUPAPI.@]
2015 */
2016 CONFIGRET
2017 WINAPI
2018 CM_Free_Log_Conf(
2019 _In_ LOG_CONF lcLogConfToBeFreed,
2020 _In_ ULONG ulFlags)
2021 {
2022 TRACE("CM_Free_Log_Conf(%lx %lx)\n",
2023 lcLogConfToBeFreed, ulFlags);
2024
2025 return CM_Free_Log_Conf_Ex(lcLogConfToBeFreed, ulFlags, NULL);
2026 }
2027
2028
2029 /***********************************************************************
2030 * CM_Free_Log_Conf_Ex [SETUPAPI.@]
2031 */
2032 CONFIGRET
2033 WINAPI
2034 CM_Free_Log_Conf_Ex(
2035 _In_ LOG_CONF lcLogConfToBeFreed,
2036 _In_ ULONG ulFlags,
2037 _In_opt_ HMACHINE hMachine)
2038 {
2039 RPC_BINDING_HANDLE BindingHandle = NULL;
2040 HSTRING_TABLE StringTable = NULL;
2041 LPWSTR lpDevInst;
2042 PLOG_CONF_INFO pLogConfInfo;
2043 CONFIGRET ret;
2044
2045 TRACE("CM_Free_Log_Conf_Ex(%lx %lx %p)\n",
2046 lcLogConfToBeFreed, ulFlags, hMachine);
2047
2048 if (!pSetupIsUserAdmin())
2049 return CR_ACCESS_DENIED;
2050
2051 pLogConfInfo = (PLOG_CONF_INFO)lcLogConfToBeFreed;
2052 if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
2053 return CR_INVALID_LOG_CONF;
2054
2055 if (ulFlags != 0)
2056 return CR_INVALID_FLAG;
2057
2058 if (hMachine != NULL)
2059 {
2060 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2061 if (BindingHandle == NULL)
2062 return CR_FAILURE;
2063
2064 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2065 if (StringTable == 0)
2066 return CR_FAILURE;
2067 }
2068 else
2069 {
2070 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2071 return CR_FAILURE;
2072 }
2073
2074 lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
2075 if (lpDevInst == NULL)
2076 return CR_INVALID_DEVNODE;
2077
2078 RpcTryExcept
2079 {
2080 ret = PNP_FreeLogConf(BindingHandle, lpDevInst, pLogConfInfo->ulFlags,
2081 pLogConfInfo->ulTag, 0);
2082 }
2083 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2084 {
2085 ret = RpcStatusToCmStatus(RpcExceptionCode());
2086 }
2087 RpcEndExcept;
2088
2089 return ret;
2090 }
2091
2092
2093 /***********************************************************************
2094 * CM_Free_Log_Conf_Handle [SETUPAPI.@]
2095 */
2096 CONFIGRET
2097 WINAPI
2098 CM_Free_Log_Conf_Handle(
2099 _In_ LOG_CONF lcLogConf)
2100 {
2101 PLOG_CONF_INFO pLogConfInfo;
2102
2103 TRACE("CM_Free_Log_Conf_Handle(%lx)\n", lcLogConf);
2104
2105 pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
2106 if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
2107 return CR_INVALID_LOG_CONF;
2108
2109 HeapFree(GetProcessHeap(), 0, pLogConfInfo);
2110
2111 return CR_SUCCESS;
2112 }
2113
2114
2115 /***********************************************************************
2116 * CM_Free_Range_List [SETUPAPI.@]
2117 */
2118 CONFIGRET
2119 WINAPI
2120 CM_Free_Range_List(
2121 _In_ RANGE_LIST RangeList,
2122 _In_ ULONG ulFlags)
2123 {
2124 PINTERNAL_RANGE_LIST pRangeList;
2125 PINTERNAL_RANGE pRange;
2126 PLIST_ENTRY ListEntry;
2127
2128 FIXME("CM_Free_Range_List(%p %lx)\n",
2129 RangeList, ulFlags);
2130
2131 pRangeList = (PINTERNAL_RANGE_LIST)RangeList;
2132
2133 if (!IsValidRangeList(pRangeList))
2134 return CR_INVALID_RANGE_LIST;
2135
2136 if (ulFlags != 0)
2137 return CR_INVALID_FLAG;
2138
2139 /* Lock the range list */
2140 WaitForSingleObject(pRangeList->hMutex, INFINITE);
2141
2142 /* Free the list of ranges */
2143 while (!IsListEmpty(&pRangeList->ListHead))
2144 {
2145 ListEntry = RemoveHeadList(&pRangeList->ListHead);
2146 pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2147 HeapFree(GetProcessHeap(), 0, pRange);
2148 }
2149
2150 /* Unlock the range list */
2151 ReleaseMutex(pRangeList->hMutex);
2152
2153 /* Close the mutex */
2154 CloseHandle(pRangeList->hMutex);
2155
2156 /* Free the range list */
2157 HeapFree(GetProcessHeap(), 0, pRangeList);
2158
2159 return CR_SUCCESS;
2160 }
2161
2162
2163 /***********************************************************************
2164 * CM_Free_Res_Des [SETUPAPI.@]
2165 */
2166 CONFIGRET
2167 WINAPI
2168 CM_Free_Res_Des(
2169 _Out_ PRES_DES prdResDes,
2170 _In_ RES_DES rdResDes,
2171 _In_ ULONG ulFlags)
2172 {
2173 TRACE("CM_Free_Res_Des(%p %p %lx)\n",
2174 prdResDes, rdResDes, ulFlags);
2175
2176 return CM_Free_Res_Des_Ex(prdResDes, rdResDes, ulFlags, NULL);
2177 }
2178
2179
2180 /***********************************************************************
2181 * CM_Free_Res_Des_Ex [SETUPAPI.@]
2182 */
2183 CONFIGRET
2184 WINAPI
2185 CM_Free_Res_Des_Ex(
2186 _Out_ PRES_DES prdResDes,
2187 _In_ RES_DES rdResDes,
2188 _In_ ULONG ulFlags,
2189 _In_opt_ HMACHINE hMachine)
2190 {
2191 FIXME("CM_Free_Res_Des_Ex(%p %p %lx %p)\n",
2192 prdResDes, rdResDes, ulFlags, hMachine);
2193
2194 return CR_CALL_NOT_IMPLEMENTED;
2195 }
2196
2197
2198 /***********************************************************************
2199 * CM_Free_Res_Des_Handle [SETUPAPI.@]
2200 */
2201 CONFIGRET
2202 WINAPI
2203 CM_Free_Res_Des_Handle(
2204 _In_ RES_DES rdResDes)
2205 {
2206 FIXME("CM_Free_Res_Des_Handle(%p)\n", rdResDes);
2207
2208 return CR_CALL_NOT_IMPLEMENTED;
2209 }
2210
2211
2212 /***********************************************************************
2213 * CM_Get_Child [SETUPAPI.@]
2214 */
2215 CONFIGRET
2216 WINAPI
2217 CM_Get_Child(
2218 _Out_ PDEVINST pdnDevInst,
2219 _In_ DEVINST dnDevInst,
2220 _In_ ULONG ulFlags)
2221 {
2222 TRACE("CM_Get_Child(%p %p %lx)\n",
2223 pdnDevInst, dnDevInst, ulFlags);
2224
2225 return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
2226 }
2227
2228
2229 /***********************************************************************
2230 * CM_Get_Child_Ex [SETUPAPI.@]
2231 */
2232 CONFIGRET
2233 WINAPI
2234 CM_Get_Child_Ex(
2235 _Out_ PDEVINST pdnDevInst,
2236 _In_ DEVINST dnDevInst,
2237 _In_ ULONG ulFlags,
2238 _In_opt_ HMACHINE hMachine)
2239 {
2240 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
2241 RPC_BINDING_HANDLE BindingHandle = NULL;
2242 HSTRING_TABLE StringTable = NULL;
2243 LPWSTR lpDevInst;
2244 DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
2245 CONFIGRET ret;
2246
2247 TRACE("CM_Get_Child_Ex(%p %lx %lx %p)\n",
2248 pdnDevInst, dnDevInst, ulFlags, hMachine);
2249
2250 if (pdnDevInst == NULL)
2251 return CR_INVALID_POINTER;
2252
2253 if (dnDevInst == 0)
2254 return CR_INVALID_DEVINST;
2255
2256 if (ulFlags != 0)
2257 return CR_INVALID_FLAG;
2258
2259 *pdnDevInst = -1;
2260
2261 if (hMachine != NULL)
2262 {
2263 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2264 if (BindingHandle == NULL)
2265 return CR_FAILURE;
2266
2267 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2268 if (StringTable == 0)
2269 return CR_FAILURE;
2270 }
2271 else
2272 {
2273 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2274 return CR_FAILURE;
2275 }
2276
2277 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2278 if (lpDevInst == NULL)
2279 return CR_INVALID_DEVNODE;
2280
2281 RpcTryExcept
2282 {
2283 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
2284 PNP_GET_CHILD_DEVICE_INSTANCE,
2285 lpDevInst,
2286 szRelatedDevInst,
2287 &dwLength,
2288 0);
2289 }
2290 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2291 {
2292 ret = RpcStatusToCmStatus(RpcExceptionCode());
2293 }
2294 RpcEndExcept;
2295
2296 if (ret != CR_SUCCESS)
2297 return ret;
2298
2299 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
2300
2301 dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
2302 if (dwIndex == -1)
2303 return CR_FAILURE;
2304
2305 *pdnDevInst = dwIndex;
2306
2307 return CR_SUCCESS;
2308 }
2309
2310
2311 /***********************************************************************
2312 * CM_Get_Class_Key_NameA [SETUPAPI.@]
2313 */
2314 CONFIGRET
2315 WINAPI
2316 CM_Get_Class_Key_NameA(
2317 _In_ LPGUID ClassGuid,
2318 _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2319 _Inout_ PULONG pulLength,
2320 _In_ ULONG ulFlags)
2321 {
2322 TRACE("CM_Get_Class_Key_NameA(%p %p %p %lx)\n",
2323 ClassGuid, pszKeyName, pulLength, ulFlags);
2324
2325 return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
2326 ulFlags, NULL);
2327 }
2328
2329
2330 /***********************************************************************
2331 * CM_Get_Class_Key_NameW [SETUPAPI.@]
2332 */
2333 CONFIGRET
2334 WINAPI
2335 CM_Get_Class_Key_NameW(
2336 _In_ LPGUID ClassGuid,
2337 _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2338 _Inout_ PULONG pulLength,
2339 _In_ ULONG ulFlags)
2340 {
2341 TRACE("CM_Get_Class_Key_NameW(%p %p %p %lx)\n",
2342 ClassGuid, pszKeyName, pulLength, ulFlags);
2343
2344 return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
2345 ulFlags, NULL);
2346 }
2347
2348
2349 /***********************************************************************
2350 * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
2351 */
2352 CONFIGRET
2353 WINAPI
2354 CM_Get_Class_Key_Name_ExA(
2355 _In_ LPGUID ClassGuid,
2356 _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2357 _Inout_ PULONG pulLength,
2358 _In_ ULONG ulFlags,
2359 _In_opt_ HMACHINE hMachine)
2360 {
2361 WCHAR szBuffer[MAX_GUID_STRING_LEN];
2362 CONFIGRET ret = CR_SUCCESS;
2363 ULONG ulLength;
2364 ULONG ulOrigLength;
2365
2366 TRACE("CM_Get_Class_Key_Name_ExA(%p %p %p %lx %p)\n",
2367 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2368
2369 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2370 return CR_INVALID_POINTER;
2371
2372 ulOrigLength = *pulLength;
2373 *pulLength = 0;
2374
2375 ulLength = MAX_GUID_STRING_LEN;
2376 ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
2377 ulFlags, hMachine);
2378 if (ret == CR_SUCCESS)
2379 {
2380 if (WideCharToMultiByte(CP_ACP,
2381 0,
2382 szBuffer,
2383 ulLength,
2384 pszKeyName,
2385 ulOrigLength,
2386 NULL,
2387 NULL) == 0)
2388 ret = CR_FAILURE;
2389 else
2390 *pulLength = lstrlenA(pszKeyName) + 1;
2391 }
2392
2393 return CR_SUCCESS;
2394 }
2395
2396
2397 /***********************************************************************
2398 * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
2399 */
2400 CONFIGRET
2401 WINAPI
2402 CM_Get_Class_Key_Name_ExW(
2403 _In_ LPGUID ClassGuid,
2404 _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2405 _Inout_ PULONG pulLength,
2406 _In_ ULONG ulFlags,
2407 _In_opt_ HMACHINE hMachine)
2408 {
2409 TRACE("CM_Get_Class_Key_Name_ExW(%p %p %p %lx %p)\n",
2410 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2411
2412 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2413 return CR_INVALID_POINTER;
2414
2415 if (ulFlags != 0)
2416 return CR_INVALID_FLAG;
2417
2418 if (*pulLength < MAX_GUID_STRING_LEN)
2419 {
2420 *pulLength = 0;
2421 return CR_BUFFER_SMALL;
2422 }
2423
2424 if (!GuidToString(ClassGuid, pszKeyName))
2425 return CR_INVALID_DATA;
2426
2427 *pulLength = MAX_GUID_STRING_LEN;
2428
2429 return CR_SUCCESS;
2430 }
2431
2432
2433 /***********************************************************************
2434 * CM_Get_Class_NameA [SETUPAPI.@]
2435 */
2436 CONFIGRET
2437 WINAPI
2438 CM_Get_Class_NameA(
2439 _In_ LPGUID ClassGuid,
2440 _Out_writes_opt_(*pulLength) PCHAR Buffer,
2441 _Inout_ PULONG pulLength,
2442 _In_ ULONG ulFlags)
2443 {
2444 TRACE("CM_Get_Class_NameA(%p %p %p %lx)\n",
2445 ClassGuid, Buffer, pulLength, ulFlags);
2446
2447 return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
2448 NULL);
2449 }
2450
2451
2452 /***********************************************************************
2453 * CM_Get_Class_NameW [SETUPAPI.@]
2454 */
2455 CONFIGRET
2456 WINAPI
2457 CM_Get_Class_NameW(
2458 _In_ LPGUID ClassGuid,
2459 _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2460 _Inout_ PULONG pulLength,
2461 _In_ ULONG ulFlags)
2462 {
2463 TRACE("CM_Get_Class_NameW(%p %p %p %lx)\n",
2464 ClassGuid, Buffer, pulLength, ulFlags);
2465
2466 return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
2467 NULL);
2468 }
2469
2470
2471 /***********************************************************************
2472 * CM_Get_Class_Name_ExA [SETUPAPI.@]
2473 */
2474 CONFIGRET
2475 WINAPI
2476 CM_Get_Class_Name_ExA(
2477 _In_ LPGUID ClassGuid,
2478 _Out_writes_opt_(*pulLength) PCHAR Buffer,
2479 _Inout_ PULONG pulLength,
2480 _In_ ULONG ulFlags,
2481 _In_opt_ HMACHINE hMachine)
2482 {
2483 WCHAR szBuffer[MAX_CLASS_NAME_LEN];
2484 CONFIGRET ret = CR_SUCCESS;
2485 ULONG ulLength;
2486 ULONG ulOrigLength;
2487
2488 TRACE("CM_Get_Class_Name_ExA(%p %p %p %lx %p)\n",
2489 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2490
2491 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2492 return CR_INVALID_POINTER;
2493
2494 ulOrigLength = *pulLength;
2495 *pulLength = 0;
2496
2497 ulLength = MAX_CLASS_NAME_LEN;
2498 ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
2499 ulFlags, hMachine);
2500 if (ret == CR_SUCCESS)
2501 {
2502 if (WideCharToMultiByte(CP_ACP,
2503 0,
2504 szBuffer,
2505 ulLength,
2506 Buffer,
2507 ulOrigLength,
2508 NULL,
2509 NULL) == 0)
2510 ret = CR_FAILURE;
2511 else
2512 *pulLength = lstrlenA(Buffer) + 1;
2513 }
2514
2515 return ret;
2516 }
2517
2518
2519 /***********************************************************************
2520 * CM_Get_Class_Name_ExW [SETUPAPI.@]
2521 */
2522 CONFIGRET
2523 WINAPI
2524 CM_Get_Class_Name_ExW(
2525 _In_ LPGUID ClassGuid,
2526 _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2527 _Inout_ PULONG pulLength,
2528 _In_ ULONG ulFlags,
2529 _In_opt_ HMACHINE hMachine)
2530 {
2531 WCHAR szGuidString[MAX_GUID_STRING_LEN];
2532 RPC_BINDING_HANDLE BindingHandle = NULL;
2533 CONFIGRET ret;
2534
2535 TRACE("CM_Get_Class_Name_ExW(%p %p %p %lx %p\n",
2536 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2537
2538 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2539 return CR_INVALID_POINTER;
2540
2541 if (ulFlags != 0)
2542 return CR_INVALID_FLAG;
2543
2544 if (!GuidToString(ClassGuid, szGuidString))
2545 return CR_INVALID_DATA;
2546
2547 TRACE("Guid %s\n", debugstr_w(szGuidString));
2548
2549 if (hMachine != NULL)
2550 {
2551 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2552 if (BindingHandle == NULL)
2553 return CR_FAILURE;
2554 }
2555 else
2556 {
2557 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2558 return CR_FAILURE;
2559 }
2560
2561 RpcTryExcept
2562 {
2563 ret = PNP_GetClassName(BindingHandle,
2564 szGuidString,
2565 Buffer,
2566 pulLength,
2567 ulFlags);
2568 }
2569 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2570 {
2571 ret = RpcStatusToCmStatus(RpcExceptionCode());
2572 }
2573 RpcEndExcept;
2574
2575 return ret;
2576 }
2577
2578
2579 /***********************************************************************
2580 * CM_Get_Class_Registry_PropertyA [SETUPAPI.@]
2581 */
2582 CONFIGRET
2583 WINAPI
2584 CM_Get_Class_Registry_PropertyA(
2585 LPGUID ClassGuid,
2586 ULONG ulProperty,
2587 PULONG pulRegDataType,
2588 PVOID Buffer,
2589 PULONG pulLength,
2590 ULONG ulFlags,
2591 HMACHINE hMachine)
2592 {
2593 PWSTR BufferW = NULL;
2594 ULONG ulLength = 0;
2595 ULONG ulType;
2596 CONFIGRET ret;
2597
2598 TRACE("CM_Get_Class_Registry_PropertyA(%p %lu %p %p %p %lx %p)\n",
2599 ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
2600 ulFlags, hMachine);
2601
2602 if (pulLength == NULL)
2603 return CR_INVALID_POINTER;
2604
2605 if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
2606 return CR_INVALID_PROPERTY;
2607
2608 ulType = GetRegistryPropertyType(ulProperty);
2609 if (ulType == REG_SZ || ulType == REG_MULTI_SZ)
2610 {
2611 /* Get the required buffer size */
2612 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2613 NULL, &ulLength, ulFlags, hMachine);
2614 if (ret != CR_BUFFER_SMALL)
2615 return ret;
2616
2617 /* Allocate the unicode buffer */
2618 BufferW = HeapAlloc(GetProcessHeap(), 0, ulLength);
2619 if (BufferW == NULL)
2620 return CR_OUT_OF_MEMORY;
2621
2622 /* Get the property */
2623 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2624 BufferW, &ulLength, ulFlags, hMachine);
2625 if (ret != CR_SUCCESS)
2626 {
2627 HeapFree(GetProcessHeap(), 0, BufferW);
2628 return ret;
2629 }
2630
2631 /* Do W->A conversion */
2632 *pulLength = WideCharToMultiByte(CP_ACP,
2633 0,
2634 BufferW,
2635 lstrlenW(BufferW) + 1,
2636 Buffer,
2637 *pulLength,
2638 NULL,
2639 NULL);
2640
2641 /* Release the unicode buffer */
2642 HeapFree(GetProcessHeap(), 0, BufferW);
2643
2644 if (*pulLength == 0)
2645 ret = CR_FAILURE;
2646 }
2647 else
2648 {
2649 /* Get the property */
2650 ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
2651 Buffer, pulLength, ulFlags, hMachine);
2652 }
2653
2654 return ret;
2655 }
2656
2657
2658 /***********************************************************************
2659 * CM_Get_Class_Registry_PropertyW [SETUPAPI.@]
2660 */
2661 CONFIGRET
2662 WINAPI
2663 CM_Get_Class_Registry_PropertyW(
2664 LPGUID ClassGuid,
2665 ULONG ulProperty,
2666 PULONG pulRegDataType,
2667 PVOID Buffer,
2668 PULONG pulLength,
2669 ULONG ulFlags,
2670 HMACHINE hMachine)
2671 {
2672 RPC_BINDING_HANDLE BindingHandle = NULL;
2673 WCHAR szGuidString[PNP_MAX_GUID_STRING_LEN + 1];
2674 ULONG ulType = 0;
2675 ULONG ulTransferLength = 0;
2676 CONFIGRET ret;
2677
2678 TRACE("CM_Get_Class_Registry_PropertyW(%p %lu %p %p %p %lx %p)\n",
2679 ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
2680 ulFlags, hMachine);
2681
2682 if (ClassGuid == NULL || pulLength == NULL)
2683 return CR_INVALID_POINTER;
2684
2685 if (ulFlags != 0)
2686 return CR_INVALID_FLAG;
2687
2688 if (pSetupStringFromGuid(ClassGuid,
2689 szGuidString,
2690 PNP_MAX_GUID_STRING_LEN) != 0)
2691 return CR_INVALID_DATA;
2692
2693 if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
2694 return CR_INVALID_PROPERTY;
2695
2696 if (hMachine != NULL)
2697 {
2698 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2699 if (BindingHandle == NULL)
2700 return CR_FAILURE;
2701 }
2702 else
2703 {
2704 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2705 return CR_FAILURE;
2706 }
2707
2708 ulTransferLength = *pulLength;
2709
2710 RpcTryExcept
2711 {
2712 ret = PNP_GetClassRegProp(BindingHandle,
2713 szGuidString,
2714 ulProperty,
2715 &ulType,
2716 Buffer,
2717 &ulTransferLength,
2718 pulLength,
2719 ulFlags);
2720 }
2721 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2722 {
2723 ret = RpcStatusToCmStatus(RpcExceptionCode());
2724 }
2725 RpcEndExcept;
2726
2727 if (ret == CR_SUCCESS)
2728 {
2729 if (pulRegDataType != NULL)
2730 *pulRegDataType = ulType;
2731 }
2732
2733 return ret;
2734 }
2735
2736
2737 /***********************************************************************
2738 * CM_Get_Depth [SETUPAPI.@]
2739 */
2740 CONFIGRET
2741 WINAPI
2742 CM_Get_Depth(
2743 _Out_ PULONG pulDepth,
2744 _In_ DEVINST dnDevInst,
2745 _In_ ULONG ulFlags)
2746 {
2747 TRACE("CM_Get_Depth(%p %lx %lx)\n",
2748 pulDepth, dnDevInst, ulFlags);
2749
2750 return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
2751 }
2752
2753
2754 /***********************************************************************
2755 * CM_Get_Depth_Ex [SETUPAPI.@]
2756 */
2757 CONFIGRET
2758 WINAPI
2759 CM_Get_Depth_Ex(
2760 _Out_ PULONG pulDepth,
2761 _In_ DEVINST dnDevInst,
2762 _In_ ULONG ulFlags,
2763 _In_opt_ HMACHINE hMachine)
2764 {
2765 RPC_BINDING_HANDLE BindingHandle = NULL;
2766 HSTRING_TABLE StringTable = NULL;
2767 LPWSTR lpDevInst;
2768 CONFIGRET ret;
2769
2770 TRACE("CM_Get_Depth_Ex(%p %lx %lx %p)\n",
2771 pulDepth, dnDevInst, ulFlags, hMachine);
2772
2773 if (pulDepth == NULL)
2774 return CR_INVALID_POINTER;
2775
2776 if (dnDevInst == 0)
2777 return CR_INVALID_DEVINST;
2778
2779 if (ulFlags != 0)
2780 return CR_INVALID_FLAG;
2781
2782 if (hMachine != NULL)
2783 {
2784 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2785 if (BindingHandle == NULL)
2786 return CR_FAILURE;
2787
2788 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2789 if (StringTable == 0)
2790 return CR_FAILURE;
2791 }
2792 else
2793 {
2794 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2795 return CR_FAILURE;
2796 }
2797
2798 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2799 if (lpDevInst == NULL)
2800 return CR_INVALID_DEVNODE;
2801
2802 RpcTryExcept
2803 {
2804 ret = PNP_GetDepth(BindingHandle,
2805 lpDevInst,
2806 pulDepth,
2807 ulFlags);
2808 }
2809 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2810 {
2811 ret = RpcStatusToCmStatus(RpcExceptionCode());
2812 }
2813 RpcEndExcept;
2814
2815 return ret;
2816 }
2817
2818
2819 /***********************************************************************
2820 * CM_Get_DevNode_Custom_PropertyA [SETUPAPI.@]
2821 */
2822 CONFIGRET
2823 WINAPI
2824 CM_Get_DevNode_Custom_PropertyA(
2825 _In_ DEVINST dnDevInst,
2826 _In_ PCSTR pszCustomPropertyName,
2827 _Out_opt_ PULONG pulRegDataType,
2828 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
2829 _Inout_ PULONG pulLength,
2830 _In_ ULONG ulFlags)
2831 {
2832 TRACE("CM_Get_DevNode_Custom_PropertyA(%lx %s %p %p %p %lx)\n",
2833 dnDevInst, pszCustomPropertyName, pulRegDataType,
2834 Buffer, pulLength, ulFlags);
2835
2836 return CM_Get_DevNode_Custom_Property_ExA(dnDevInst, pszCustomPropertyName,
2837 pulRegDataType, Buffer,
2838 pulLength, ulFlags, NULL);
2839 }
2840
2841
2842 /***********************************************************************
2843 * CM_Get_DevNode_Custom_PropertyW [SETUPAPI.@]
2844 */
2845 CONFIGRET
2846 WINAPI
2847 CM_Get_DevNode_Custom_PropertyW(
2848 _In_ DEVINST dnDevInst,
2849 _In_ PCWSTR pszCustomPropertyName,
2850 _Out_opt_ PULONG pulRegDataType,
2851 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
2852 _Inout_ PULONG pulLength,
2853 _In_ ULONG ulFlags)
2854 {
2855 TRACE("CM_Get_DevNode_Custom_PropertyW(%lx %s %p %p %p %lx)\n",
2856 dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
2857 Buffer, pulLength, ulFlags);
2858
2859 return CM_Get_DevNode_Custom_Property_ExW(dnDevInst, pszCustomPropertyName,
2860 pulRegDataType, Buffer,
2861 pulLength, ulFlags, NULL);
2862 }
2863
2864
2865 /***********************************************************************
2866 * CM_Get_DevNode_Custom_Property_ExA [SETUPAPI.@]
2867 */
2868 CONFIGRET
2869 WINAPI
2870 CM_Get_DevNode_Custom_Property_ExA(
2871 _In_ DEVINST dnDevInst,
2872 _In_ PCSTR pszCustomPropertyName,
2873 _Out_opt_ PULONG pulRegDataType,
2874 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
2875 _Inout_ PULONG pulLength,
2876 _In_ ULONG ulFlags,
2877 _In_opt_ HMACHINE hMachine)
2878 {
2879 LPWSTR pszPropertyNameW = NULL;
2880 PVOID BufferW;
2881 ULONG ulLengthW;
2882 ULONG ulDataType = REG_NONE;
2883 CONFIGRET ret;
2884
2885 TRACE("CM_Get_DevNode_Custom_Property_ExA(%lx %s %p %p %p %lx %p)\n",
2886 dnDevInst, pszCustomPropertyName, pulRegDataType,
2887 Buffer, pulLength, ulFlags, hMachine);
2888
2889 if (!pulLength)
2890 return CR_INVALID_POINTER;
2891
2892 ulLengthW = *pulLength * sizeof(WCHAR);
2893 BufferW = HeapAlloc(GetProcessHeap(), 0, ulLengthW);
2894 if (!BufferW)
2895 return CR_OUT_OF_MEMORY;
2896
2897 pszPropertyNameW = pSetupMultiByteToUnicode(pszCustomPropertyName,
2898 CP_ACP);
2899 if (pszPropertyNameW == NULL)
2900 {
2901 HeapFree(GetProcessHeap(), 0, BufferW);
2902 return CR_OUT_OF_MEMORY;
2903 }
2904
2905 ret = CM_Get_DevNode_Custom_Property_ExW(dnDevInst,
2906 pszPropertyNameW,
2907 &ulDataType,
2908 BufferW,
2909 &ulLengthW,
2910 ulFlags,
2911 hMachine);
2912 if (ret == CR_SUCCESS)
2913 {
2914 if (ulDataType == REG_SZ ||
2915 ulDataType == REG_EXPAND_SZ ||
2916 ulDataType == REG_MULTI_SZ)
2917 {
2918 /* Do W->A conversion */
2919 *pulLength = WideCharToMultiByte(CP_ACP,
2920 0,
2921 BufferW,
2922 lstrlenW(BufferW) + 1,
2923 Buffer,
2924 *pulLength,
2925 NULL,
2926 NULL);
2927 if (*pulLength == 0)
2928 ret = CR_FAILURE;
2929 }
2930 else
2931 {
2932 /* Directly copy the value */
2933 if (ulLengthW <= *pulLength)
2934 memcpy(Buffer, BufferW, ulLengthW);
2935 else
2936 {
2937 *pulLength = ulLengthW;
2938 ret = CR_BUFFER_SMALL;
2939 }
2940 }
2941 }
2942
2943 if (pulRegDataType)
2944 *pulRegDataType = ulDataType;
2945
2946 HeapFree(GetProcessHeap(), 0, BufferW);
2947 MyFree(pszPropertyNameW);
2948
2949 return ret;
2950 }
2951
2952
2953 /***********************************************************************
2954 * CM_Get_DevNode_Custom_Property_ExW [SETUPAPI.@]
2955 */
2956 CONFIGRET
2957 WINAPI
2958 CM_Get_DevNode_Custom_Property_ExW(
2959 _In_ DEVINST dnDevInst,
2960 _In_ PCWSTR pszCustomPropertyName,
2961 _Out_opt_ PULONG pulRegDataType,
2962 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
2963 _Inout_ PULONG pulLength,
2964 _In_ ULONG ulFlags,
2965 _In_opt_ HMACHINE hMachine)
2966 {
2967 RPC_BINDING_HANDLE BindingHandle = NULL;
2968 HSTRING_TABLE StringTable = NULL;
2969 LPWSTR lpDevInst;
2970 ULONG ulDataType = REG_NONE;
2971 ULONG ulTransferLength;
2972 CONFIGRET ret = CR_SUCCESS;
2973
2974 TRACE("CM_Get_DevNode_Custom_Property_ExW(%lx %s %p %p %p %lx %p)\n",
2975 dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
2976 Buffer, pulLength, ulFlags, hMachine);
2977
2978 if (dnDevInst == 0)
2979 return CR_INVALID_DEVNODE;
2980
2981 if (pszCustomPropertyName == NULL ||
2982 pulLength == NULL ||
2983 *pulLength == 0)
2984 return CR_INVALID_POINTER;
2985
2986 if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
2987 return CR_INVALID_FLAG;
2988
2989 if (hMachine != NULL)
2990 {
2991 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2992 if (BindingHandle == NULL)
2993 return CR_FAILURE;
2994
2995 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2996 if (StringTable == 0)
2997 return CR_FAILURE;
2998 }
2999 else
3000 {
3001 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3002 return CR_FAILURE;
3003 }
3004
3005 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3006 if (lpDevInst == NULL)
3007 return CR_INVALID_DEVNODE;
3008
3009 ulTransferLength = *pulLength;
3010
3011 RpcTryExcept
3012 {
3013 ret = PNP_GetCustomDevProp(BindingHandle,
3014 lpDevInst,
3015 (LPWSTR)pszCustomPropertyName,
3016 &ulDataType,
3017 Buffer,
3018 &ulTransferLength,
3019 pulLength,
3020 ulFlags);
3021 }
3022 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3023 {
3024 ret = RpcStatusToCmStatus(RpcExceptionCode());
3025 }
3026 RpcEndExcept;
3027
3028 if (ret == CR_SUCCESS)
3029 {
3030 if (pulRegDataType != NULL)
3031 *pulRegDataType = ulDataType;
3032 }
3033
3034 return ret;
3035 }
3036
3037
3038 /***********************************************************************
3039 * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
3040 */
3041 CONFIGRET
3042 WINAPI
3043 CM_Get_DevNode_Registry_PropertyA(
3044 _In_ DEVINST dnDevInst,
3045 _In_ ULONG ulProperty,
3046 _Out_opt_ PULONG pulRegDataType,
3047 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3048 _Inout_ PULONG pulLength,
3049 _In_ ULONG ulFlags)
3050 {
3051 TRACE("CM_Get_DevNode_Registry_PropertyA(%lx %lu %p %p %p %lx)\n",
3052 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3053
3054 return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
3055 pulRegDataType, Buffer,
3056 pulLength, ulFlags, NULL);
3057 }
3058
3059
3060 /***********************************************************************
3061 * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
3062 */
3063 CONFIGRET
3064 WINAPI
3065 CM_Get_DevNode_Registry_PropertyW(
3066 _In_ DEVINST dnDevInst,
3067 _In_ ULONG ulProperty,
3068 _Out_opt_ PULONG pulRegDataType,
3069 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3070 _Inout_ PULONG pulLength,
3071 _In_ ULONG ulFlags)
3072 {
3073 TRACE("CM_Get_DevNode_Registry_PropertyW(%lx %lu %p %p %p %lx)\n",
3074 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3075
3076 return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
3077 pulRegDataType, Buffer,
3078 pulLength, ulFlags, NULL);
3079 }
3080
3081
3082 /***********************************************************************
3083 * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
3084 */
3085 CONFIGRET
3086 WINAPI
3087 CM_Get_DevNode_Registry_Property_ExA(
3088 _In_ DEVINST dnDevInst,
3089 _In_ ULONG ulProperty,
3090 _Out_opt_ PULONG pulRegDataType,
3091 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3092 _Inout_ PULONG pulLength,
3093 _In_ ULONG ulFlags,
3094 _In_opt_ HMACHINE hMachine)
3095 {
3096 PVOID BufferW;
3097 ULONG LengthW;
3098 ULONG ulDataType = REG_NONE;
3099 CONFIGRET ret;
3100
3101 TRACE("CM_Get_DevNode_Registry_Property_ExA(%lx %lu %p %p %p %lx %p)\n",
3102 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3103 ulFlags, hMachine);
3104
3105 if (!pulLength)
3106 return CR_INVALID_POINTER;
3107
3108 LengthW = *pulLength * sizeof(WCHAR);
3109 BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
3110
3111 if (!BufferW)
3112 return CR_OUT_OF_MEMORY;
3113
3114 ret = CM_Get_DevNode_Registry_Property_ExW(dnDevInst,
3115 ulProperty,
3116 &ulDataType,
3117 BufferW,
3118 &LengthW,
3119 ulFlags,
3120 hMachine);
3121
3122 if (ret == CR_SUCCESS)
3123 {
3124 if (ulDataType == REG_SZ ||
3125 ulDataType == REG_EXPAND_SZ ||
3126 ulDataType == REG_MULTI_SZ)
3127 {
3128 /* Do W->A conversion */
3129 *pulLength = WideCharToMultiByte(CP_ACP,
3130 0,
3131 BufferW,
3132 lstrlenW(BufferW) + 1,
3133 Buffer,
3134 *pulLength,
3135 NULL,
3136 NULL);
3137 if (*pulLength == 0)
3138 ret = CR_FAILURE;
3139 }
3140 else
3141 {
3142 /* Directly copy the value */
3143 if (LengthW <= *pulLength)
3144 memcpy(Buffer, BufferW, LengthW);
3145 else
3146 {
3147 *pulLength = LengthW;
3148 ret = CR_BUFFER_SMALL;
3149 }
3150 }
3151 }
3152
3153 if (pulRegDataType)
3154 *pulRegDataType = ulDataType;
3155
3156 HeapFree(GetProcessHeap(), 0, BufferW);
3157
3158 return ret;
3159 }
3160
3161
3162 /***********************************************************************
3163 * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
3164 */
3165 CONFIGRET
3166 WINAPI
3167 CM_Get_DevNode_Registry_Property_ExW(
3168 _In_ DEVINST dnDevInst,
3169 _In_ ULONG ulProperty,
3170 _Out_opt_ PULONG pulRegDataType,
3171 _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3172 _Inout_ PULONG pulLength,
3173 _In_ ULONG ulFlags,
3174 _In_opt_ HMACHINE hMachine)
3175 {
3176 RPC_BINDING_HANDLE BindingHandle = NULL;
3177 HSTRING_TABLE StringTable = NULL;
3178 CONFIGRET ret = CR_SUCCESS;
3179 LPWSTR lpDevInst;
3180 ULONG ulDataType = REG_NONE;
3181 ULONG ulTransferLength = 0;
3182
3183 TRACE("CM_Get_DevNode_Registry_Property_ExW(%lx %lu %p %p %p %lx %p)\n",
3184 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3185 ulFlags, hMachine);
3186
3187 if (dnDevInst == 0)
3188 return CR_INVALID_DEVNODE;
3189
3190 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
3191 return CR_INVALID_PROPERTY;
3192
3193 /* pulRegDataType is optional */
3194
3195 /* Buffer is optional */
3196
3197 if (pulLength == NULL)
3198 return CR_INVALID_POINTER;
3199
3200 if (*pulLength == 0)
3201 return CR_INVALID_POINTER;
3202
3203 if (ulFlags != 0)
3204 return CR_INVALID_FLAG;
3205
3206 if (hMachine != NULL)
3207 {
3208 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3209 if (BindingHandle == NULL)
3210 return CR_FAILURE;
3211
3212 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3213 if (StringTable == 0)
3214 return CR_FAILURE;
3215 }
3216 else
3217 {
3218 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3219 return CR_FAILURE;
3220 }
3221
3222 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3223 if (lpDevInst == NULL)
3224 return CR_INVALID_DEVNODE;
3225
3226 ulTransferLength = *pulLength;
3227
3228 RpcTryExcept
3229 {
3230 ret = PNP_GetDeviceRegProp(BindingHandle,
3231 lpDevInst,
3232 ulProperty,
3233 &ulDataType,
3234 Buffer,
3235 &ulTransferLength,
3236 pulLength,
3237 ulFlags);
3238 }
3239 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3240 {
3241 ret = RpcStatusToCmStatus(RpcExceptionCode());
3242 }
3243 RpcEndExcept;
3244
3245 if (ret == CR_SUCCESS)
3246 {
3247 if (pulRegDataType != NULL)
3248 *pulRegDataType = ulDataType;
3249 }
3250
3251 return ret;
3252 }
3253
3254
3255 /***********************************************************************
3256 * CM_Get_DevNode_Status [SETUPAPI.@]
3257 */
3258 CONFIGRET
3259 WINAPI
3260 CM_Get_DevNode_Status(
3261 _Out_ PULONG pulStatus,
3262 _Out_ PULONG pulProblemNumber,
3263 _In_ DEVINST dnDevInst,
3264 _In_ ULONG ulFlags)
3265 {
3266 TRACE("CM_Get_DevNode_Status(%p %p %lx %lx)\n",
3267 pulStatus, pulProblemNumber, dnDevInst, ulFlags);
3268
3269 return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
3270 ulFlags, NULL);
3271 }
3272
3273
3274 /***********************************************************************
3275 * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
3276 */
3277 CONFIGRET
3278 WINAPI
3279 CM_Get_DevNode_Status_Ex(
3280 _Out_ PULONG pulStatus,
3281 _Out_ PULONG pulProblemNumber,
3282 _In_ DEVINST dnDevInst,
3283 _In_ ULONG ulFlags,
3284 _In_opt_ HMACHINE hMachine)
3285 {
3286 RPC_BINDING_HANDLE BindingHandle = NULL;
3287 HSTRING_TABLE StringTable = NULL;
3288 LPWSTR lpDevInst;
3289 CONFIGRET ret;
3290
3291 TRACE("CM_Get_DevNode_Status_Ex(%p %p %lx %lx %p)\n",
3292 pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
3293
3294 if (pulStatus == NULL || pulProblemNumber == NULL)
3295 return CR_INVALID_POINTER;
3296
3297 if (dnDevInst == 0)
3298 return CR_INVALID_DEVINST;
3299
3300 if (ulFlags != 0)
3301 return CR_INVALID_FLAG;
3302
3303 if (hMachine != NULL)
3304 {
3305 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3306 if (BindingHandle == NULL)
3307 return CR_FAILURE;
3308
3309 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3310 if (StringTable == 0)
3311 return CR_FAILURE;
3312 }
3313 else
3314 {
3315 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3316 return CR_FAILURE;
3317 }
3318
3319 lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3320 if (lpDevInst == NULL)
3321 return CR_INVALID_DEVNODE;
3322
3323 RpcTryExcept
3324 {
3325 ret = PNP_GetDeviceStatus(BindingHandle,
3326 lpDevInst,
3327 pulStatus,
3328 pulProblemNumber,
3329 ulFlags);
3330 }
3331 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3332 {
3333 ret = RpcStatusToCmStatus(RpcExceptionCode());
3334 }
3335 RpcEndExcept;
3336
3337 return ret;
3338 }
3339
3340
3341 /***********************************************************************
3342 * CM_Get_Device_IDA [SETUPAPI.@]
3343 */
3344 CONFIGRET
3345 WINAPI
3346 CM_Get_Device_IDA(
3347 _In_ DEVINST dnDevInst,
3348 _Out_writes_(BufferLen) PCHAR Buffer,
3349 _In_ ULONG BufferLen,
3350 _In_ ULONG ulFlags)
3351 {
3352 TRACE("CM_Get_Device_IDA(%lx %p %lu %lx)\n",
3353 dnDevInst, Buffer, BufferLen, ulFlags);
3354
3355 return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3356 }
3357
3358
3359 /***********************************************************************
3360 * CM_Get_Device_IDW [SETUPAPI.@]
3361 */
3362 CONFIGRET
3363 WINAPI
3364 CM_Get_Device_IDW(
3365 _In_ DEVINST dnDevInst,
3366 _Out_writes_(BufferLen) PWCHAR Buffer,
3367 _In_ ULONG BufferLen,
3368 _In_ ULONG ulFlags)
3369 {
3370 TRACE("CM_Get_Device_IDW(%lx %p %lu %lx)\n",
3371 dnDevInst, Buffer, BufferLen, ulFlags);
3372
3373 return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3374 }
3375
3376
3377 /***********************************************************************
3378 * CM_Get_Device_ID_ExA [SETUPAPI.@]
3379 */
3380 CONFIGRET
3381 WINAPI
3382 CM_Get_Device_ID_ExA(
3383 _In_ DEVINST dnDevInst,
3384 _Out_writes_(BufferLen) PCHAR Buffer,
3385 _In_ ULONG BufferLen,
3386 _In_ ULONG ulFlags,
3387 _In_opt_ HMACHINE hMachine)
3388 {
3389 WCHAR szBufferW[MAX_DEVICE_ID_LEN];
3390 CONFIGRET ret = CR_SUCCESS;
3391
3392 TRACE("CM_Get_Device_ID_ExA(%lx %p %lu %lx %p)\n",
3393 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3394
3395 if (Buffer == NULL)
3396 return CR_INVALID_POINTER;
3397
3398 ret = CM_Get_Device_ID_ExW(dnDevInst,
3399 szBufferW,
3400 MAX_DEVICE_ID_LEN,
3401 ulFlags,
3402 hMachine);
3403 if (ret == CR_SUCCESS)
3404 {
3405 if (WideCharToMultiByte(CP_ACP,
3406 0,
3407 szBufferW,
3408 lstrlenW(szBufferW) + 1,
3409 Buffer,
3410 BufferLen,
3411 NULL,
3412 NULL) == 0)
3413 ret = CR_FAILURE;
3414 }
3415
3416 return ret;
3417 }
3418
3419
3420 /***********************************************************************
3421 * CM_Get_Device_ID_ExW [SETUPAPI.@]
3422 */
3423 CONFIGRET
3424 WINAPI
3425 CM_Get_Device_ID_ExW(
3426 _In_ DEVINST dnDevInst,
3427 _Out_writes_(BufferLen) PWCHAR Buffer,
3428 _In_ ULONG BufferLen,
3429 _In_ ULONG ulFlags,
3430 _In_opt_ HMACHINE hMachine)
3431 {
3432 HSTRING_TABLE StringTable = NULL;
3433
3434 TRACE("CM_Get_Device_ID_ExW(%lx %p %lu %lx %p)\n",
3435 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3436
3437 if (dnDevInst == 0)
3438 return CR_INVALID_DEVINST;
3439
3440 if (Buffer == NULL)
3441 return CR_INVALID_POINTER;
3442
3443 if (ulFlags != 0)
3444 return CR_INVALID_FLAG;
3445
3446 if (hMachine != NULL)
3447 {
3448 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3449 if (StringTable == NULL)
3450 return CR_FAILURE;
3451 }
3452 else
3453 {
3454 if (!PnpGetLocalHandles(NULL, &StringTable))
3455 return CR_FAILURE;
3456 }
3457
3458 if (!pSetupStringTableStringFromIdEx(StringTable,
3459 dnDevInst,
3460 Buffer,
3461 &BufferLen))
3462 return CR_FAILURE;
3463
3464 return CR_SUCCESS;
3465 }
3466
3467
3468 /***********************************************************************
3469 * CM_Get_Device_ID_ListA [SETUPAPI.@]
3470 */
3471 CONFIGRET
3472 WINAPI
3473 CM_Get_Device_ID_ListA(
3474 _In_ PCSTR pszFilter,
3475 _Out_writes_(BufferLen) PCHAR Buffer,
3476 _In_ ULONG BufferLen,
3477 _In_ ULONG ulFlags)
3478 {
3479 TRACE("CM_Get_Device_ID_ListA(%p %p %lu %lx)\n",
3480 pszFilter, Buffer, BufferLen, ulFlags);
3481
3482 return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
3483 ulFlags, NULL);
3484 }
3485
3486
3487 /***********************************************************************
3488 * CM_Get_Device_ID_ListW [SETUPAPI.@]
3489 */
3490 CONFIGRET
3491 WINAPI
3492 CM_Get_Device_ID_ListW(
3493 _In_ PCWSTR pszFilter,
3494 _Out_writes_(BufferLen) PWCHAR Buffer,
3495 _In_ ULONG BufferLen,
3496 _In_ ULONG ulFlags)
3497 {
3498 TRACE("CM_Get_Device_ID_ListW(%p %p %lu %lx)\n",
3499 pszFilter, Buffer, BufferLen, ulFlags);
3500
3501 return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
3502 ulFlags, NULL);
3503 }
3504
3505
3506 /***********************************************************************
3507 * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
3508 */
3509 CONFIGRET
3510 WINAPI
3511 CM_Get_Device_ID_List_ExA(
3512 _In_ PCSTR pszFilter,
3513 _Out_writes_(BufferLen) PCHAR Buffer,
3514 _In_ ULONG BufferLen,
3515 _In_ ULONG ulFlags,
3516 _In_opt_ HMACHINE hMachine)
3517 {
3518 LPWSTR BufferW = NULL;
3519 LPWSTR pszFilterW = NULL;
3520 CONFIGRET ret = CR_SUCCESS;
3521
3522 TRACE("CM_Get_Device_ID_List_ExA(%p %p %lu %lx %p)\n",
3523 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3524
3525 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
3526 if (BufferW == NULL)
3527 return CR_OUT_OF_MEMORY;
3528
3529 if (pszFilter == NULL)
3530 {
3531 ret = CM_Get_Device_ID_List_ExW(NULL,
3532 BufferW,
3533 BufferLen,
3534 ulFlags,
3535 hMachine);
3536 }
3537 else
3538 {
3539 if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3540 {
3541 ret = CR_INVALID_DEVICE_ID;
3542 goto Done;
3543 }
3544
3545 ret = CM_Get_Device_ID_List_ExW(pszFilterW,
3546 BufferW,
3547 BufferLen,
3548 ulFlags,
3549 hMachine);
3550
3551 MyFree(pszFilterW);
3552 }
3553
3554 if (WideCharToMultiByte(CP_ACP,
3555 0,
3556 BufferW,
3557 lstrlenW(BufferW) + 1,
3558 Buffer,
3559 BufferLen,
3560 NULL,
3561 NULL) == 0)
3562 ret = CR_FAILURE;
3563
3564 Done:
3565 MyFree(BufferW);
3566
3567 return ret;
3568 }
3569
3570
3571 /***********************************************************************
3572 * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
3573 */
3574 CONFIGRET
3575 WINAPI
3576 CM_Get_Device_ID_List_ExW(
3577 _In_ PCWSTR pszFilter,
3578 _Out_writes_(BufferLen) PWCHAR Buffer,
3579 _In_ ULONG BufferLen,
3580 _In_ ULONG ulFlags,