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