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