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