xref: /reactos/dll/win32/setupapi/cfgmgr.c (revision f24fbb65)
1 /*
2  * Configuration manager functions
3  *
4  * Copyright 2000 James Hatheway
5  * Copyright 2005, 2006 Eric Kohl
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "setupapi_private.h"
23 
24 #include <dbt.h>
25 #include <pnp_c.h>
26 #include <winsvc.h>
27 
28 #include <pseh/pseh2.h>
29 
30 #include "rpc_private.h"
31 
32 DWORD
33 WINAPI
34 I_ScPnPGetServiceName(IN SERVICE_STATUS_HANDLE hServiceStatus,
35                       OUT LPWSTR lpServiceName,
36                       IN DWORD cchServiceName);
37 
38 
39 /* Registry key and value names */
40 static const WCHAR BackslashOpenBrace[] = {'\\', '{', 0};
41 static const WCHAR CloseBrace[] = {'}', 0};
42 static const WCHAR Class[]  = {'C','l','a','s','s',0};
43 
44 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
45                                      'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
46                                      'C','o','n','t','r','o','l','\\',
47                                      'C','l','a','s','s',0};
48 
49 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
50                                       'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
51                                       'C','o','n','t','r','o','l','\\',
52                                       'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
53 
54 typedef struct _MACHINE_INFO
55 {
56     WCHAR szMachineName[SP_MAX_MACHINENAME_LENGTH];
57     RPC_BINDING_HANDLE BindingHandle;
58     HSTRING_TABLE StringTable;
59     BOOL bLocal;
60 } MACHINE_INFO, *PMACHINE_INFO;
61 
62 
63 typedef struct _LOG_CONF_INFO
64 {
65     ULONG ulMagic;
66     DEVINST dnDevInst;
67     ULONG ulType;
68     ULONG ulTag;
69 } LOG_CONF_INFO, *PLOG_CONF_INFO;
70 
71 #define LOG_CONF_MAGIC 0x464E434C  /* "LCNF" */
72 
73 typedef struct _RES_DES_INFO
74 {
75     ULONG ulMagic;
76     DEVINST dnDevInst;
77     ULONG ulLogConfType;
78     ULONG ulLogConfTag;
79     ULONG ulResDesType;
80     ULONG ulResDesTag;
81 } RES_DES_INFO, *PRES_DES_INFO;
82 
83 #define RES_DES_MAGIC 0x53445352  /* "RSDS" */
84 
85 typedef struct _NOTIFY_DATA
86 {
87     ULONG ulMagic;
88     PVOID hNotifyHandle;
89 } NOTIFY_DATA, *PNOTIFY_DATA;
90 
91 #define NOTIFY_MAGIC 0x44556677
92 
93 
94 typedef struct _INTERNAL_RANGE
95 {
96     LIST_ENTRY ListEntry;
97     struct _INTERNAL_RANGE_LIST *pRangeList;
98     DWORDLONG ullStart;
99     DWORDLONG ullEnd;
100 } INTERNAL_RANGE, *PINTERNAL_RANGE;
101 
102 typedef struct _INTERNAL_RANGE_LIST
103 {
104     ULONG ulMagic;
105     HANDLE hMutex;
106     LIST_ENTRY ListHead;
107 } INTERNAL_RANGE_LIST, *PINTERNAL_RANGE_LIST;
108 
109 #define RANGE_LIST_MAGIC 0x33445566
110 
111 typedef struct _CONFLICT_DATA
112 {
113     ULONG ulMagic;
114     PPNP_CONFLICT_LIST pConflictList;
115 } CONFLICT_DATA, *PCONFLICT_DATA;
116 
117 #define CONFLICT_MAGIC 0x11225588
118 
119 
120 /* FUNCTIONS ****************************************************************/
121 
122 static
123 BOOL
GuidToString(_In_ LPGUID Guid,_Out_ LPWSTR String)124 GuidToString(
125     _In_ LPGUID Guid,
126     _Out_ LPWSTR String)
127 {
128     LPWSTR lpString;
129 
130     if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
131         return FALSE;
132 
133     lstrcpyW(&String[1], lpString);
134 
135     String[0] = '{';
136     String[MAX_GUID_STRING_LEN - 2] = '}';
137     String[MAX_GUID_STRING_LEN - 1] = UNICODE_NULL;
138 
139     RpcStringFreeW(&lpString);
140 
141     return TRUE;
142 }
143 
144 
145 static
146 CONFIGRET
RpcStatusToCmStatus(_In_ RPC_STATUS Status)147 RpcStatusToCmStatus(
148     _In_ RPC_STATUS Status)
149 {
150     return CR_FAILURE;
151 }
152 
153 
154 static
155 ULONG
GetRegistryPropertyType(_In_ ULONG ulProperty)156 GetRegistryPropertyType(
157     _In_ ULONG ulProperty)
158 {
159     switch (ulProperty)
160     {
161         case CM_DRP_DEVICEDESC:
162         case CM_DRP_SERVICE:
163         case CM_DRP_CLASS:
164         case CM_DRP_CLASSGUID:
165         case CM_DRP_DRIVER:
166         case CM_DRP_MFG:
167         case CM_DRP_FRIENDLYNAME:
168         case CM_DRP_LOCATION_INFORMATION:
169         case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
170         case CM_DRP_ENUMERATOR_NAME:
171         case CM_DRP_SECURITY_SDS:
172         case CM_DRP_UI_NUMBER_DESC_FORMAT:
173             return REG_SZ;
174 
175         case CM_DRP_HARDWAREID:
176         case CM_DRP_COMPATIBLEIDS:
177         case CM_DRP_UPPERFILTERS:
178         case CM_DRP_LOWERFILTERS:
179             return REG_MULTI_SZ;
180 
181         case CM_DRP_CONFIGFLAGS:
182         case CM_DRP_CAPABILITIES:
183         case CM_DRP_UI_NUMBER:
184         case CM_DRP_LEGACYBUSTYPE:
185         case CM_DRP_BUSNUMBER:
186         case CM_DRP_DEVTYPE:
187         case CM_DRP_EXCLUSIVE:
188         case CM_DRP_CHARACTERISTICS:
189         case CM_DRP_ADDRESS:
190         case CM_DRP_REMOVAL_POLICY:
191         case CM_DRP_REMOVAL_POLICY_HW_DEFAULT:
192         case CM_DRP_REMOVAL_POLICY_OVERRIDE:
193         case CM_DRP_INSTALL_STATE:
194             return REG_DWORD;
195 
196         case CM_DRP_BUSTYPEGUID:
197         case CM_DRP_SECURITY:
198         case CM_DRP_DEVICE_POWER_DATA:
199         default:
200             return REG_BINARY;
201     }
202 
203     return REG_NONE;
204 }
205 
206 
207 static
208 VOID
SplitDeviceInstanceId(_In_ PWSTR pszDeviceInstanceId,_Out_ PWSTR pszDeviceId,_Out_ PWSTR pszInstanceId)209 SplitDeviceInstanceId(
210     _In_ PWSTR pszDeviceInstanceId,
211     _Out_ PWSTR pszDeviceId,
212     _Out_ PWSTR pszInstanceId)
213 {
214     PWCHAR ptr;
215 
216     wcscpy(pszDeviceId, pszDeviceInstanceId);
217 
218     ptr = wcschr(pszDeviceId, L'\\');
219     if (ptr != NULL)
220     {
221         *ptr = UNICODE_NULL;
222         ptr++;
223 
224         wcscpy(pszInstanceId, ptr);
225     }
226     else
227     {
228         *pszInstanceId = UNICODE_NULL;
229     }
230 }
231 
232 
233 static
234 CONFIGRET
GetDeviceInstanceKeyPath(_In_ RPC_BINDING_HANDLE BindingHandle,_In_ PWSTR pszDeviceInst,_Out_ PWSTR pszKeyPath,_Out_ PWSTR pszInstancePath,_In_ ULONG ulHardwareProfile,_In_ ULONG ulFlags)235 GetDeviceInstanceKeyPath(
236     _In_ RPC_BINDING_HANDLE BindingHandle,
237     _In_ PWSTR pszDeviceInst,
238     _Out_ PWSTR pszKeyPath,
239     _Out_ PWSTR pszInstancePath,
240     _In_ ULONG ulHardwareProfile,
241     _In_ ULONG ulFlags)
242 {
243     PWSTR pszBuffer = NULL;
244     ULONG ulType = 0;
245     ULONG ulTransferLength, ulLength;
246     CONFIGRET ret = CR_SUCCESS;
247 
248     TRACE("GetDeviceInstanceKeyPath()\n");
249 
250     /* Allocate a buffer for the device id */
251     pszBuffer = MyMalloc(300 * sizeof(WCHAR));
252     if (pszBuffer == NULL)
253     {
254         ERR("MyMalloc() failed\n");
255         return CR_OUT_OF_MEMORY;
256     }
257 
258     if (ulFlags & CM_REGISTRY_SOFTWARE)
259     {
260         /* Software Key Path */
261 
262         ulTransferLength = 300 * sizeof(WCHAR);
263         ulLength = 300 * sizeof(WCHAR);
264 
265         RpcTryExcept
266         {
267             ret = PNP_GetDeviceRegProp(BindingHandle,
268                                        pszDeviceInst,
269                                        CM_DRP_DRIVER,
270                                        &ulType,
271                                        (PVOID)pszBuffer,
272                                        &ulTransferLength,
273                                        &ulLength,
274                                        0);
275         }
276         RpcExcept(EXCEPTION_EXECUTE_HANDLER)
277         {
278             ret = RpcStatusToCmStatus(RpcExceptionCode());
279         }
280         RpcEndExcept;
281 
282         if (ret != CR_SUCCESS)
283         {
284             RpcTryExcept
285             {
286                 ret = PNP_GetClassInstance(BindingHandle,
287                                            pszDeviceInst,
288                                            (PVOID)pszBuffer,
289                                            300);
290             }
291             RpcExcept(EXCEPTION_EXECUTE_HANDLER)
292             {
293                 ret = RpcStatusToCmStatus(RpcExceptionCode());
294             }
295             RpcEndExcept;
296 
297             if (ret != CR_SUCCESS)
298             {
299                 goto done;
300             }
301         }
302 
303         TRACE("szBuffer: %S\n", pszBuffer);
304 
305         SplitDeviceInstanceId(pszBuffer,
306                               pszBuffer,
307                               pszInstancePath);
308 
309         TRACE("szBuffer: %S\n", pszBuffer);
310 
311         if (ulFlags & CM_REGISTRY_CONFIG)
312         {
313             if (ulHardwareProfile == 0)
314             {
315                 wsprintfW(pszKeyPath,
316                           L"%s\\%s\\%s\\%s",
317                           L"System\\CurrentControlSet\\Hardware Profiles",
318                           L"Current",
319                           L"System\\CurrentControlSet\\Control\\Class",
320                           pszBuffer);
321             }
322             else
323             {
324                 wsprintfW(pszKeyPath,
325                           L"%s\\%04lu\\%s\\%s",
326                           L"System\\CurrentControlSet\\Hardware Profiles",
327                           ulHardwareProfile,
328                           L"System\\CurrentControlSet\\Control\\Class",
329                           pszBuffer);
330             }
331         }
332         else
333         {
334             wsprintfW(pszKeyPath,
335                       L"%s\\%s",
336                       L"System\\CurrentControlSet\\Control\\Class",
337                       pszBuffer);
338         }
339     }
340     else
341     {
342         /* Hardware Key Path */
343 
344         if (ulFlags & CM_REGISTRY_CONFIG)
345         {
346             SplitDeviceInstanceId(pszDeviceInst,
347                                   pszBuffer,
348                                   pszInstancePath);
349 
350             if (ulHardwareProfile == 0)
351             {
352                 wsprintfW(pszKeyPath,
353                           L"%s\\%s\\%s\\%s",
354                           L"System\\CurrentControlSet\\Hardware Profiles",
355                           L"Current",
356                           L"System\\CurrentControlSet\\Enum",
357                           pszBuffer);
358             }
359             else
360             {
361                 wsprintfW(pszKeyPath,
362                           L"%s\\%04lu\\%s\\%s",
363                           L"System\\CurrentControlSet\\Hardware Profiles",
364                           ulHardwareProfile,
365                           L"System\\CurrentControlSet\\Enum",
366                           pszBuffer);
367             }
368         }
369         else if (ulFlags & CM_REGISTRY_USER)
370         {
371             wsprintfW(pszKeyPath,
372                       L"%s\\%s",
373                       L"System\\CurrentControlSet\\Enum",
374                       pszDeviceInst);
375 
376             wcscpy(pszInstancePath,
377                    L"Device Parameters");
378         }
379         else
380         {
381             SplitDeviceInstanceId(pszDeviceInst,
382                                   pszBuffer,
383                                   pszInstancePath);
384 
385             wsprintfW(pszKeyPath,
386                       L"%s\\%s",
387                       L"System\\CurrentControlSet\\Enum",
388                       pszBuffer);
389         }
390     }
391 
392 done:
393     if (pszBuffer != NULL)
394         MyFree(pszBuffer);
395 
396     return ret;
397 }
398 
399 
400 BOOL
IsValidRangeList(_In_opt_ PINTERNAL_RANGE_LIST pRangeList)401 IsValidRangeList(
402     _In_opt_ PINTERNAL_RANGE_LIST pRangeList)
403 {
404     BOOL bValid = TRUE;
405 
406     if (pRangeList == NULL)
407         return FALSE;
408 
409     _SEH2_TRY
410     {
411         if (pRangeList->ulMagic != RANGE_LIST_MAGIC)
412             bValid = FALSE;
413     }
414     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
415     {
416         bValid = FALSE;
417     }
418     _SEH2_END;
419 
420     return bValid;
421 }
422 
423 
424 BOOL
IsValidLogConf(_In_opt_ PLOG_CONF_INFO pLogConfInfo)425 IsValidLogConf(
426     _In_opt_ PLOG_CONF_INFO pLogConfInfo)
427 {
428     BOOL bValid = TRUE;
429 
430     if (pLogConfInfo == NULL)
431         return FALSE;
432 
433     _SEH2_TRY
434     {
435         if (pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
436             bValid = FALSE;
437     }
438     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
439     {
440         bValid = FALSE;
441     }
442     _SEH2_END;
443 
444     return bValid;
445 }
446 
447 
448 BOOL
IsValidResDes(_In_opt_ PRES_DES_INFO pResDesInfo)449 IsValidResDes(
450     _In_opt_ PRES_DES_INFO pResDesInfo)
451 {
452     BOOL bValid = TRUE;
453 
454     if (pResDesInfo == NULL)
455         return FALSE;
456 
457     _SEH2_TRY
458     {
459         if (pResDesInfo->ulMagic != RES_DES_MAGIC)
460             bValid = FALSE;
461     }
462     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
463     {
464         bValid = FALSE;
465     }
466     _SEH2_END;
467 
468     return bValid;
469 }
470 
471 
472 BOOL
IsValidConflictData(_In_opt_ PCONFLICT_DATA pConflictData)473 IsValidConflictData(
474     _In_opt_ PCONFLICT_DATA pConflictData)
475 {
476     BOOL bValid = TRUE;
477 
478     if (pConflictData == NULL)
479         return FALSE;
480 
481     _SEH2_TRY
482     {
483         if (pConflictData->ulMagic != CONFLICT_MAGIC)
484             bValid = FALSE;
485     }
486     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
487     {
488         bValid = FALSE;
489     }
490     _SEH2_END;
491 
492     return bValid;
493 }
494 
495 
496 /***********************************************************************
497  * CMP_GetBlockedDriverInfo [SETUPAPI.@]
498  */
499 CONFIGRET
500 WINAPI
CMP_GetBlockedDriverInfo(_Out_opt_ LPWSTR pszNames,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)501 CMP_GetBlockedDriverInfo(
502     _Out_opt_ LPWSTR pszNames,
503     _Inout_ PULONG pulLength,
504     _In_ ULONG ulFlags,
505     _In_opt_ HMACHINE hMachine)
506 {
507     RPC_BINDING_HANDLE BindingHandle = NULL;
508     ULONG ulTransferLength;
509     CONFIGRET ret;
510 
511     TRACE("CMP_GetBlockedDriverInfo(%p %p %lx %p)\n",
512           pszNames, pulLength, ulFlags, hMachine);
513 
514     if (hMachine != NULL)
515     {
516         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
517         if (BindingHandle == NULL)
518             return CR_FAILURE;
519     }
520     else
521     {
522         if (!PnpGetLocalHandles(&BindingHandle, NULL))
523             return CR_FAILURE;
524     }
525 
526     ulTransferLength = *pulLength;
527 
528     RpcTryExcept
529     {
530         ret = PNP_GetBlockedDriverInfo(BindingHandle,
531                                        (PBYTE)pszNames,
532                                        &ulTransferLength,
533                                        pulLength,
534                                        ulFlags);
535     }
536     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
537     {
538         ret = RpcStatusToCmStatus(RpcExceptionCode());
539     }
540     RpcEndExcept;
541 
542     return ret;
543 }
544 
545 
546 /***********************************************************************
547  * CMP_GetServerSideDeviceInstallFlags [SETUPAPI.@]
548  */
549 CONFIGRET
550 WINAPI
CMP_GetServerSideDeviceInstallFlags(_Out_ PULONG pulSSDIFlags,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)551 CMP_GetServerSideDeviceInstallFlags(
552     _Out_ PULONG pulSSDIFlags,
553     _In_ ULONG ulFlags,
554     _In_opt_ HMACHINE hMachine)
555 {
556     RPC_BINDING_HANDLE BindingHandle = NULL;
557     CONFIGRET ret;
558 
559     TRACE("CMP_GetServerSideDeviceInstallFlags(%p %lx %p)\n",
560           pulSSDIFlags, ulFlags, hMachine);
561 
562     if (pulSSDIFlags == NULL)
563         return CR_INVALID_POINTER;
564 
565     if (ulFlags != 0)
566         return CR_INVALID_FLAG;
567 
568     if (hMachine != NULL)
569     {
570         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
571         if (BindingHandle == NULL)
572             return CR_FAILURE;
573     }
574     else
575     {
576         if (!PnpGetLocalHandles(&BindingHandle, NULL))
577             return CR_FAILURE;
578     }
579 
580     RpcTryExcept
581     {
582         ret = PNP_GetServerSideDeviceInstallFlags(BindingHandle,
583                                                   pulSSDIFlags,
584                                                   ulFlags);
585     }
586     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
587     {
588         ret = RpcStatusToCmStatus(RpcExceptionCode());
589     }
590     RpcEndExcept;
591 
592     return ret;
593 }
594 
595 
596 /***********************************************************************
597  * CMP_Init_Detection [SETUPAPI.@]
598  */
599 CONFIGRET
600 WINAPI
CMP_Init_Detection(_In_ ULONG ulMagic)601 CMP_Init_Detection(
602     _In_ ULONG ulMagic)
603 {
604     RPC_BINDING_HANDLE BindingHandle = NULL;
605     CONFIGRET ret;
606 
607     TRACE("CMP_Init_Detection(%lu)\n", ulMagic);
608 
609     if (ulMagic != CMP_MAGIC)
610         return CR_INVALID_DATA;
611 
612     if (!PnpGetLocalHandles(&BindingHandle, NULL))
613         return CR_FAILURE;
614 
615     RpcTryExcept
616     {
617         ret = PNP_InitDetection(BindingHandle);
618     }
619     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
620     {
621         ret = RpcStatusToCmStatus(RpcExceptionCode());
622     }
623     RpcEndExcept;
624 
625     return ret;
626 }
627 
628 
629 /***********************************************************************
630  * CMP_RegisterNotification [SETUPAPI.@]
631  */
632 CONFIGRET
633 WINAPI
CMP_RegisterNotification(_In_ HANDLE hRecipient,_In_ LPVOID lpvNotificationFilter,_In_ ULONG ulFlags,_Out_ PHDEVNOTIFY phDevNotify)634 CMP_RegisterNotification(
635     _In_ HANDLE hRecipient,
636     _In_ LPVOID lpvNotificationFilter,
637     _In_ ULONG ulFlags,
638     _Out_ PHDEVNOTIFY phDevNotify)
639 {
640     RPC_BINDING_HANDLE BindingHandle = NULL;
641     PNOTIFY_DATA pNotifyData;
642     WCHAR szNameBuffer[256];
643     INT nLength;
644     DWORD ulUnknown9 = 0;
645     DWORD dwError;
646     CONFIGRET ret = CR_SUCCESS;
647 
648     FIXME("CMP_RegisterNotification(%p %p %lu %p)\n",
649           hRecipient, lpvNotificationFilter, ulFlags, phDevNotify);
650 
651     if ((hRecipient == NULL) ||
652         (lpvNotificationFilter == NULL) ||
653         (phDevNotify == NULL))
654         return CR_INVALID_POINTER;
655 
656     if (ulFlags & ~0x7)
657         return CR_INVALID_FLAG;
658 
659     if (((PDEV_BROADCAST_HDR)lpvNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR))
660         return CR_INVALID_DATA;
661 
662     if (!PnpGetLocalHandles(&BindingHandle, NULL))
663         return CR_FAILURE;
664 
665     pNotifyData = HeapAlloc(GetProcessHeap(),
666                             HEAP_ZERO_MEMORY,
667                             sizeof(NOTIFY_DATA));
668     if (pNotifyData == NULL)
669         return CR_OUT_OF_MEMORY;
670 
671     pNotifyData->ulMagic = NOTIFY_MAGIC;
672     pNotifyData->hNotifyHandle = NULL;
673 
674     ZeroMemory(szNameBuffer, sizeof(szNameBuffer));
675 
676     if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_WINDOW_HANDLE)
677     {
678         FIXME("Register a window\n");
679 
680         nLength = GetWindowTextW((HWND)hRecipient,
681                                  szNameBuffer,
682                                  ARRAYSIZE(szNameBuffer));
683         if (nLength == 0)
684         {
685             szNameBuffer[0] = UNICODE_NULL;
686         }
687 
688         FIXME("Register window: %S\n", szNameBuffer);
689     }
690     else if ((ulFlags & DEVICE_NOTIFY_SERVICE_HANDLE) == DEVICE_NOTIFY_SERVICE_HANDLE)
691     {
692         FIXME("Register a service\n");
693 
694         dwError = I_ScPnPGetServiceName((SERVICE_STATUS_HANDLE)hRecipient,
695                                         szNameBuffer,
696                                         ARRAYSIZE(szNameBuffer));
697         if (dwError != ERROR_SUCCESS)
698         {
699             HeapFree(GetProcessHeap(), 0, pNotifyData);
700             return CR_INVALID_DATA;
701         }
702 
703         FIXME("Register service: %S\n", szNameBuffer);
704     }
705 
706     RpcTryExcept
707     {
708         ret = PNP_RegisterNotification(BindingHandle,
709                                        (DWORD_PTR)hRecipient,
710                                        szNameBuffer,
711                                        (BYTE*)lpvNotificationFilter,
712                                        ((DEV_BROADCAST_HDR*)lpvNotificationFilter)->dbch_size,
713                                        ulFlags,
714                                        &pNotifyData->hNotifyHandle,
715                                        GetCurrentProcessId(),
716                                        &ulUnknown9); /* ??? */
717     }
718     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
719     {
720         ret = RpcStatusToCmStatus(RpcExceptionCode());
721     }
722     RpcEndExcept;
723 
724     if (ret == CR_SUCCESS)
725     {
726         TRACE("hNotifyHandle: %p\n", pNotifyData->hNotifyHandle);
727         *phDevNotify = (HDEVNOTIFY)pNotifyData;
728     }
729     else
730     {
731         HeapFree(GetProcessHeap(), 0, pNotifyData);
732 
733         *phDevNotify = (HDEVNOTIFY)NULL;
734     }
735 
736     return ret;
737 }
738 
739 
740 /***********************************************************************
741  * CMP_Report_LogOn [SETUPAPI.@]
742  */
743 CONFIGRET
744 WINAPI
CMP_Report_LogOn(_In_ DWORD dwMagic,_In_ DWORD dwProcessId)745 CMP_Report_LogOn(
746     _In_ DWORD dwMagic,
747     _In_ DWORD dwProcessId)
748 {
749     RPC_BINDING_HANDLE BindingHandle = NULL;
750     CONFIGRET ret = CR_SUCCESS;
751     BOOL bAdmin;
752     DWORD i;
753 
754     TRACE("CMP_Report_LogOn(%lu %lu)\n", dwMagic, dwProcessId);
755 
756     if (dwMagic != CMP_MAGIC)
757         return CR_INVALID_DATA;
758 
759     if (!PnpGetLocalHandles(&BindingHandle, NULL))
760         return CR_FAILURE;
761 
762     bAdmin = pSetupIsUserAdmin();
763 
764     for (i = 0; i < 30; i++)
765     {
766         RpcTryExcept
767         {
768             ret = PNP_ReportLogOn(BindingHandle,
769                                   bAdmin,
770                                   dwProcessId);
771         }
772         RpcExcept(EXCEPTION_EXECUTE_HANDLER)
773         {
774             ret = RpcStatusToCmStatus(RpcExceptionCode());
775         }
776         RpcEndExcept;
777 
778         if (ret == CR_SUCCESS)
779             break;
780 
781         Sleep(5000);
782     }
783 
784     return ret;
785 }
786 
787 
788 /***********************************************************************
789  * CMP_UnregisterNotification [SETUPAPI.@]
790  */
791 CONFIGRET
792 WINAPI
CMP_UnregisterNotification(_In_ HDEVNOTIFY hDevNotify)793 CMP_UnregisterNotification(
794     _In_ HDEVNOTIFY hDevNotify)
795 {
796     RPC_BINDING_HANDLE BindingHandle = NULL;
797     PNOTIFY_DATA pNotifyData;
798     CONFIGRET ret = CR_SUCCESS;
799 
800     TRACE("CMP_UnregisterNotification(%p)\n", hDevNotify);
801 
802     pNotifyData = (PNOTIFY_DATA)hDevNotify;
803 
804     if ((pNotifyData == NULL) ||
805         (pNotifyData->ulMagic != NOTIFY_MAGIC))
806         return CR_INVALID_POINTER;
807 
808     if (!PnpGetLocalHandles(&BindingHandle, NULL))
809         return CR_FAILURE;
810 
811     RpcTryExcept
812     {
813         ret = PNP_UnregisterNotification(BindingHandle,
814                                          &pNotifyData->hNotifyHandle);
815     }
816     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
817     {
818         ret = RpcStatusToCmStatus(RpcExceptionCode());
819     }
820     RpcEndExcept;
821 
822     if (ret == CR_SUCCESS)
823     {
824         pNotifyData->hNotifyHandle = NULL;
825         HeapFree(GetProcessHeap(), 0, pNotifyData);
826     }
827 
828     return ret;
829 }
830 
831 
832 /***********************************************************************
833  * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
834  */
835 DWORD
836 WINAPI
CMP_WaitNoPendingInstallEvents(_In_ DWORD dwTimeout)837 CMP_WaitNoPendingInstallEvents(
838     _In_ DWORD dwTimeout)
839 {
840     HANDLE hEvent;
841     DWORD ret;
842 
843     TRACE("CMP_WaitNoPendingInstallEvents(%lu)\n", dwTimeout);
844 
845     hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
846     if (hEvent == NULL)
847        return WAIT_FAILED;
848 
849     ret = WaitForSingleObject(hEvent, dwTimeout);
850     CloseHandle(hEvent);
851     return ret;
852 }
853 
854 
855 /***********************************************************************
856  * CMP_WaitServicesAvailable [SETUPAPI.@]
857  */
858 CONFIGRET
859 WINAPI
CMP_WaitServicesAvailable(_In_opt_ HMACHINE hMachine)860 CMP_WaitServicesAvailable(
861     _In_opt_ HMACHINE hMachine)
862 {
863     RPC_BINDING_HANDLE BindingHandle = NULL;
864     CONFIGRET ret = CR_SUCCESS;
865     WORD Version;
866 
867     TRACE("CMP_WaitServicesAvailable(%p)\n", hMachine);
868 
869     if (hMachine != NULL)
870     {
871         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
872         if (BindingHandle == NULL)
873             return CR_FAILURE;
874     }
875     else
876     {
877         if (!PnpGetLocalHandles(&BindingHandle, NULL))
878             return CR_FAILURE;
879     }
880 
881     RpcTryExcept
882     {
883         ret = PNP_GetVersion(BindingHandle, &Version);
884     }
885     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
886     {
887         ret = RpcStatusToCmStatus(RpcExceptionCode());
888     }
889     RpcEndExcept;
890 
891     return ret;
892 }
893 
894 
895 /***********************************************************************
896  * CM_Add_Empty_Log_Conf [SETUPAPI.@]
897  */
898 CONFIGRET
899 WINAPI
CM_Add_Empty_Log_Conf(_Out_ PLOG_CONF plcLogConf,_In_ DEVINST dnDevInst,_In_ PRIORITY Priority,_In_ ULONG ulFlags)900 CM_Add_Empty_Log_Conf(
901     _Out_ PLOG_CONF plcLogConf,
902     _In_ DEVINST dnDevInst,
903     _In_ PRIORITY Priority,
904     _In_ ULONG ulFlags)
905 {
906     TRACE("CM_Add_Empty_Log_Conf(%p %p %lu %lx)\n",
907           plcLogConf, dnDevInst, Priority, ulFlags);
908 
909     return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
910                                     ulFlags, NULL);
911 }
912 
913 
914 /***********************************************************************
915  * CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
916  */
917 CONFIGRET
918 WINAPI
CM_Add_Empty_Log_Conf_Ex(_Out_ PLOG_CONF plcLogConf,_In_ DEVINST dnDevInst,_In_ PRIORITY Priority,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)919 CM_Add_Empty_Log_Conf_Ex(
920     _Out_ PLOG_CONF plcLogConf,
921     _In_ DEVINST dnDevInst,
922     _In_ PRIORITY Priority,
923     _In_ ULONG ulFlags,
924     _In_opt_ HMACHINE hMachine)
925 {
926     RPC_BINDING_HANDLE BindingHandle = NULL;
927     HSTRING_TABLE StringTable = NULL;
928     ULONG ulLogConfTag = 0;
929     LPWSTR lpDevInst;
930     PLOG_CONF_INFO pLogConfInfo;
931     CONFIGRET ret = CR_SUCCESS;
932 
933     FIXME("CM_Add_Empty_Log_Conf_Ex(%p %p %lu %lx %p)\n",
934           plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
935 
936     if (!pSetupIsUserAdmin())
937         return CR_ACCESS_DENIED;
938 
939     if (plcLogConf == NULL)
940         return CR_INVALID_POINTER;
941 
942     if (dnDevInst == 0)
943         return CR_INVALID_DEVINST;
944 
945     if (Priority > 0xFFFF)
946         return CR_INVALID_PRIORITY;
947 
948     if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
949         return CR_INVALID_FLAG;
950 
951     if (hMachine != NULL)
952     {
953         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
954         if (BindingHandle == NULL)
955             return CR_FAILURE;
956 
957         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
958         if (StringTable == 0)
959             return CR_FAILURE;
960     }
961     else
962     {
963         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
964             return CR_FAILURE;
965     }
966 
967     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
968     if (lpDevInst == NULL)
969         return CR_INVALID_DEVNODE;
970 
971     RpcTryExcept
972     {
973         ret = PNP_AddEmptyLogConf(BindingHandle, lpDevInst, Priority,
974                                   &ulLogConfTag, ulFlags);
975     }
976     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
977     {
978         ret = RpcStatusToCmStatus(RpcExceptionCode());
979     }
980     RpcEndExcept;
981 
982     if (ret == CR_SUCCESS)
983     {
984         pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
985         if (pLogConfInfo == NULL)
986         {
987             ret = CR_OUT_OF_MEMORY;
988         }
989         else
990         {
991             pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
992             pLogConfInfo->dnDevInst = dnDevInst;
993             pLogConfInfo->ulType = ulFlags;
994             pLogConfInfo->ulTag = ulLogConfTag;
995 
996             *plcLogConf = (LOG_CONF)pLogConfInfo;
997 
998             ret = CR_SUCCESS;
999         }
1000     }
1001 
1002     return ret;
1003 }
1004 
1005 
1006 /***********************************************************************
1007  * CM_Add_IDA [SETUPAPI.@]
1008  */
1009 CONFIGRET
1010 WINAPI
CM_Add_IDA(_In_ DEVINST dnDevInst,_In_ PSTR pszID,_In_ ULONG ulFlags)1011 CM_Add_IDA(
1012     _In_ DEVINST dnDevInst,
1013     _In_ PSTR pszID,
1014     _In_ ULONG ulFlags)
1015 {
1016     TRACE("CM_Add_IDA(%p %s %lx)\n",
1017           dnDevInst, debugstr_a(pszID), ulFlags);
1018 
1019     return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
1020 }
1021 
1022 
1023 /***********************************************************************
1024  * CM_Add_IDW [SETUPAPI.@]
1025  */
1026 CONFIGRET
1027 WINAPI
CM_Add_IDW(_In_ DEVINST dnDevInst,_In_ PWSTR pszID,_In_ ULONG ulFlags)1028 CM_Add_IDW(
1029     _In_ DEVINST dnDevInst,
1030     _In_ PWSTR pszID,
1031     _In_ ULONG ulFlags)
1032 {
1033     TRACE("CM_Add_IDW(%p %s %lx)\n",
1034           dnDevInst, debugstr_w(pszID), ulFlags);
1035 
1036     return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
1037 }
1038 
1039 
1040 /***********************************************************************
1041  * CM_Add_ID_ExA [SETUPAPI.@]
1042  */
1043 CONFIGRET
1044 WINAPI
CM_Add_ID_ExA(_In_ DEVINST dnDevInst,_In_ PSTR pszID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)1045 CM_Add_ID_ExA(
1046     _In_ DEVINST dnDevInst,
1047     _In_ PSTR pszID,
1048     _In_ ULONG ulFlags,
1049     _In_opt_ HMACHINE hMachine)
1050 {
1051     PWSTR pszIDW;
1052     CONFIGRET ret;
1053 
1054     TRACE("CM_Add_ID_ExA(%p %s %lx %p)\n",
1055           dnDevInst, debugstr_a(pszID), ulFlags, hMachine);
1056 
1057     if (pSetupCaptureAndConvertAnsiArg(pszID, &pszIDW))
1058         return CR_INVALID_DATA;
1059 
1060     ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);
1061 
1062     MyFree(pszIDW);
1063 
1064     return ret;
1065 }
1066 
1067 
1068 /***********************************************************************
1069  * CM_Add_ID_ExW [SETUPAPI.@]
1070  */
1071 CONFIGRET
1072 WINAPI
CM_Add_ID_ExW(_In_ DEVINST dnDevInst,_In_ PWSTR pszID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)1073 CM_Add_ID_ExW(
1074     _In_ DEVINST dnDevInst,
1075     _In_ PWSTR pszID,
1076     _In_ ULONG ulFlags,
1077     _In_opt_ HMACHINE hMachine)
1078 {
1079     RPC_BINDING_HANDLE BindingHandle = NULL;
1080     HSTRING_TABLE StringTable = NULL;
1081     LPWSTR lpDevInst;
1082     CONFIGRET ret;
1083 
1084     TRACE("CM_Add_ID_ExW(%p %s %lx %p)\n",
1085           dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
1086 
1087     if (!pSetupIsUserAdmin())
1088         return CR_ACCESS_DENIED;
1089 
1090     if (dnDevInst == 0)
1091         return CR_INVALID_DEVINST;
1092 
1093     if (pszID == NULL)
1094         return CR_INVALID_POINTER;
1095 
1096     if (ulFlags & ~CM_ADD_ID_BITS)
1097         return CR_INVALID_FLAG;
1098 
1099     if (hMachine != NULL)
1100     {
1101         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1102         if (BindingHandle == NULL)
1103             return CR_FAILURE;
1104 
1105         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1106         if (StringTable == 0)
1107             return CR_FAILURE;
1108     }
1109     else
1110     {
1111         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1112             return CR_FAILURE;
1113     }
1114 
1115     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1116     if (lpDevInst == NULL)
1117         return CR_INVALID_DEVNODE;
1118 
1119     RpcTryExcept
1120     {
1121         ret = PNP_AddID(BindingHandle,
1122                         lpDevInst,
1123                         pszID,
1124                         ulFlags);
1125     }
1126     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1127     {
1128         ret = RpcStatusToCmStatus(RpcExceptionCode());
1129     }
1130     RpcEndExcept;
1131 
1132     return ret;
1133 }
1134 
1135 
1136 /***********************************************************************
1137  * CM_Add_Range [SETUPAPI.@]
1138  */
1139 CONFIGRET
1140 WINAPI
CM_Add_Range(_In_ DWORDLONG ullStartValue,_In_ DWORDLONG ullEndValue,_In_ RANGE_LIST rlh,_In_ ULONG ulFlags)1141 CM_Add_Range(
1142     _In_ DWORDLONG ullStartValue,
1143     _In_ DWORDLONG ullEndValue,
1144     _In_ RANGE_LIST rlh,
1145     _In_ ULONG ulFlags)
1146 {
1147     PINTERNAL_RANGE_LIST pRangeList;
1148     PINTERNAL_RANGE pRange;
1149     CONFIGRET ret = CR_SUCCESS;
1150 
1151     FIXME("CM_Add_Range(%I64u %I64u %p %lx)\n",
1152           ullStartValue, ullEndValue, rlh, ulFlags);
1153 
1154     pRangeList = (PINTERNAL_RANGE_LIST)rlh;
1155 
1156     if (!IsValidRangeList(pRangeList))
1157         return CR_INVALID_RANGE_LIST;
1158 
1159     if (ulFlags & ~CM_ADD_RANGE_BITS)
1160         return CR_INVALID_FLAG;
1161 
1162     if (ullEndValue < ullStartValue)
1163         return CR_INVALID_RANGE;
1164 
1165     /* Lock the range list */
1166     WaitForSingleObject(pRangeList->hMutex, INFINITE);
1167 
1168     /* Allocate the new range */
1169     pRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
1170     if (pRange == NULL)
1171     {
1172         ret = CR_OUT_OF_MEMORY;
1173         goto done;
1174     }
1175 
1176     pRange->pRangeList = pRangeList;
1177     pRange->ullStart = ullStartValue;
1178     pRange->ullEnd = ullEndValue;
1179 
1180     /* Insert the range */
1181     if (IsListEmpty(&pRangeList->ListHead))
1182     {
1183         InsertTailList(&pRangeList->ListHead, &pRange->ListEntry);
1184     }
1185     else
1186     {
1187         HeapFree(GetProcessHeap(), 0, pRange);
1188         UNIMPLEMENTED;
1189     }
1190 
1191 done:
1192     /* Unlock the range list */
1193     ReleaseMutex(pRangeList->hMutex);
1194 
1195     return ret;
1196 }
1197 
1198 
1199 /***********************************************************************
1200  * CM_Add_Res_Des [SETUPAPI.@]
1201  */
1202 CONFIGRET
1203 WINAPI
CM_Add_Res_Des(_Out_opt_ PRES_DES prdResDes,_In_ LOG_CONF lcLogConf,_In_ RESOURCEID ResourceID,_In_reads_bytes_ (ResourceLen)PCVOID ResourceData,_In_ ULONG ResourceLen,_In_ ULONG ulFlags)1204 CM_Add_Res_Des(
1205     _Out_opt_ PRES_DES prdResDes,
1206     _In_ LOG_CONF lcLogConf,
1207     _In_ RESOURCEID ResourceID,
1208     _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1209     _In_ ULONG ResourceLen,
1210     _In_ ULONG ulFlags)
1211 {
1212     TRACE("CM_Add_Res_Des(%p %p %lu %p %lu %lx)\n",
1213           prdResDes, lcLogConf, ResourceID, ResourceData, ResourceLen, ulFlags);
1214 
1215     return CM_Add_Res_Des_Ex(prdResDes, lcLogConf, ResourceID, ResourceData,
1216                              ResourceLen, ulFlags, NULL);
1217 }
1218 
1219 
1220 /***********************************************************************
1221  * CM_Add_Res_Des_Ex [SETUPAPI.@]
1222  */
1223 CONFIGRET
1224 WINAPI
CM_Add_Res_Des_Ex(_Out_opt_ PRES_DES prdResDes,_In_ LOG_CONF lcLogConf,_In_ RESOURCEID ResourceID,_In_reads_bytes_ (ResourceLen)PCVOID ResourceData,_In_ ULONG ResourceLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)1225 CM_Add_Res_Des_Ex(
1226     _Out_opt_ PRES_DES prdResDes,
1227     _In_ LOG_CONF lcLogConf,
1228     _In_ RESOURCEID ResourceID,
1229     _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1230     _In_ ULONG ResourceLen,
1231     _In_ ULONG ulFlags,
1232     _In_opt_ HMACHINE hMachine)
1233 {
1234     FIXME("CM_Add_Res_Des_Ex(%p %p %lu %p %lu %lx %p)\n",
1235           prdResDes, lcLogConf, ResourceID,
1236           ResourceData, ResourceLen, ulFlags, hMachine);
1237 
1238     return CR_CALL_NOT_IMPLEMENTED;
1239 }
1240 
1241 
1242 /***********************************************************************
1243  * CM_Connect_MachineA [SETUPAPI.@]
1244  */
1245 CONFIGRET
1246 WINAPI
CM_Connect_MachineA(_In_opt_ PCSTR UNCServerName,_Out_ PHMACHINE phMachine)1247 CM_Connect_MachineA(
1248     _In_opt_ PCSTR UNCServerName,
1249     _Out_ PHMACHINE phMachine)
1250 {
1251     PWSTR pServerNameW;
1252     CONFIGRET ret;
1253 
1254     TRACE("CM_Connect_MachineA(%s %p)\n",
1255           debugstr_a(UNCServerName), phMachine);
1256 
1257     if (UNCServerName == NULL || *UNCServerName == 0)
1258         return CM_Connect_MachineW(NULL, phMachine);
1259 
1260     if (pSetupCaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
1261         return CR_INVALID_DATA;
1262 
1263     ret = CM_Connect_MachineW(pServerNameW, phMachine);
1264 
1265     MyFree(pServerNameW);
1266 
1267     return ret;
1268 }
1269 
1270 
1271 /***********************************************************************
1272  * CM_Connect_MachineW [SETUPAPI.@]
1273  */
1274 CONFIGRET
1275 WINAPI
CM_Connect_MachineW(_In_opt_ PCWSTR UNCServerName,_Out_ PHMACHINE phMachine)1276 CM_Connect_MachineW(
1277     _In_opt_ PCWSTR UNCServerName,
1278     _Out_ PHMACHINE phMachine)
1279 {
1280     PMACHINE_INFO pMachine;
1281 
1282     TRACE("CM_Connect_MachineW(%s %p)\n",
1283           debugstr_w(UNCServerName), phMachine);
1284 
1285     if (phMachine == NULL)
1286         return CR_INVALID_POINTER;
1287 
1288     *phMachine = NULL;
1289 
1290     pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
1291     if (pMachine == NULL)
1292         return CR_OUT_OF_MEMORY;
1293 
1294     if (UNCServerName == NULL || *UNCServerName == 0)
1295     {
1296         pMachine->bLocal = TRUE;
1297 
1298         /* FIXME: store the computers name in pMachine->szMachineName */
1299 
1300         if (!PnpGetLocalHandles(&pMachine->BindingHandle,
1301                                 &pMachine->StringTable))
1302         {
1303             HeapFree(GetProcessHeap(), 0, pMachine);
1304             return CR_FAILURE;
1305         }
1306     }
1307     else
1308     {
1309         pMachine->bLocal = FALSE;
1310         if (wcslen(UNCServerName) >= SP_MAX_MACHINENAME_LENGTH - 1)
1311         {
1312             HeapFree(GetProcessHeap(), 0, pMachine);
1313             return CR_INVALID_MACHINENAME;
1314         }
1315         lstrcpyW(pMachine->szMachineName, UNCServerName);
1316 
1317         pMachine->StringTable = pSetupStringTableInitialize();
1318         if (pMachine->StringTable == NULL)
1319         {
1320             HeapFree(GetProcessHeap(), 0, pMachine);
1321             return CR_FAILURE;
1322         }
1323 
1324         pSetupStringTableAddString(pMachine->StringTable, L"PLT", 1);
1325 
1326         if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
1327         {
1328             pSetupStringTableDestroy(pMachine->StringTable);
1329             HeapFree(GetProcessHeap(), 0, pMachine);
1330             return CR_INVALID_MACHINENAME;
1331         }
1332     }
1333 
1334     *phMachine = (PHMACHINE)pMachine;
1335 
1336     return CR_SUCCESS;
1337 }
1338 
1339 
1340 /***********************************************************************
1341  * CM_Create_DevNodeA [SETUPAPI.@]
1342  */
1343 CONFIGRET
1344 WINAPI
CM_Create_DevNodeA(_Out_ PDEVINST pdnDevInst,_In_ DEVINSTID_A pDeviceID,_In_ DEVINST dnParent,_In_ ULONG ulFlags)1345 CM_Create_DevNodeA(
1346     _Out_ PDEVINST pdnDevInst,
1347     _In_ DEVINSTID_A pDeviceID,
1348     _In_ DEVINST dnParent,
1349     _In_ ULONG ulFlags)
1350 {
1351     TRACE("CM_Create_DevNodeA(%p %s %p %lx)\n",
1352           pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
1353 
1354     return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
1355                                  ulFlags, NULL);
1356 }
1357 
1358 
1359 /***********************************************************************
1360  * CM_Create_DevNodeW [SETUPAPI.@]
1361  */
1362 CONFIGRET
1363 WINAPI
CM_Create_DevNodeW(_Out_ PDEVINST pdnDevInst,_In_ DEVINSTID_W pDeviceID,_In_ DEVINST dnParent,_In_ ULONG ulFlags)1364 CM_Create_DevNodeW(
1365     _Out_ PDEVINST pdnDevInst,
1366     _In_ DEVINSTID_W pDeviceID,
1367     _In_ DEVINST dnParent,
1368     _In_ ULONG ulFlags)
1369 {
1370     TRACE("CM_Create_DevNodeW(%p %s %p %lx)\n",
1371           pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
1372 
1373     return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
1374                                  ulFlags, NULL);
1375 }
1376 
1377 
1378 /***********************************************************************
1379  * CM_Create_DevNode_ExA [SETUPAPI.@]
1380  */
1381 CONFIGRET
1382 WINAPI
CM_Create_DevNode_ExA(_Out_ PDEVINST pdnDevInst,_In_ DEVINSTID_A pDeviceID,_In_ DEVINST dnParent,_In_ ULONG ulFlags,_In_opt_ HANDLE hMachine)1383 CM_Create_DevNode_ExA(
1384     _Out_ PDEVINST pdnDevInst,
1385     _In_ DEVINSTID_A pDeviceID,
1386     _In_ DEVINST dnParent,
1387     _In_ ULONG ulFlags,
1388     _In_opt_ HANDLE hMachine)
1389 {
1390     DEVINSTID_W pDeviceIDW;
1391     CONFIGRET ret;
1392 
1393     TRACE("CM_Create_DevNode_ExA(%p %s %p %lx %p)\n",
1394           pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
1395 
1396     if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
1397         return CR_INVALID_DATA;
1398 
1399     ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
1400                                 hMachine);
1401 
1402     MyFree(pDeviceIDW);
1403 
1404     return ret;
1405 }
1406 
1407 
1408 /***********************************************************************
1409  * CM_Create_DevNode_ExW [SETUPAPI.@]
1410  */
1411 CONFIGRET
1412 WINAPI
CM_Create_DevNode_ExW(_Out_ PDEVINST pdnDevInst,_In_ DEVINSTID_W pDeviceID,_In_ DEVINST dnParent,_In_ ULONG ulFlags,_In_opt_ HANDLE hMachine)1413 CM_Create_DevNode_ExW(
1414     _Out_ PDEVINST pdnDevInst,
1415     _In_ DEVINSTID_W pDeviceID,
1416     _In_ DEVINST dnParent,
1417     _In_ ULONG ulFlags,
1418     _In_opt_ HANDLE hMachine)
1419 {
1420     RPC_BINDING_HANDLE BindingHandle = NULL;
1421     HSTRING_TABLE StringTable = NULL;
1422     LPWSTR lpParentDevInst;
1423     CONFIGRET ret = CR_SUCCESS;
1424     WCHAR szLocalDeviceID[MAX_DEVICE_ID_LEN];
1425 
1426     TRACE("CM_Create_DevNode_ExW(%p %s %p %lx %p)\n",
1427           pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
1428 
1429     if (!pSetupIsUserAdmin())
1430         return CR_ACCESS_DENIED;
1431 
1432     if (pdnDevInst == NULL)
1433         return CR_INVALID_POINTER;
1434 
1435     if (pDeviceID == NULL || wcslen(pDeviceID) == 0 || wcslen(pDeviceID) >= MAX_DEVICE_ID_LEN)
1436         return CR_INVALID_DEVICE_ID;
1437 
1438     if (dnParent == 0)
1439         return CR_INVALID_DEVNODE;
1440 
1441     if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
1442         return CR_INVALID_FLAG;
1443 
1444     if (hMachine != NULL)
1445     {
1446         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1447         if (BindingHandle == NULL)
1448             return CR_FAILURE;
1449 
1450         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1451         if (StringTable == 0)
1452             return CR_FAILURE;
1453     }
1454     else
1455     {
1456         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1457             return CR_FAILURE;
1458     }
1459 
1460     lpParentDevInst = pSetupStringTableStringFromId(StringTable, dnParent);
1461     if (lpParentDevInst == NULL)
1462         return CR_INVALID_DEVNODE;
1463 
1464     wcscpy(szLocalDeviceID, pDeviceID);
1465 
1466     RpcTryExcept
1467     {
1468         ret = PNP_CreateDevInst(BindingHandle,
1469                                 szLocalDeviceID,
1470                                 lpParentDevInst,
1471                                 MAX_DEVICE_ID_LEN,
1472                                 ulFlags);
1473     }
1474     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1475     {
1476         ret = RpcStatusToCmStatus(RpcExceptionCode());
1477     }
1478     RpcEndExcept;
1479 
1480     if (ret == CR_SUCCESS)
1481     {
1482         /* If CM_CREATE_DEVINST_GENERATE_ID was passed in, PNP_CreateDevInst
1483          * will return the generated device ID in szLocalDeviceID */
1484         *pdnDevInst = pSetupStringTableAddString(StringTable, szLocalDeviceID, 1);
1485         if (*pdnDevInst == 0)
1486             ret = CR_NO_SUCH_DEVNODE;
1487     }
1488 
1489     return ret;
1490 }
1491 
1492 
1493 /***********************************************************************
1494  * CM_Create_Range_List [SETUPAPI.@]
1495  */
1496 CONFIGRET
1497 WINAPI
CM_Create_Range_List(_Out_ PRANGE_LIST prlh,_In_ ULONG ulFlags)1498 CM_Create_Range_List(
1499     _Out_ PRANGE_LIST prlh,
1500     _In_ ULONG ulFlags)
1501 {
1502     PINTERNAL_RANGE_LIST pRangeList;
1503 
1504     FIXME("CM_Create_Range_List(%p %lx)\n",
1505           prlh, ulFlags);
1506 
1507     if (ulFlags != 0)
1508         return CR_INVALID_FLAG;
1509 
1510     if (prlh == NULL)
1511         return CR_INVALID_POINTER;
1512 
1513     /* Allocate the range list */
1514     pRangeList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(INTERNAL_RANGE_LIST));
1515     if (pRangeList == NULL)
1516         return CR_OUT_OF_MEMORY;
1517 
1518     /* Set the magic value */
1519     pRangeList->ulMagic = RANGE_LIST_MAGIC;
1520 
1521     /* Initialize the mutex for synchonized access */
1522     pRangeList->hMutex = CreateMutex(NULL, FALSE, NULL);
1523     if (pRangeList->hMutex == NULL)
1524     {
1525         HeapFree(GetProcessHeap(), 0, pRangeList);
1526         return CR_FAILURE;
1527     }
1528 
1529     InitializeListHead(&pRangeList->ListHead);
1530 
1531     *prlh = (RANGE_LIST)pRangeList;
1532 
1533     return CR_SUCCESS;
1534 }
1535 
1536 
1537 /***********************************************************************
1538  * CM_Delete_Class_Key [SETUPAPI.@]
1539  */
1540 CONFIGRET
1541 WINAPI
CM_Delete_Class_Key(_In_ LPGUID ClassGuid,_In_ ULONG ulFlags)1542 CM_Delete_Class_Key(
1543     _In_ LPGUID ClassGuid,
1544     _In_ ULONG ulFlags)
1545 {
1546     TRACE("CM_Delete_Class_Key(%p %lx)\n",
1547           ClassGuid, ulFlags);
1548 
1549     return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
1550 }
1551 
1552 
1553 /***********************************************************************
1554  * CM_Delete_Class_Key_Ex [SETUPAPI.@]
1555  */
1556 CONFIGRET
1557 WINAPI
CM_Delete_Class_Key_Ex(_In_ LPGUID ClassGuid,_In_ ULONG ulFlags,_In_opt_ HANDLE hMachine)1558 CM_Delete_Class_Key_Ex(
1559     _In_ LPGUID ClassGuid,
1560     _In_ ULONG ulFlags,
1561     _In_opt_ HANDLE hMachine)
1562 {
1563     WCHAR szGuidString[MAX_GUID_STRING_LEN];
1564     RPC_BINDING_HANDLE BindingHandle = NULL;
1565     CONFIGRET ret;
1566 
1567     TRACE("CM_Delete_Class_Key_Ex(%p %lx %p)\n",
1568           ClassGuid, ulFlags, hMachine);
1569 
1570     if (ClassGuid == NULL)
1571         return CR_INVALID_POINTER;
1572 
1573     if (ulFlags & ~CM_DELETE_CLASS_BITS)
1574         return CR_INVALID_FLAG;
1575 
1576     if (!GuidToString(ClassGuid, szGuidString))
1577         return CR_INVALID_DATA;
1578 
1579     if (hMachine != NULL)
1580     {
1581         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1582         if (BindingHandle == NULL)
1583             return CR_FAILURE;
1584     }
1585     else
1586     {
1587         if (!PnpGetLocalHandles(&BindingHandle, NULL))
1588             return CR_FAILURE;
1589     }
1590 
1591     RpcTryExcept
1592     {
1593         ret = PNP_DeleteClassKey(BindingHandle,
1594                                  szGuidString,
1595                                  ulFlags);
1596     }
1597     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1598     {
1599         ret = RpcStatusToCmStatus(RpcExceptionCode());
1600     }
1601     RpcEndExcept;
1602 
1603     return ret;
1604 }
1605 
1606 
1607 /***********************************************************************
1608  * CM_Delete_DevNode_Key [SETUPAPI.@]
1609  */
1610 CONFIGRET
1611 WINAPI
CM_Delete_DevNode_Key(_In_ DEVINST dnDevInst,_In_ ULONG ulHardwareProfile,_In_ ULONG ulFlags)1612 CM_Delete_DevNode_Key(
1613     _In_ DEVINST dnDevInst,
1614     _In_ ULONG ulHardwareProfile,
1615     _In_ ULONG ulFlags)
1616 {
1617     TRACE("CM_Delete_DevNode_Key(%p %lu %lx)\n",
1618           dnDevInst, ulHardwareProfile, ulFlags);
1619 
1620     return CM_Delete_DevNode_Key_Ex(dnDevInst, ulHardwareProfile, ulFlags,
1621                                     NULL);
1622 }
1623 
1624 
1625 /***********************************************************************
1626  * CM_Delete_DevNode_Key_Ex [SETUPAPI.@]
1627  */
1628 CONFIGRET
1629 WINAPI
CM_Delete_DevNode_Key_Ex(_In_ DEVINST dnDevInst,_In_ ULONG ulHardwareProfile,_In_ ULONG ulFlags,_In_opt_ HANDLE hMachine)1630 CM_Delete_DevNode_Key_Ex(
1631     _In_ DEVINST dnDevInst,
1632     _In_ ULONG ulHardwareProfile,
1633     _In_ ULONG ulFlags,
1634     _In_opt_ HANDLE hMachine)
1635 {
1636     RPC_BINDING_HANDLE BindingHandle = NULL;
1637     HSTRING_TABLE StringTable = NULL;
1638     PWSTR pszDevInst, pszKeyPath = NULL, pszInstancePath = NULL;
1639     CONFIGRET ret;
1640 
1641     FIXME("CM_Delete_DevNode_Key_Ex(%p %lu %lx %p)\n",
1642           dnDevInst, ulHardwareProfile, ulFlags, hMachine);
1643 
1644     if (dnDevInst == 0)
1645         return CR_INVALID_DEVINST;
1646 
1647     if (ulFlags & ~CM_REGISTRY_BITS)
1648         return CR_INVALID_FLAG;
1649 
1650     if ((ulFlags & CM_REGISTRY_USER) && (ulFlags & CM_REGISTRY_CONFIG))
1651         return CR_INVALID_FLAG;
1652 
1653     if (hMachine != NULL)
1654     {
1655         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1656         if (BindingHandle == NULL)
1657             return CR_FAILURE;
1658 
1659         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1660         if (StringTable == 0)
1661             return CR_FAILURE;
1662     }
1663     else
1664     {
1665         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1666             return CR_FAILURE;
1667     }
1668 
1669     pszDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1670     if (pszDevInst == NULL)
1671         return CR_INVALID_DEVNODE;
1672 
1673     TRACE("pszDevInst: %S\n", pszDevInst);
1674 
1675     pszKeyPath = MyMalloc(512 * sizeof(WCHAR));
1676     if (pszKeyPath == NULL)
1677     {
1678         ret = CR_OUT_OF_MEMORY;
1679         goto done;
1680     }
1681 
1682     pszInstancePath = MyMalloc(512 * sizeof(WCHAR));
1683     if (pszInstancePath == NULL)
1684     {
1685         ret = CR_OUT_OF_MEMORY;
1686         goto done;
1687     }
1688 
1689     ret = GetDeviceInstanceKeyPath(BindingHandle,
1690                                    pszDevInst,
1691                                    pszKeyPath,
1692                                    pszInstancePath,
1693                                    ulHardwareProfile,
1694                                    ulFlags);
1695     if (ret != CR_SUCCESS)
1696         goto done;
1697 
1698     TRACE("pszKeyPath: %S\n", pszKeyPath);
1699     TRACE("pszInstancePath: %S\n", pszInstancePath);
1700 
1701     if (ulFlags & CM_REGISTRY_USER)
1702     {
1703         FIXME("The CM_REGISTRY_USER flag is not supported yet!\n");
1704     }
1705     else
1706     {
1707 #if 0
1708         if (!pSetupIsUserAdmin())
1709         {
1710             ret = CR_ACCESS_DENIED;
1711             goto done;
1712         }
1713 #endif
1714 
1715         if (!(ulFlags & CM_REGISTRY_CONFIG))
1716             ulHardwareProfile = 0;
1717 
1718         RpcTryExcept
1719         {
1720             ret = PNP_DeleteRegistryKey(BindingHandle,
1721                                         pszDevInst,
1722                                         pszKeyPath,
1723                                         pszInstancePath,
1724                                         ulHardwareProfile);
1725         }
1726         RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1727         {
1728             ret = RpcStatusToCmStatus(RpcExceptionCode());
1729         }
1730         RpcEndExcept;
1731     }
1732 
1733 done:
1734     if (pszInstancePath != NULL)
1735         MyFree(pszInstancePath);
1736 
1737     if (pszKeyPath != NULL)
1738         MyFree(pszKeyPath);
1739 
1740     return ret;
1741 }
1742 
1743 
1744 /***********************************************************************
1745  * CM_Delete_Range [SETUPAPI.@]
1746  */
1747 CONFIGRET
1748 WINAPI
CM_Delete_Range(_In_ DWORDLONG ullStartValue,_In_ DWORDLONG ullEndValue,_In_ RANGE_LIST rlh,_In_ ULONG ulFlags)1749 CM_Delete_Range(
1750     _In_ DWORDLONG ullStartValue,
1751     _In_ DWORDLONG ullEndValue,
1752     _In_ RANGE_LIST rlh,
1753     _In_ ULONG ulFlags)
1754 {
1755     FIXME("CM_Delete_Range(%I64u %I64u %p %lx)\n",
1756           ullStartValue, ullEndValue, rlh, ulFlags);
1757 
1758     return CR_CALL_NOT_IMPLEMENTED;
1759 }
1760 
1761 
1762 /***********************************************************************
1763  * CM_Detect_Resource_Conflict [SETUPAPI.@]
1764  */
1765 CONFIGRET
1766 WINAPI
CM_Detect_Resource_Conflict(_In_ DEVINST dnDevInst,_In_ RESOURCEID ResourceID,_In_reads_bytes_ (ResourceLen)PCVOID ResourceData,_In_ ULONG ResourceLen,_Out_ PBOOL pbConflictDetected,_In_ ULONG ulFlags)1767 CM_Detect_Resource_Conflict(
1768     _In_ DEVINST dnDevInst,
1769     _In_ RESOURCEID ResourceID,
1770     _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1771     _In_ ULONG ResourceLen,
1772     _Out_ PBOOL pbConflictDetected,
1773     _In_ ULONG ulFlags)
1774 {
1775     TRACE("CM_Detect_Resource_Conflict(%p %lu %p %lu %p 0x%lx)\n",
1776           dnDevInst, ResourceID, ResourceData, ResourceLen,
1777           pbConflictDetected, ulFlags);
1778 
1779     return CM_Detect_Resource_Conflict_Ex(dnDevInst,
1780                                           ResourceID,
1781                                           ResourceData,
1782                                           ResourceLen,
1783                                           pbConflictDetected,
1784                                           ulFlags,
1785                                           NULL);
1786 }
1787 
1788 
1789 /***********************************************************************
1790  * CM_Detect_Resource_Conflict_Ex [SETUPAPI.@]
1791  */
1792 CONFIGRET
1793 WINAPI
CM_Detect_Resource_Conflict_Ex(_In_ DEVINST dnDevInst,_In_ RESOURCEID ResourceID,_In_reads_bytes_ (ResourceLen)PCVOID ResourceData,_In_ ULONG ResourceLen,_Out_ PBOOL pbConflictDetected,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)1794 CM_Detect_Resource_Conflict_Ex(
1795     _In_ DEVINST dnDevInst,
1796     _In_ RESOURCEID ResourceID,
1797     _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
1798     _In_ ULONG ResourceLen,
1799     _Out_ PBOOL pbConflictDetected,
1800     _In_ ULONG ulFlags,
1801     _In_opt_ HMACHINE hMachine)
1802 {
1803     FIXME("CM_Detect_Resource_Conflict_Ex(%p %lu %p %lu %p 0x%lx %p)\n",
1804           dnDevInst, ResourceID, ResourceData, ResourceLen,
1805           pbConflictDetected, ulFlags, hMachine);
1806 
1807     return CR_CALL_NOT_IMPLEMENTED;
1808 }
1809 
1810 
1811 /***********************************************************************
1812  * CM_Disable_DevNode [SETUPAPI.@]
1813  */
1814 CONFIGRET
1815 WINAPI
CM_Disable_DevNode(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)1816 CM_Disable_DevNode(
1817     _In_ DEVINST dnDevInst,
1818     _In_ ULONG ulFlags)
1819 {
1820     TRACE("CM_Disable_DevNode(%p %lx)\n",
1821           dnDevInst, ulFlags);
1822 
1823     return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
1824 }
1825 
1826 
1827 /***********************************************************************
1828  * CM_Disable_DevNode_Ex [SETUPAPI.@]
1829  */
1830 CONFIGRET
1831 WINAPI
CM_Disable_DevNode_Ex(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)1832 CM_Disable_DevNode_Ex(
1833     _In_ DEVINST dnDevInst,
1834     _In_ ULONG ulFlags,
1835     _In_opt_ HMACHINE hMachine)
1836 {
1837     RPC_BINDING_HANDLE BindingHandle = NULL;
1838     HSTRING_TABLE StringTable = NULL;
1839     LPWSTR lpDevInst;
1840     CONFIGRET ret;
1841 
1842     TRACE("CM_Disable_DevNode_Ex(%p %lx %p)\n",
1843           dnDevInst, ulFlags, hMachine);
1844 
1845     if (!pSetupIsUserAdmin())
1846         return CR_ACCESS_DENIED;
1847 
1848     if (dnDevInst == 0)
1849         return CR_INVALID_DEVINST;
1850 
1851     if (ulFlags != 0)
1852         return CR_INVALID_FLAG;
1853 
1854     if (hMachine != NULL)
1855     {
1856         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1857         if (BindingHandle == NULL)
1858             return CR_FAILURE;
1859 
1860         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1861         if (StringTable == 0)
1862             return CR_FAILURE;
1863     }
1864     else
1865     {
1866         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1867             return CR_FAILURE;
1868     }
1869 
1870     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
1871     if (lpDevInst == NULL)
1872         return CR_INVALID_DEVNODE;
1873 
1874     RpcTryExcept
1875     {
1876         ret = PNP_DisableDevInst(BindingHandle,
1877                                  lpDevInst,
1878                                  NULL,
1879                                  NULL,
1880                                  0,
1881                                  ulFlags);
1882     }
1883     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1884     {
1885         ret = RpcStatusToCmStatus(RpcExceptionCode());
1886     }
1887     RpcEndExcept;
1888 
1889     return ret;
1890 }
1891 
1892 
1893 /***********************************************************************
1894  * CM_Disconnect_Machine [SETUPAPI.@]
1895  */
1896 CONFIGRET
1897 WINAPI
CM_Disconnect_Machine(_In_opt_ HMACHINE hMachine)1898 CM_Disconnect_Machine(
1899     _In_opt_ HMACHINE hMachine)
1900 {
1901     PMACHINE_INFO pMachine;
1902 
1903     TRACE("CM_Disconnect_Machine(%p)\n", hMachine);
1904 
1905     pMachine = (PMACHINE_INFO)hMachine;
1906     if (pMachine == NULL)
1907         return CR_SUCCESS;
1908 
1909     if (pMachine->bLocal == FALSE)
1910     {
1911         if (pMachine->StringTable != NULL)
1912             pSetupStringTableDestroy(pMachine->StringTable);
1913 
1914         if (!PnpUnbindRpc(pMachine->BindingHandle))
1915             return CR_ACCESS_DENIED;
1916     }
1917 
1918     HeapFree(GetProcessHeap(), 0, pMachine);
1919 
1920     return CR_SUCCESS;
1921 }
1922 
1923 
1924 /***********************************************************************
1925  * CM_Dup_Range_List [SETUPAPI.@]
1926  */
1927 CONFIGRET
1928 WINAPI
CM_Dup_Range_List(_In_ RANGE_LIST rlhOld,_In_ RANGE_LIST rlhNew,_In_ ULONG ulFlags)1929 CM_Dup_Range_List(
1930     _In_ RANGE_LIST rlhOld,
1931     _In_ RANGE_LIST rlhNew,
1932     _In_ ULONG ulFlags)
1933 {
1934     PINTERNAL_RANGE_LIST pOldRangeList, pNewRangeList;
1935     PINTERNAL_RANGE pOldRange, pNewRange;
1936     PLIST_ENTRY ListEntry;
1937     CONFIGRET ret = CR_SUCCESS;
1938 
1939     FIXME("CM_Dup_Range_List(%p %p %lx)\n",
1940           rlhOld, rlhNew, ulFlags);
1941 
1942     pOldRangeList = (PINTERNAL_RANGE_LIST)rlhOld;
1943     pNewRangeList = (PINTERNAL_RANGE_LIST)rlhNew;
1944 
1945     if (!IsValidRangeList(pOldRangeList))
1946         return CR_INVALID_RANGE_LIST;
1947 
1948     if (!IsValidRangeList(pNewRangeList))
1949         return CR_INVALID_RANGE_LIST;
1950 
1951     if (ulFlags != 0)
1952         return CR_INVALID_FLAG;
1953 
1954     /* Lock the range lists */
1955     WaitForSingleObject(pOldRangeList->hMutex, INFINITE);
1956     WaitForSingleObject(pNewRangeList->hMutex, INFINITE);
1957 
1958     /* Delete the new range list, if ist is not empty */
1959     while (!IsListEmpty(&pNewRangeList->ListHead))
1960     {
1961         ListEntry = RemoveHeadList(&pNewRangeList->ListHead);
1962         pNewRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
1963         HeapFree(GetProcessHeap(), 0, pNewRange);
1964     }
1965 
1966     /* Copy the old range list into the new range list */
1967     ListEntry = &pOldRangeList->ListHead;
1968     while (ListEntry->Flink == &pOldRangeList->ListHead)
1969     {
1970         pOldRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
1971 
1972         pNewRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
1973         if (pNewRange == NULL)
1974         {
1975             ret = CR_OUT_OF_MEMORY;
1976             goto done;
1977         }
1978 
1979         pNewRange->pRangeList = pNewRangeList;
1980         pNewRange->ullStart = pOldRange->ullStart;
1981         pNewRange->ullEnd = pOldRange->ullEnd;
1982 
1983         InsertTailList(&pNewRangeList->ListHead, &pNewRange->ListEntry);
1984 
1985         ListEntry = ListEntry->Flink;
1986     }
1987 
1988 done:
1989     /* Unlock the range lists */
1990     ReleaseMutex(pNewRangeList->hMutex);
1991     ReleaseMutex(pOldRangeList->hMutex);
1992 
1993     return ret;
1994 }
1995 
1996 
1997 /***********************************************************************
1998  * CM_Enable_DevNode [SETUPAPI.@]
1999  */
2000 CONFIGRET
2001 WINAPI
CM_Enable_DevNode(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)2002 CM_Enable_DevNode(
2003     _In_ DEVINST dnDevInst,
2004     _In_ ULONG ulFlags)
2005 {
2006     TRACE("CM_Enable_DevNode(%p %lx)\n",
2007           dnDevInst, ulFlags);
2008 
2009     return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
2010 }
2011 
2012 
2013 /***********************************************************************
2014  * CM_Enable_DevNode_Ex [SETUPAPI.@]
2015  */
2016 CONFIGRET
2017 WINAPI
CM_Enable_DevNode_Ex(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2018 CM_Enable_DevNode_Ex(
2019     _In_ DEVINST dnDevInst,
2020     _In_ ULONG ulFlags,
2021     _In_opt_ HMACHINE hMachine)
2022 {
2023     RPC_BINDING_HANDLE BindingHandle = NULL;
2024     HSTRING_TABLE StringTable = NULL;
2025     LPWSTR lpDevInst;
2026     CONFIGRET ret;
2027 
2028     TRACE("CM_Enable_DevNode_Ex(%p %lx %p)\n",
2029           dnDevInst, ulFlags, hMachine);
2030 
2031     if (!pSetupIsUserAdmin())
2032         return CR_ACCESS_DENIED;
2033 
2034     if (dnDevInst == 0)
2035         return CR_INVALID_DEVINST;
2036 
2037     if (ulFlags != 0)
2038         return CR_INVALID_FLAG;
2039 
2040     if (hMachine != NULL)
2041     {
2042         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2043         if (BindingHandle == NULL)
2044             return CR_FAILURE;
2045 
2046         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2047         if (StringTable == 0)
2048             return CR_FAILURE;
2049     }
2050     else
2051     {
2052         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2053             return CR_FAILURE;
2054     }
2055 
2056     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2057     if (lpDevInst == NULL)
2058         return CR_INVALID_DEVNODE;
2059 
2060     RpcTryExcept
2061     {
2062         ret = PNP_DeviceInstanceAction(BindingHandle,
2063                                        PNP_DEVINST_ENABLE,
2064                                        ulFlags,
2065                                        lpDevInst,
2066                                        NULL);
2067     }
2068     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2069     {
2070         ret = RpcStatusToCmStatus(RpcExceptionCode());
2071     }
2072     RpcEndExcept;
2073 
2074     return ret;
2075 }
2076 
2077 
2078 /***********************************************************************
2079  * CM_Enumerate_Classes [SETUPAPI.@]
2080  */
2081 CONFIGRET
2082 WINAPI
CM_Enumerate_Classes(_In_ ULONG ulClassIndex,_Out_ LPGUID ClassGuid,_In_ ULONG ulFlags)2083 CM_Enumerate_Classes(
2084     _In_ ULONG ulClassIndex,
2085     _Out_ LPGUID ClassGuid,
2086     _In_ ULONG ulFlags)
2087 {
2088     TRACE("CM_Enumerate_Classes(%lx %p %lx)\n",
2089           ulClassIndex, ClassGuid, ulFlags);
2090 
2091     return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
2092 }
2093 
2094 
2095 /***********************************************************************
2096  * CM_Enumerate_Classes_Ex [SETUPAPI.@]
2097  */
2098 CONFIGRET
2099 WINAPI
CM_Enumerate_Classes_Ex(_In_ ULONG ulClassIndex,_Out_ LPGUID ClassGuid,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2100 CM_Enumerate_Classes_Ex(
2101     _In_ ULONG ulClassIndex,
2102     _Out_ LPGUID ClassGuid,
2103     _In_ ULONG ulFlags,
2104     _In_opt_ HMACHINE hMachine)
2105 {
2106     WCHAR szBuffer[MAX_GUID_STRING_LEN];
2107     RPC_BINDING_HANDLE BindingHandle = NULL;
2108     CONFIGRET ret = CR_SUCCESS;
2109     ULONG ulLength = MAX_GUID_STRING_LEN;
2110 
2111     TRACE("CM_Enumerate_Classes_Ex(%lx %p %lx %p)\n",
2112           ulClassIndex, ClassGuid, ulFlags, hMachine);
2113 
2114     if (ClassGuid == NULL)
2115         return CR_INVALID_POINTER;
2116 
2117     if (ulFlags != 0)
2118         return CR_INVALID_FLAG;
2119 
2120     if (hMachine != NULL)
2121     {
2122         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2123         if (BindingHandle == NULL)
2124             return CR_FAILURE;
2125     }
2126     else
2127     {
2128         if (!PnpGetLocalHandles(&BindingHandle, NULL))
2129             return CR_FAILURE;
2130     }
2131 
2132     RpcTryExcept
2133     {
2134         ret = PNP_EnumerateSubKeys(BindingHandle,
2135                                    PNP_CLASS_SUBKEYS,
2136                                    ulClassIndex,
2137                                    szBuffer,
2138                                    MAX_GUID_STRING_LEN,
2139                                    &ulLength,
2140                                    ulFlags);
2141     }
2142     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2143     {
2144         ret = RpcStatusToCmStatus(RpcExceptionCode());
2145     }
2146     RpcEndExcept;
2147 
2148     if (ret == CR_SUCCESS)
2149     {
2150         /* Remove the {} */
2151         szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
2152 
2153         /* Convert the buffer to a GUID */
2154         if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
2155             return CR_FAILURE;
2156     }
2157 
2158     return ret;
2159 }
2160 
2161 
2162 /***********************************************************************
2163  * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
2164  */
2165 CONFIGRET
2166 WINAPI
CM_Enumerate_EnumeratorsA(_In_ ULONG ulEnumIndex,_Out_writes_ (* pulLength)PCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)2167 CM_Enumerate_EnumeratorsA(
2168     _In_ ULONG ulEnumIndex,
2169     _Out_writes_(*pulLength) PCHAR Buffer,
2170     _Inout_ PULONG pulLength,
2171     _In_ ULONG ulFlags)
2172 {
2173     TRACE("CM_Enumerate_EnumeratorsA(%lu %p %p %lx)\n",
2174           ulEnumIndex, Buffer, pulLength, ulFlags);
2175 
2176     return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
2177                                         ulFlags, NULL);
2178 }
2179 
2180 
2181 /***********************************************************************
2182  * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
2183  */
2184 CONFIGRET
2185 WINAPI
CM_Enumerate_EnumeratorsW(_In_ ULONG ulEnumIndex,_Out_writes_ (* pulLength)PWCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)2186 CM_Enumerate_EnumeratorsW(
2187     _In_ ULONG ulEnumIndex,
2188     _Out_writes_(*pulLength) PWCHAR Buffer,
2189     _Inout_ PULONG pulLength,
2190     _In_ ULONG ulFlags)
2191 {
2192     TRACE("CM_Enumerate_EnumeratorsW(%lu %p %p %lx)\n",
2193           ulEnumIndex, Buffer, pulLength, ulFlags);
2194 
2195     return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
2196                                         ulFlags, NULL);
2197 }
2198 
2199 
2200 /***********************************************************************
2201  * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
2202  */
2203 CONFIGRET
2204 WINAPI
CM_Enumerate_Enumerators_ExA(_In_ ULONG ulEnumIndex,_Out_writes_ (* pulLength)PCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2205 CM_Enumerate_Enumerators_ExA(
2206     _In_ ULONG ulEnumIndex,
2207     _Out_writes_(*pulLength) PCHAR Buffer,
2208     _Inout_ PULONG pulLength,
2209     _In_ ULONG ulFlags,
2210     _In_opt_ HMACHINE hMachine)
2211 {
2212     WCHAR szBuffer[MAX_DEVICE_ID_LEN];
2213     ULONG ulOrigLength;
2214     ULONG ulLength;
2215     CONFIGRET ret = CR_SUCCESS;
2216 
2217     TRACE("CM_Enumerate_Enumerators_ExA(%lu %p %p %lx %p)\n",
2218           ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2219 
2220     if (Buffer == NULL || pulLength == NULL)
2221         return CR_INVALID_POINTER;
2222 
2223     if (ulFlags != 0)
2224         return CR_INVALID_FLAG;
2225 
2226     ulOrigLength = *pulLength;
2227     *pulLength = 0;
2228 
2229     ulLength = MAX_DEVICE_ID_LEN;
2230     ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
2231                                        ulFlags, hMachine);
2232     if (ret == CR_SUCCESS)
2233     {
2234         if (WideCharToMultiByte(CP_ACP,
2235                                 0,
2236                                 szBuffer,
2237                                 ulLength,
2238                                 Buffer,
2239                                 ulOrigLength,
2240                                 NULL,
2241                                 NULL) == 0)
2242             ret = CR_FAILURE;
2243         else
2244             *pulLength = lstrlenA(Buffer) + 1;
2245     }
2246 
2247     return ret;
2248 }
2249 
2250 
2251 /***********************************************************************
2252  * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
2253  */
2254 CONFIGRET
2255 WINAPI
CM_Enumerate_Enumerators_ExW(_In_ ULONG ulEnumIndex,_Out_writes_ (* pulLength)PWCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2256 CM_Enumerate_Enumerators_ExW(
2257     _In_ ULONG ulEnumIndex,
2258     _Out_writes_(*pulLength) PWCHAR Buffer,
2259     _Inout_ PULONG pulLength,
2260     _In_ ULONG ulFlags,
2261     _In_opt_ HMACHINE hMachine)
2262 {
2263     RPC_BINDING_HANDLE BindingHandle = NULL;
2264     CONFIGRET ret;
2265 
2266     TRACE("CM_Enumerate_Enumerators_ExW(%lu %p %p %lx %p)\n",
2267           ulEnumIndex, Buffer, pulLength, ulFlags, hMachine);
2268 
2269     if (Buffer == NULL || pulLength == NULL)
2270         return CR_INVALID_POINTER;
2271 
2272     if (ulFlags != 0)
2273         return CR_INVALID_FLAG;
2274 
2275     *Buffer = UNICODE_NULL;
2276 
2277     if (hMachine != NULL)
2278     {
2279         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2280         if (BindingHandle == NULL)
2281             return CR_FAILURE;
2282     }
2283     else
2284     {
2285         if (!PnpGetLocalHandles(&BindingHandle, NULL))
2286             return CR_FAILURE;
2287     }
2288 
2289     RpcTryExcept
2290     {
2291         ret = PNP_EnumerateSubKeys(BindingHandle,
2292                                    PNP_ENUMERATOR_SUBKEYS,
2293                                    ulEnumIndex,
2294                                    Buffer,
2295                                    *pulLength,
2296                                    pulLength,
2297                                    ulFlags);
2298     }
2299     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2300     {
2301         ret = RpcStatusToCmStatus(RpcExceptionCode());
2302     }
2303     RpcEndExcept;
2304 
2305     return ret;
2306 }
2307 
2308 
2309 /***********************************************************************
2310  * CM_Find_Range [SETUPAPI.@]
2311  */
2312 CONFIGRET
2313 WINAPI
CM_Find_Range(_Out_ PDWORDLONG pullStart,_In_ DWORDLONG ullStart,_In_ ULONG ulLength,_In_ DWORDLONG ullAlignment,_In_ DWORDLONG ullEnd,_In_ RANGE_LIST rlh,_In_ ULONG ulFlags)2314 CM_Find_Range(
2315     _Out_ PDWORDLONG pullStart,
2316     _In_ DWORDLONG ullStart,
2317     _In_ ULONG ulLength,
2318     _In_ DWORDLONG ullAlignment,
2319     _In_ DWORDLONG ullEnd,
2320     _In_ RANGE_LIST rlh,
2321     _In_ ULONG ulFlags)
2322 {
2323     FIXME("CM_Find_Range(%p %I64u %lu %I64u %I64u %p %lx)\n",
2324           pullStart, ullStart, ulLength, ullAlignment, ullEnd, rlh, ulFlags);
2325 
2326     return CR_CALL_NOT_IMPLEMENTED;
2327 }
2328 
2329 
2330 /***********************************************************************
2331  * CM_First_Range [SETUPAPI.@]
2332  */
2333 CONFIGRET
2334 WINAPI
CM_First_Range(_In_ RANGE_LIST rlh,_Out_ PDWORDLONG pullStart,_Out_ PDWORDLONG pullEnd,_Out_ PRANGE_ELEMENT preElement,_In_ ULONG ulFlags)2335 CM_First_Range(
2336     _In_ RANGE_LIST rlh,
2337     _Out_ PDWORDLONG pullStart,
2338     _Out_ PDWORDLONG pullEnd,
2339     _Out_ PRANGE_ELEMENT preElement,
2340     _In_ ULONG ulFlags)
2341 {
2342     PINTERNAL_RANGE_LIST pRangeList;
2343     PINTERNAL_RANGE pRange;
2344     PLIST_ENTRY ListEntry;
2345     CONFIGRET ret = CR_SUCCESS;
2346 
2347     FIXME("CM_First_Range(%p %p %p %p %lx)\n",
2348           rlh, pullStart, pullEnd, preElement, ulFlags);
2349 
2350     pRangeList = (PINTERNAL_RANGE_LIST)rlh;
2351 
2352     if (!IsValidRangeList(pRangeList))
2353         return CR_INVALID_RANGE_LIST;
2354 
2355     if (pullStart == NULL || pullEnd == NULL || preElement == NULL)
2356         return CR_INVALID_POINTER;
2357 
2358     if (ulFlags != 0)
2359         return CR_INVALID_FLAG;
2360 
2361     /* Lock the range list */
2362     WaitForSingleObject(pRangeList->hMutex, INFINITE);
2363 
2364     /* Fail, if the list is empty */
2365     if (IsListEmpty(&pRangeList->ListHead))
2366     {
2367         ret = CR_FAILURE;
2368         goto done;
2369     }
2370 
2371     /* Get the first range */
2372     ListEntry = pRangeList->ListHead.Flink;
2373     pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2374 
2375     /* Return the range data */
2376     *pullStart = pRange->ullStart;
2377     *pullEnd = pRange->ullEnd;
2378     *preElement = (RANGE_ELEMENT)pRange;
2379 
2380 done:
2381     /* Unlock the range list */
2382     ReleaseMutex(pRangeList->hMutex);
2383 
2384     return ret;
2385 }
2386 
2387 
2388 /***********************************************************************
2389  * CM_Free_Log_Conf [SETUPAPI.@]
2390  */
2391 CONFIGRET
2392 WINAPI
CM_Free_Log_Conf(_In_ LOG_CONF lcLogConfToBeFreed,_In_ ULONG ulFlags)2393 CM_Free_Log_Conf(
2394     _In_ LOG_CONF lcLogConfToBeFreed,
2395     _In_ ULONG ulFlags)
2396 {
2397     TRACE("CM_Free_Log_Conf(%lx %lx)\n",
2398           lcLogConfToBeFreed, ulFlags);
2399 
2400     return CM_Free_Log_Conf_Ex(lcLogConfToBeFreed, ulFlags, NULL);
2401 }
2402 
2403 
2404 /***********************************************************************
2405  * CM_Free_Log_Conf_Ex [SETUPAPI.@]
2406  */
2407 CONFIGRET
2408 WINAPI
CM_Free_Log_Conf_Ex(_In_ LOG_CONF lcLogConfToBeFreed,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2409 CM_Free_Log_Conf_Ex(
2410     _In_ LOG_CONF lcLogConfToBeFreed,
2411     _In_ ULONG ulFlags,
2412     _In_opt_ HMACHINE hMachine)
2413 {
2414     RPC_BINDING_HANDLE BindingHandle = NULL;
2415     HSTRING_TABLE StringTable = NULL;
2416     LPWSTR lpDevInst;
2417     PLOG_CONF_INFO pLogConfInfo;
2418     CONFIGRET ret;
2419 
2420     TRACE("CM_Free_Log_Conf_Ex(%lx %lx %p)\n",
2421           lcLogConfToBeFreed, ulFlags, hMachine);
2422 
2423     if (!pSetupIsUserAdmin())
2424         return CR_ACCESS_DENIED;
2425 
2426     pLogConfInfo = (PLOG_CONF_INFO)lcLogConfToBeFreed;
2427     if (!IsValidLogConf(pLogConfInfo))
2428         return CR_INVALID_LOG_CONF;
2429 
2430     if (ulFlags != 0)
2431         return CR_INVALID_FLAG;
2432 
2433     if (hMachine != NULL)
2434     {
2435         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2436         if (BindingHandle == NULL)
2437             return CR_FAILURE;
2438 
2439         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2440         if (StringTable == 0)
2441             return CR_FAILURE;
2442     }
2443     else
2444     {
2445         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2446             return CR_FAILURE;
2447     }
2448 
2449     lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
2450     if (lpDevInst == NULL)
2451         return CR_INVALID_DEVNODE;
2452 
2453     RpcTryExcept
2454     {
2455         ret = PNP_FreeLogConf(BindingHandle,
2456                               lpDevInst,
2457                               pLogConfInfo->ulType,
2458                               pLogConfInfo->ulTag,
2459                               0);
2460     }
2461     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2462     {
2463         ret = RpcStatusToCmStatus(RpcExceptionCode());
2464     }
2465     RpcEndExcept;
2466 
2467     return ret;
2468 }
2469 
2470 
2471 /***********************************************************************
2472  * CM_Free_Log_Conf_Handle [SETUPAPI.@]
2473  */
2474 CONFIGRET
2475 WINAPI
CM_Free_Log_Conf_Handle(_In_ LOG_CONF lcLogConf)2476 CM_Free_Log_Conf_Handle(
2477     _In_ LOG_CONF lcLogConf)
2478 {
2479     PLOG_CONF_INFO pLogConfInfo;
2480 
2481     TRACE("CM_Free_Log_Conf_Handle(%lx)\n", lcLogConf);
2482 
2483     pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
2484     if (!IsValidLogConf(pLogConfInfo))
2485         return CR_INVALID_LOG_CONF;
2486 
2487     HeapFree(GetProcessHeap(), 0, pLogConfInfo);
2488 
2489     return CR_SUCCESS;
2490 }
2491 
2492 
2493 /***********************************************************************
2494  * CM_Free_Range_List [SETUPAPI.@]
2495  */
2496 CONFIGRET
2497 WINAPI
CM_Free_Range_List(_In_ RANGE_LIST RangeList,_In_ ULONG ulFlags)2498 CM_Free_Range_List(
2499     _In_ RANGE_LIST RangeList,
2500     _In_ ULONG ulFlags)
2501 {
2502     PINTERNAL_RANGE_LIST pRangeList;
2503     PINTERNAL_RANGE pRange;
2504     PLIST_ENTRY ListEntry;
2505 
2506     FIXME("CM_Free_Range_List(%p %lx)\n",
2507           RangeList, ulFlags);
2508 
2509     pRangeList = (PINTERNAL_RANGE_LIST)RangeList;
2510 
2511     if (!IsValidRangeList(pRangeList))
2512         return CR_INVALID_RANGE_LIST;
2513 
2514     if (ulFlags != 0)
2515         return CR_INVALID_FLAG;
2516 
2517     /* Lock the range list */
2518     WaitForSingleObject(pRangeList->hMutex, INFINITE);
2519 
2520     /* Free the list of ranges */
2521     while (!IsListEmpty(&pRangeList->ListHead))
2522     {
2523         ListEntry = RemoveHeadList(&pRangeList->ListHead);
2524         pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
2525         HeapFree(GetProcessHeap(), 0, pRange);
2526     }
2527 
2528     /* Unlock the range list */
2529     ReleaseMutex(pRangeList->hMutex);
2530 
2531     /* Close the mutex */
2532     CloseHandle(pRangeList->hMutex);
2533 
2534     /* Free the range list */
2535     HeapFree(GetProcessHeap(), 0, pRangeList);
2536 
2537     return CR_SUCCESS;
2538 }
2539 
2540 
2541 /***********************************************************************
2542  * CM_Free_Res_Des [SETUPAPI.@]
2543  */
2544 CONFIGRET
2545 WINAPI
CM_Free_Res_Des(_Out_ PRES_DES prdResDes,_In_ RES_DES rdResDes,_In_ ULONG ulFlags)2546 CM_Free_Res_Des(
2547     _Out_ PRES_DES prdResDes,
2548     _In_ RES_DES rdResDes,
2549     _In_ ULONG ulFlags)
2550 {
2551     TRACE("CM_Free_Res_Des(%p %p %lx)\n",
2552           prdResDes, rdResDes, ulFlags);
2553 
2554     return CM_Free_Res_Des_Ex(prdResDes, rdResDes, ulFlags, NULL);
2555 }
2556 
2557 
2558 /***********************************************************************
2559  * CM_Free_Res_Des_Ex [SETUPAPI.@]
2560  */
2561 CONFIGRET
2562 WINAPI
CM_Free_Res_Des_Ex(_Out_ PRES_DES prdResDes,_In_ RES_DES rdResDes,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2563 CM_Free_Res_Des_Ex(
2564     _Out_ PRES_DES prdResDes,
2565     _In_ RES_DES rdResDes,
2566     _In_ ULONG ulFlags,
2567     _In_opt_ HMACHINE hMachine)
2568 {
2569     FIXME("CM_Free_Res_Des_Ex(%p %p %lx %p)\n",
2570           prdResDes, rdResDes, ulFlags, hMachine);
2571 
2572     return CR_CALL_NOT_IMPLEMENTED;
2573 }
2574 
2575 
2576 /***********************************************************************
2577  * CM_Free_Res_Des_Handle [SETUPAPI.@]
2578  */
2579 CONFIGRET
2580 WINAPI
CM_Free_Res_Des_Handle(_In_ RES_DES rdResDes)2581 CM_Free_Res_Des_Handle(
2582     _In_ RES_DES rdResDes)
2583 {
2584     PRES_DES_INFO pResDesInfo;
2585 
2586     FIXME("CM_Free_Res_Des_Handle(%p)\n", rdResDes);
2587 
2588     pResDesInfo = (PRES_DES_INFO)rdResDes;
2589     if (!IsValidResDes(pResDesInfo))
2590         return CR_INVALID_RES_DES;
2591 
2592     HeapFree(GetProcessHeap(), 0, pResDesInfo);
2593 
2594     return CR_SUCCESS;
2595 }
2596 
2597 
2598 /***********************************************************************
2599  * CM_Free_Resource_Conflict_Handle [SETUPAPI.@]
2600  */
2601 CONFIGRET
2602 WINAPI
CM_Free_Resource_Conflict_Handle(_In_ CONFLICT_LIST clConflictList)2603 CM_Free_Resource_Conflict_Handle(
2604     _In_ CONFLICT_LIST clConflictList)
2605 {
2606     PCONFLICT_DATA pConflictData;
2607 
2608     FIXME("CM_Free_Resource_Conflict_Handle(%p)\n",
2609           clConflictList);
2610 
2611     pConflictData = (PCONFLICT_DATA)clConflictList;
2612     if (!IsValidConflictData(pConflictData))
2613         return CR_INVALID_CONFLICT_LIST;
2614 
2615     if (pConflictData->pConflictList != NULL)
2616         MyFree(pConflictData->pConflictList);
2617 
2618     MyFree(pConflictData);
2619 
2620     return CR_SUCCESS;
2621 }
2622 
2623 
2624 /***********************************************************************
2625  * CM_Get_Child [SETUPAPI.@]
2626  */
2627 CONFIGRET
2628 WINAPI
CM_Get_Child(_Out_ PDEVINST pdnDevInst,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)2629 CM_Get_Child(
2630     _Out_ PDEVINST pdnDevInst,
2631     _In_ DEVINST dnDevInst,
2632     _In_ ULONG ulFlags)
2633 {
2634     TRACE("CM_Get_Child(%p %p %lx)\n",
2635           pdnDevInst, dnDevInst, ulFlags);
2636 
2637     return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
2638 }
2639 
2640 
2641 /***********************************************************************
2642  * CM_Get_Child_Ex [SETUPAPI.@]
2643  */
2644 CONFIGRET
2645 WINAPI
CM_Get_Child_Ex(_Out_ PDEVINST pdnDevInst,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2646 CM_Get_Child_Ex(
2647     _Out_ PDEVINST pdnDevInst,
2648     _In_ DEVINST dnDevInst,
2649     _In_ ULONG ulFlags,
2650     _In_opt_ HMACHINE hMachine)
2651 {
2652     WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
2653     RPC_BINDING_HANDLE BindingHandle = NULL;
2654     HSTRING_TABLE StringTable = NULL;
2655     LPWSTR lpDevInst;
2656     DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
2657     CONFIGRET ret;
2658 
2659     TRACE("CM_Get_Child_Ex(%p %lx %lx %p)\n",
2660           pdnDevInst, dnDevInst, ulFlags, hMachine);
2661 
2662     if (pdnDevInst == NULL)
2663         return CR_INVALID_POINTER;
2664 
2665     if (dnDevInst == 0)
2666         return CR_INVALID_DEVINST;
2667 
2668     if (ulFlags != 0)
2669         return CR_INVALID_FLAG;
2670 
2671     *pdnDevInst = -1;
2672 
2673     if (hMachine != NULL)
2674     {
2675         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2676         if (BindingHandle == NULL)
2677             return CR_FAILURE;
2678 
2679         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2680         if (StringTable == 0)
2681             return CR_FAILURE;
2682     }
2683     else
2684     {
2685         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2686             return CR_FAILURE;
2687     }
2688 
2689     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
2690     if (lpDevInst == NULL)
2691         return CR_INVALID_DEVNODE;
2692 
2693     RpcTryExcept
2694     {
2695         ret = PNP_GetRelatedDeviceInstance(BindingHandle,
2696                                            PNP_GET_CHILD_DEVICE_INSTANCE,
2697                                            lpDevInst,
2698                                            szRelatedDevInst,
2699                                            &dwLength,
2700                                            0);
2701     }
2702     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2703     {
2704         ret = RpcStatusToCmStatus(RpcExceptionCode());
2705     }
2706     RpcEndExcept;
2707 
2708     if (ret != CR_SUCCESS)
2709         return ret;
2710 
2711     TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
2712 
2713     dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
2714     if (dwIndex == -1)
2715         return CR_FAILURE;
2716 
2717     *pdnDevInst = dwIndex;
2718 
2719     return CR_SUCCESS;
2720 }
2721 
2722 
2723 /***********************************************************************
2724  * CM_Get_Class_Key_NameA [SETUPAPI.@]
2725  */
2726 CONFIGRET
2727 WINAPI
CM_Get_Class_Key_NameA(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)LPSTR pszKeyName,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)2728 CM_Get_Class_Key_NameA(
2729     _In_ LPGUID ClassGuid,
2730     _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2731     _Inout_ PULONG pulLength,
2732     _In_ ULONG ulFlags)
2733 {
2734     TRACE("CM_Get_Class_Key_NameA(%p %p %p %lx)\n",
2735           ClassGuid, pszKeyName, pulLength, ulFlags);
2736 
2737     return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
2738                                      ulFlags, NULL);
2739 }
2740 
2741 
2742 /***********************************************************************
2743  * CM_Get_Class_Key_NameW [SETUPAPI.@]
2744  */
2745 CONFIGRET
2746 WINAPI
CM_Get_Class_Key_NameW(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)LPWSTR pszKeyName,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)2747 CM_Get_Class_Key_NameW(
2748     _In_ LPGUID ClassGuid,
2749     _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2750     _Inout_ PULONG pulLength,
2751     _In_ ULONG ulFlags)
2752 {
2753     TRACE("CM_Get_Class_Key_NameW(%p %p %p %lx)\n",
2754           ClassGuid, pszKeyName, pulLength, ulFlags);
2755 
2756     return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
2757                                      ulFlags, NULL);
2758 }
2759 
2760 
2761 /***********************************************************************
2762  * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
2763  */
2764 CONFIGRET
2765 WINAPI
CM_Get_Class_Key_Name_ExA(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)LPSTR pszKeyName,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2766 CM_Get_Class_Key_Name_ExA(
2767     _In_ LPGUID ClassGuid,
2768     _Out_writes_opt_(*pulLength) LPSTR pszKeyName,
2769     _Inout_ PULONG pulLength,
2770     _In_ ULONG ulFlags,
2771     _In_opt_ HMACHINE hMachine)
2772 {
2773     WCHAR szBuffer[MAX_GUID_STRING_LEN];
2774     CONFIGRET ret = CR_SUCCESS;
2775     ULONG ulLength;
2776     ULONG ulOrigLength;
2777 
2778     TRACE("CM_Get_Class_Key_Name_ExA(%p %p %p %lx %p)\n",
2779           ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2780 
2781     if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2782         return CR_INVALID_POINTER;
2783 
2784     ulOrigLength = *pulLength;
2785     *pulLength = 0;
2786 
2787     ulLength = MAX_GUID_STRING_LEN;
2788     ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
2789                                     ulFlags, hMachine);
2790     if (ret == CR_SUCCESS)
2791     {
2792         if (WideCharToMultiByte(CP_ACP,
2793                                 0,
2794                                 szBuffer,
2795                                 ulLength,
2796                                 pszKeyName,
2797                                 ulOrigLength,
2798                                 NULL,
2799                                 NULL) == 0)
2800             ret = CR_FAILURE;
2801         else
2802             *pulLength = lstrlenA(pszKeyName) + 1;
2803     }
2804 
2805     return CR_SUCCESS;
2806 }
2807 
2808 
2809 /***********************************************************************
2810  * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
2811  */
2812 CONFIGRET
2813 WINAPI
CM_Get_Class_Key_Name_ExW(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)LPWSTR pszKeyName,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2814 CM_Get_Class_Key_Name_ExW(
2815     _In_ LPGUID ClassGuid,
2816     _Out_writes_opt_(*pulLength) LPWSTR pszKeyName,
2817     _Inout_ PULONG pulLength,
2818     _In_ ULONG ulFlags,
2819     _In_opt_ HMACHINE hMachine)
2820 {
2821     TRACE("CM_Get_Class_Key_Name_ExW(%p %p %p %lx %p)\n",
2822           ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
2823 
2824     if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
2825         return CR_INVALID_POINTER;
2826 
2827     if (ulFlags != 0)
2828         return CR_INVALID_FLAG;
2829 
2830     if (*pulLength < MAX_GUID_STRING_LEN)
2831     {
2832         *pulLength = 0;
2833         return CR_BUFFER_SMALL;
2834     }
2835 
2836     if (!GuidToString(ClassGuid, pszKeyName))
2837         return CR_INVALID_DATA;
2838 
2839     *pulLength = MAX_GUID_STRING_LEN;
2840 
2841     return CR_SUCCESS;
2842 }
2843 
2844 
2845 /***********************************************************************
2846  * CM_Get_Class_NameA [SETUPAPI.@]
2847  */
2848 CONFIGRET
2849 WINAPI
CM_Get_Class_NameA(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)PCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)2850 CM_Get_Class_NameA(
2851     _In_ LPGUID ClassGuid,
2852     _Out_writes_opt_(*pulLength) PCHAR Buffer,
2853     _Inout_ PULONG pulLength,
2854     _In_ ULONG ulFlags)
2855 {
2856     TRACE("CM_Get_Class_NameA(%p %p %p %lx)\n",
2857           ClassGuid, Buffer, pulLength, ulFlags);
2858 
2859     return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
2860                                  NULL);
2861 }
2862 
2863 
2864 /***********************************************************************
2865  * CM_Get_Class_NameW [SETUPAPI.@]
2866  */
2867 CONFIGRET
2868 WINAPI
CM_Get_Class_NameW(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)PWCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)2869 CM_Get_Class_NameW(
2870     _In_ LPGUID ClassGuid,
2871     _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2872     _Inout_ PULONG pulLength,
2873     _In_ ULONG ulFlags)
2874 {
2875     TRACE("CM_Get_Class_NameW(%p %p %p %lx)\n",
2876           ClassGuid, Buffer, pulLength, ulFlags);
2877 
2878     return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
2879                                  NULL);
2880 }
2881 
2882 
2883 /***********************************************************************
2884  * CM_Get_Class_Name_ExA [SETUPAPI.@]
2885  */
2886 CONFIGRET
2887 WINAPI
CM_Get_Class_Name_ExA(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)PCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2888 CM_Get_Class_Name_ExA(
2889     _In_ LPGUID ClassGuid,
2890     _Out_writes_opt_(*pulLength) PCHAR Buffer,
2891     _Inout_ PULONG pulLength,
2892     _In_ ULONG ulFlags,
2893     _In_opt_ HMACHINE hMachine)
2894 {
2895     WCHAR szBuffer[MAX_CLASS_NAME_LEN];
2896     CONFIGRET ret = CR_SUCCESS;
2897     ULONG ulLength;
2898     ULONG ulOrigLength;
2899 
2900     TRACE("CM_Get_Class_Name_ExA(%p %p %p %lx %p)\n",
2901           ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2902 
2903     if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2904         return CR_INVALID_POINTER;
2905 
2906     ulOrigLength = *pulLength;
2907     *pulLength = 0;
2908 
2909     ulLength = MAX_CLASS_NAME_LEN;
2910     ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
2911                                 ulFlags, hMachine);
2912     if (ret == CR_SUCCESS)
2913     {
2914         if (WideCharToMultiByte(CP_ACP,
2915                                 0,
2916                                 szBuffer,
2917                                 ulLength,
2918                                 Buffer,
2919                                 ulOrigLength,
2920                                 NULL,
2921                                 NULL) == 0)
2922             ret = CR_FAILURE;
2923         else
2924             *pulLength = lstrlenA(Buffer) + 1;
2925     }
2926 
2927     return ret;
2928 }
2929 
2930 
2931 /***********************************************************************
2932  * CM_Get_Class_Name_ExW [SETUPAPI.@]
2933  */
2934 CONFIGRET
2935 WINAPI
CM_Get_Class_Name_ExW(_In_ LPGUID ClassGuid,_Out_writes_opt_ (* pulLength)PWCHAR Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)2936 CM_Get_Class_Name_ExW(
2937     _In_ LPGUID ClassGuid,
2938     _Out_writes_opt_(*pulLength) PWCHAR Buffer,
2939     _Inout_ PULONG pulLength,
2940     _In_ ULONG ulFlags,
2941     _In_opt_ HMACHINE hMachine)
2942 {
2943     WCHAR szGuidString[MAX_GUID_STRING_LEN];
2944     RPC_BINDING_HANDLE BindingHandle = NULL;
2945     CONFIGRET ret;
2946 
2947     TRACE("CM_Get_Class_Name_ExW(%p %p %p %lx %p\n",
2948           ClassGuid, Buffer, pulLength, ulFlags, hMachine);
2949 
2950     if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
2951         return CR_INVALID_POINTER;
2952 
2953     if (ulFlags != 0)
2954         return CR_INVALID_FLAG;
2955 
2956     if (!GuidToString(ClassGuid, szGuidString))
2957         return CR_INVALID_DATA;
2958 
2959     TRACE("Guid %s\n", debugstr_w(szGuidString));
2960 
2961     if (hMachine != NULL)
2962     {
2963         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2964         if (BindingHandle == NULL)
2965             return CR_FAILURE;
2966     }
2967     else
2968     {
2969         if (!PnpGetLocalHandles(&BindingHandle, NULL))
2970             return CR_FAILURE;
2971     }
2972 
2973     RpcTryExcept
2974     {
2975         ret = PNP_GetClassName(BindingHandle,
2976                                szGuidString,
2977                                Buffer,
2978                                pulLength,
2979                                ulFlags);
2980     }
2981     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2982     {
2983         ret = RpcStatusToCmStatus(RpcExceptionCode());
2984     }
2985     RpcEndExcept;
2986 
2987     return ret;
2988 }
2989 
2990 
2991 /***********************************************************************
2992  * CM_Get_Class_Registry_PropertyA [SETUPAPI.@]
2993  */
2994 CONFIGRET
2995 WINAPI
CM_Get_Class_Registry_PropertyA(LPGUID ClassGuid,ULONG ulProperty,PULONG pulRegDataType,PVOID Buffer,PULONG pulLength,ULONG ulFlags,HMACHINE hMachine)2996 CM_Get_Class_Registry_PropertyA(
2997     LPGUID ClassGuid,
2998     ULONG ulProperty,
2999     PULONG pulRegDataType,
3000     PVOID Buffer,
3001     PULONG pulLength,
3002     ULONG ulFlags,
3003     HMACHINE hMachine)
3004 {
3005     PWSTR BufferW;
3006     ULONG ulLength = 0;
3007     ULONG ulType;
3008     CONFIGRET ret;
3009 
3010     TRACE("CM_Get_Class_Registry_PropertyA(%p %lu %p %p %p %lx %p)\n",
3011           ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
3012           ulFlags, hMachine);
3013 
3014     if (pulLength == NULL)
3015         return CR_INVALID_POINTER;
3016 
3017     if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
3018         return CR_INVALID_PROPERTY;
3019 
3020     ulType = GetRegistryPropertyType(ulProperty);
3021     if (ulType == REG_SZ || ulType == REG_MULTI_SZ)
3022     {
3023         /* Get the required buffer size */
3024         ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
3025                                               NULL, &ulLength, ulFlags, hMachine);
3026         if (ret != CR_BUFFER_SMALL)
3027             return ret;
3028 
3029         /* Allocate the unicode buffer */
3030         BufferW = HeapAlloc(GetProcessHeap(), 0, ulLength);
3031         if (BufferW == NULL)
3032             return CR_OUT_OF_MEMORY;
3033 
3034         /* Get the property */
3035         ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
3036                                               BufferW, &ulLength, ulFlags, hMachine);
3037         if (ret != CR_SUCCESS)
3038         {
3039             HeapFree(GetProcessHeap(), 0, BufferW);
3040             return ret;
3041         }
3042 
3043         /* Do W->A conversion */
3044         *pulLength = WideCharToMultiByte(CP_ACP,
3045                                          0,
3046                                          BufferW,
3047                                          ulLength,
3048                                          Buffer,
3049                                          *pulLength,
3050                                          NULL,
3051                                          NULL);
3052 
3053         /* Release the unicode buffer */
3054         HeapFree(GetProcessHeap(), 0, BufferW);
3055 
3056         if (*pulLength == 0)
3057             ret = CR_FAILURE;
3058     }
3059     else
3060     {
3061         /* Get the property */
3062         ret = CM_Get_Class_Registry_PropertyW(ClassGuid, ulProperty, pulRegDataType,
3063                                               Buffer, pulLength, ulFlags, hMachine);
3064     }
3065 
3066     return ret;
3067 }
3068 
3069 
3070 /***********************************************************************
3071  * CM_Get_Class_Registry_PropertyW [SETUPAPI.@]
3072  */
3073 CONFIGRET
3074 WINAPI
CM_Get_Class_Registry_PropertyW(LPGUID ClassGuid,ULONG ulProperty,PULONG pulRegDataType,PVOID Buffer,PULONG pulLength,ULONG ulFlags,HMACHINE hMachine)3075 CM_Get_Class_Registry_PropertyW(
3076     LPGUID ClassGuid,
3077     ULONG ulProperty,
3078     PULONG pulRegDataType,
3079     PVOID Buffer,
3080     PULONG pulLength,
3081     ULONG ulFlags,
3082     HMACHINE hMachine)
3083 {
3084     RPC_BINDING_HANDLE BindingHandle = NULL;
3085     WCHAR szGuidString[PNP_MAX_GUID_STRING_LEN + 1];
3086     ULONG ulType = 0;
3087     ULONG ulTransferLength = 0;
3088     CONFIGRET ret;
3089 
3090     TRACE("CM_Get_Class_Registry_PropertyW(%p %lu %p %p %p %lx %p)\n",
3091           ClassGuid, ulProperty, pulRegDataType, Buffer, pulLength,
3092           ulFlags, hMachine);
3093 
3094     if (ClassGuid == NULL || pulLength == NULL)
3095         return CR_INVALID_POINTER;
3096 
3097     if (ulFlags != 0)
3098         return CR_INVALID_FLAG;
3099 
3100     if (pSetupStringFromGuid(ClassGuid,
3101                              szGuidString,
3102                              PNP_MAX_GUID_STRING_LEN) != 0)
3103         return CR_INVALID_DATA;
3104 
3105     if (ulProperty < CM_CRP_MIN || ulProperty > CM_CRP_MAX)
3106         return CR_INVALID_PROPERTY;
3107 
3108     if (hMachine != NULL)
3109     {
3110         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3111         if (BindingHandle == NULL)
3112             return CR_FAILURE;
3113     }
3114     else
3115     {
3116         if (!PnpGetLocalHandles(&BindingHandle, NULL))
3117             return CR_FAILURE;
3118     }
3119 
3120     ulTransferLength = *pulLength;
3121 
3122     RpcTryExcept
3123     {
3124         ret = PNP_GetClassRegProp(BindingHandle,
3125                                   szGuidString,
3126                                   ulProperty,
3127                                   &ulType,
3128                                   Buffer,
3129                                   &ulTransferLength,
3130                                   pulLength,
3131                                   ulFlags);
3132     }
3133     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3134     {
3135         ret = RpcStatusToCmStatus(RpcExceptionCode());
3136     }
3137     RpcEndExcept;
3138 
3139     if (ret == CR_SUCCESS)
3140     {
3141         if (pulRegDataType != NULL)
3142             *pulRegDataType = ulType;
3143     }
3144 
3145     return ret;
3146 }
3147 
3148 
3149 /***********************************************************************
3150  * CM_Get_Depth [SETUPAPI.@]
3151  */
3152 CONFIGRET
3153 WINAPI
CM_Get_Depth(_Out_ PULONG pulDepth,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)3154 CM_Get_Depth(
3155     _Out_ PULONG pulDepth,
3156     _In_ DEVINST dnDevInst,
3157     _In_ ULONG ulFlags)
3158 {
3159     TRACE("CM_Get_Depth(%p %lx %lx)\n",
3160           pulDepth, dnDevInst, ulFlags);
3161 
3162     return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
3163 }
3164 
3165 
3166 /***********************************************************************
3167  * CM_Get_Depth_Ex [SETUPAPI.@]
3168  */
3169 CONFIGRET
3170 WINAPI
CM_Get_Depth_Ex(_Out_ PULONG pulDepth,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3171 CM_Get_Depth_Ex(
3172     _Out_ PULONG pulDepth,
3173     _In_ DEVINST dnDevInst,
3174     _In_ ULONG ulFlags,
3175     _In_opt_ HMACHINE hMachine)
3176 {
3177     RPC_BINDING_HANDLE BindingHandle = NULL;
3178     HSTRING_TABLE StringTable = NULL;
3179     LPWSTR lpDevInst;
3180     CONFIGRET ret;
3181 
3182     TRACE("CM_Get_Depth_Ex(%p %lx %lx %p)\n",
3183           pulDepth, dnDevInst, ulFlags, hMachine);
3184 
3185     if (pulDepth == NULL)
3186         return CR_INVALID_POINTER;
3187 
3188     if (dnDevInst == 0)
3189         return CR_INVALID_DEVINST;
3190 
3191     if (ulFlags != 0)
3192         return CR_INVALID_FLAG;
3193 
3194     if (hMachine != NULL)
3195     {
3196         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3197         if (BindingHandle == NULL)
3198             return CR_FAILURE;
3199 
3200         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3201         if (StringTable == 0)
3202             return CR_FAILURE;
3203     }
3204     else
3205     {
3206         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3207             return CR_FAILURE;
3208     }
3209 
3210     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3211     if (lpDevInst == NULL)
3212         return CR_INVALID_DEVNODE;
3213 
3214     RpcTryExcept
3215     {
3216         ret = PNP_GetDepth(BindingHandle,
3217                            lpDevInst,
3218                            pulDepth,
3219                            ulFlags);
3220     }
3221     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3222     {
3223         ret = RpcStatusToCmStatus(RpcExceptionCode());
3224     }
3225     RpcEndExcept;
3226 
3227     return ret;
3228 }
3229 
3230 
3231 /***********************************************************************
3232  * CM_Get_DevNode_Custom_PropertyA [SETUPAPI.@]
3233  */
3234 CONFIGRET
3235 WINAPI
CM_Get_DevNode_Custom_PropertyA(_In_ DEVINST dnDevInst,_In_ PCSTR pszCustomPropertyName,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)3236 CM_Get_DevNode_Custom_PropertyA(
3237     _In_ DEVINST dnDevInst,
3238     _In_ PCSTR pszCustomPropertyName,
3239     _Out_opt_ PULONG pulRegDataType,
3240     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3241     _Inout_ PULONG pulLength,
3242     _In_ ULONG ulFlags)
3243 {
3244     TRACE("CM_Get_DevNode_Custom_PropertyA(%lx %s %p %p %p %lx)\n",
3245           dnDevInst, pszCustomPropertyName, pulRegDataType,
3246           Buffer, pulLength, ulFlags);
3247 
3248     return CM_Get_DevNode_Custom_Property_ExA(dnDevInst, pszCustomPropertyName,
3249                                               pulRegDataType, Buffer,
3250                                               pulLength, ulFlags, NULL);
3251 }
3252 
3253 
3254 /***********************************************************************
3255  * CM_Get_DevNode_Custom_PropertyW [SETUPAPI.@]
3256  */
3257 CONFIGRET
3258 WINAPI
CM_Get_DevNode_Custom_PropertyW(_In_ DEVINST dnDevInst,_In_ PCWSTR pszCustomPropertyName,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)3259 CM_Get_DevNode_Custom_PropertyW(
3260     _In_ DEVINST dnDevInst,
3261     _In_ PCWSTR pszCustomPropertyName,
3262     _Out_opt_ PULONG pulRegDataType,
3263     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3264     _Inout_ PULONG pulLength,
3265     _In_ ULONG ulFlags)
3266 {
3267     TRACE("CM_Get_DevNode_Custom_PropertyW(%lx %s %p %p %p %lx)\n",
3268           dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3269           Buffer, pulLength, ulFlags);
3270 
3271     return CM_Get_DevNode_Custom_Property_ExW(dnDevInst, pszCustomPropertyName,
3272                                               pulRegDataType, Buffer,
3273                                               pulLength, ulFlags, NULL);
3274 }
3275 
3276 
3277 /***********************************************************************
3278  * CM_Get_DevNode_Custom_Property_ExA [SETUPAPI.@]
3279  */
3280 CONFIGRET
3281 WINAPI
CM_Get_DevNode_Custom_Property_ExA(_In_ DEVINST dnDevInst,_In_ PCSTR pszCustomPropertyName,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3282 CM_Get_DevNode_Custom_Property_ExA(
3283     _In_ DEVINST dnDevInst,
3284     _In_ PCSTR pszCustomPropertyName,
3285     _Out_opt_ PULONG pulRegDataType,
3286     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3287     _Inout_ PULONG pulLength,
3288     _In_ ULONG ulFlags,
3289     _In_opt_ HMACHINE hMachine)
3290 {
3291     LPWSTR pszPropertyNameW;
3292     PVOID BufferW;
3293     ULONG ulLengthW;
3294     ULONG ulDataType = REG_NONE;
3295     CONFIGRET ret;
3296 
3297     TRACE("CM_Get_DevNode_Custom_Property_ExA(%lx %s %p %p %p %lx %p)\n",
3298           dnDevInst, pszCustomPropertyName, pulRegDataType,
3299           Buffer, pulLength, ulFlags, hMachine);
3300 
3301     if (!pulLength)
3302         return CR_INVALID_POINTER;
3303 
3304     ulLengthW = *pulLength * sizeof(WCHAR);
3305     BufferW = HeapAlloc(GetProcessHeap(), 0, ulLengthW);
3306     if (!BufferW)
3307         return CR_OUT_OF_MEMORY;
3308 
3309     pszPropertyNameW = pSetupMultiByteToUnicode(pszCustomPropertyName,
3310                                                 CP_ACP);
3311     if (pszPropertyNameW == NULL)
3312     {
3313         HeapFree(GetProcessHeap(), 0, BufferW);
3314         return CR_OUT_OF_MEMORY;
3315     }
3316 
3317     ret = CM_Get_DevNode_Custom_Property_ExW(dnDevInst,
3318                                              pszPropertyNameW,
3319                                              &ulDataType,
3320                                              BufferW,
3321                                              &ulLengthW,
3322                                              ulFlags,
3323                                              hMachine);
3324     if (ret == CR_SUCCESS)
3325     {
3326         if (ulDataType == REG_SZ ||
3327             ulDataType == REG_EXPAND_SZ ||
3328             ulDataType == REG_MULTI_SZ)
3329         {
3330             /* Do W->A conversion */
3331             *pulLength = WideCharToMultiByte(CP_ACP,
3332                                              0,
3333                                              BufferW,
3334                                              lstrlenW(BufferW) + 1,
3335                                              Buffer,
3336                                              *pulLength,
3337                                              NULL,
3338                                              NULL);
3339             if (*pulLength == 0)
3340                 ret = CR_FAILURE;
3341         }
3342         else
3343         {
3344             /* Directly copy the value */
3345             if (ulLengthW <= *pulLength)
3346                 memcpy(Buffer, BufferW, ulLengthW);
3347             else
3348             {
3349                 *pulLength = ulLengthW;
3350                 ret = CR_BUFFER_SMALL;
3351             }
3352         }
3353     }
3354 
3355     if (pulRegDataType)
3356         *pulRegDataType = ulDataType;
3357 
3358     HeapFree(GetProcessHeap(), 0, BufferW);
3359     MyFree(pszPropertyNameW);
3360 
3361     return ret;
3362 }
3363 
3364 
3365 /***********************************************************************
3366  * CM_Get_DevNode_Custom_Property_ExW [SETUPAPI.@]
3367  */
3368 CONFIGRET
3369 WINAPI
CM_Get_DevNode_Custom_Property_ExW(_In_ DEVINST dnDevInst,_In_ PCWSTR pszCustomPropertyName,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3370 CM_Get_DevNode_Custom_Property_ExW(
3371     _In_ DEVINST dnDevInst,
3372     _In_ PCWSTR pszCustomPropertyName,
3373     _Out_opt_ PULONG pulRegDataType,
3374     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3375     _Inout_ PULONG pulLength,
3376     _In_ ULONG ulFlags,
3377     _In_opt_ HMACHINE hMachine)
3378 {
3379     RPC_BINDING_HANDLE BindingHandle = NULL;
3380     HSTRING_TABLE StringTable = NULL;
3381     LPWSTR lpDevInst;
3382     ULONG ulDataType = REG_NONE;
3383     ULONG ulTransferLength;
3384     CONFIGRET ret = CR_SUCCESS;
3385 
3386     TRACE("CM_Get_DevNode_Custom_Property_ExW(%lx %s %p %p %p %lx %p)\n",
3387           dnDevInst, debugstr_w(pszCustomPropertyName), pulRegDataType,
3388           Buffer, pulLength, ulFlags, hMachine);
3389 
3390     if (dnDevInst == 0)
3391         return CR_INVALID_DEVNODE;
3392 
3393     if (pszCustomPropertyName == NULL ||
3394         pulLength == NULL ||
3395         *pulLength == 0)
3396         return CR_INVALID_POINTER;
3397 
3398     if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
3399         return CR_INVALID_FLAG;
3400 
3401     if (hMachine != NULL)
3402     {
3403         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3404         if (BindingHandle == NULL)
3405             return CR_FAILURE;
3406 
3407         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3408         if (StringTable == 0)
3409             return CR_FAILURE;
3410     }
3411     else
3412     {
3413         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3414             return CR_FAILURE;
3415     }
3416 
3417     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3418     if (lpDevInst == NULL)
3419         return CR_INVALID_DEVNODE;
3420 
3421     ulTransferLength = *pulLength;
3422 
3423     RpcTryExcept
3424     {
3425         ret = PNP_GetCustomDevProp(BindingHandle,
3426                                    lpDevInst,
3427                                    (LPWSTR)pszCustomPropertyName,
3428                                    &ulDataType,
3429                                    Buffer,
3430                                    &ulTransferLength,
3431                                    pulLength,
3432                                    ulFlags);
3433     }
3434     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3435     {
3436         ret = RpcStatusToCmStatus(RpcExceptionCode());
3437     }
3438     RpcEndExcept;
3439 
3440     if (ret == CR_SUCCESS)
3441     {
3442         if (pulRegDataType != NULL)
3443             *pulRegDataType = ulDataType;
3444     }
3445 
3446     return ret;
3447 }
3448 
3449 
3450 /***********************************************************************
3451  * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
3452  */
3453 CONFIGRET
3454 WINAPI
CM_Get_DevNode_Registry_PropertyA(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)3455 CM_Get_DevNode_Registry_PropertyA(
3456     _In_ DEVINST dnDevInst,
3457     _In_ ULONG ulProperty,
3458     _Out_opt_ PULONG pulRegDataType,
3459     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3460     _Inout_ PULONG pulLength,
3461     _In_ ULONG ulFlags)
3462 {
3463     TRACE("CM_Get_DevNode_Registry_PropertyA(%lx %lu %p %p %p %lx)\n",
3464           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3465 
3466     return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
3467                                                 pulRegDataType, Buffer,
3468                                                 pulLength, ulFlags, NULL);
3469 }
3470 
3471 
3472 /***********************************************************************
3473  * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
3474  */
3475 CONFIGRET
3476 WINAPI
CM_Get_DevNode_Registry_PropertyW(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)3477 CM_Get_DevNode_Registry_PropertyW(
3478     _In_ DEVINST dnDevInst,
3479     _In_ ULONG ulProperty,
3480     _Out_opt_ PULONG pulRegDataType,
3481     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3482     _Inout_ PULONG pulLength,
3483     _In_ ULONG ulFlags)
3484 {
3485     TRACE("CM_Get_DevNode_Registry_PropertyW(%lx %lu %p %p %p %lx)\n",
3486           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
3487 
3488     return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
3489                                                 pulRegDataType, Buffer,
3490                                                 pulLength, ulFlags, NULL);
3491 }
3492 
3493 
3494 /***********************************************************************
3495  * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
3496  */
3497 CONFIGRET
3498 WINAPI
CM_Get_DevNode_Registry_Property_ExA(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3499 CM_Get_DevNode_Registry_Property_ExA(
3500     _In_ DEVINST dnDevInst,
3501     _In_ ULONG ulProperty,
3502     _Out_opt_ PULONG pulRegDataType,
3503     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3504     _Inout_ PULONG pulLength,
3505     _In_ ULONG ulFlags,
3506     _In_opt_ HMACHINE hMachine)
3507 {
3508     PVOID BufferW;
3509     ULONG LengthW;
3510     ULONG ulDataType = REG_NONE;
3511     CONFIGRET ret;
3512 
3513     TRACE("CM_Get_DevNode_Registry_Property_ExA(%lx %lu %p %p %p %lx %p)\n",
3514           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3515           ulFlags, hMachine);
3516 
3517     if (!pulLength)
3518         return CR_INVALID_POINTER;
3519 
3520     LengthW = *pulLength * sizeof(WCHAR);
3521     BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
3522     if (!BufferW)
3523         return CR_OUT_OF_MEMORY;
3524 
3525     ret = CM_Get_DevNode_Registry_Property_ExW(dnDevInst,
3526                                                ulProperty,
3527                                                &ulDataType,
3528                                                BufferW,
3529                                                &LengthW,
3530                                                ulFlags,
3531                                                hMachine);
3532 
3533     if (ret == CR_SUCCESS)
3534     {
3535         if (ulDataType == REG_SZ ||
3536             ulDataType == REG_EXPAND_SZ ||
3537             ulDataType == REG_MULTI_SZ)
3538         {
3539             /* Do W->A conversion */
3540             *pulLength = WideCharToMultiByte(CP_ACP,
3541                                              0,
3542                                              BufferW,
3543                                              lstrlenW(BufferW) + 1,
3544                                              Buffer,
3545                                              *pulLength,
3546                                              NULL,
3547                                              NULL);
3548             if (*pulLength == 0)
3549                 ret = CR_FAILURE;
3550         }
3551         else
3552         {
3553             /* Directly copy the value */
3554             if (LengthW <= *pulLength)
3555                 memcpy(Buffer, BufferW, LengthW);
3556             else
3557             {
3558                 *pulLength = LengthW;
3559                 ret = CR_BUFFER_SMALL;
3560             }
3561         }
3562     }
3563 
3564     if (pulRegDataType)
3565         *pulRegDataType = ulDataType;
3566 
3567     HeapFree(GetProcessHeap(), 0, BufferW);
3568 
3569     return ret;
3570 }
3571 
3572 
3573 /***********************************************************************
3574  * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
3575  */
3576 CONFIGRET
3577 WINAPI
CM_Get_DevNode_Registry_Property_ExW(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_Out_opt_ PULONG pulRegDataType,_Out_writes_bytes_opt_ (* pulLength)PVOID Buffer,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3578 CM_Get_DevNode_Registry_Property_ExW(
3579     _In_ DEVINST dnDevInst,
3580     _In_ ULONG ulProperty,
3581     _Out_opt_ PULONG pulRegDataType,
3582     _Out_writes_bytes_opt_(*pulLength) PVOID Buffer,
3583     _Inout_ PULONG pulLength,
3584     _In_ ULONG ulFlags,
3585     _In_opt_ HMACHINE hMachine)
3586 {
3587     RPC_BINDING_HANDLE BindingHandle = NULL;
3588     HSTRING_TABLE StringTable = NULL;
3589     CONFIGRET ret = CR_SUCCESS;
3590     LPWSTR lpDevInst;
3591     ULONG ulDataType = REG_NONE;
3592     ULONG ulTransferLength = 0;
3593 
3594     TRACE("CM_Get_DevNode_Registry_Property_ExW(%lx %lu %p %p %p %lx %p)\n",
3595           dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
3596           ulFlags, hMachine);
3597 
3598     if (dnDevInst == 0)
3599         return CR_INVALID_DEVNODE;
3600 
3601     if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
3602         return CR_INVALID_PROPERTY;
3603 
3604     /* pulRegDataType is optional */
3605 
3606     /* Buffer is optional */
3607 
3608     if (pulLength == NULL)
3609         return CR_INVALID_POINTER;
3610 
3611     if (*pulLength == 0)
3612         return CR_INVALID_POINTER;
3613 
3614     if (ulFlags != 0)
3615         return CR_INVALID_FLAG;
3616 
3617     if (hMachine != NULL)
3618     {
3619         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3620         if (BindingHandle == NULL)
3621             return CR_FAILURE;
3622 
3623         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3624         if (StringTable == 0)
3625             return CR_FAILURE;
3626     }
3627     else
3628     {
3629         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3630             return CR_FAILURE;
3631     }
3632 
3633     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3634     if (lpDevInst == NULL)
3635         return CR_INVALID_DEVNODE;
3636 
3637     ulTransferLength = *pulLength;
3638 
3639     RpcTryExcept
3640     {
3641         ret = PNP_GetDeviceRegProp(BindingHandle,
3642                                    lpDevInst,
3643                                    ulProperty,
3644                                    &ulDataType,
3645                                    Buffer,
3646                                    &ulTransferLength,
3647                                    pulLength,
3648                                    ulFlags);
3649     }
3650     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3651     {
3652         ret = RpcStatusToCmStatus(RpcExceptionCode());
3653     }
3654     RpcEndExcept;
3655 
3656     if (ret == CR_SUCCESS)
3657     {
3658         if (pulRegDataType != NULL)
3659             *pulRegDataType = ulDataType;
3660     }
3661 
3662     return ret;
3663 }
3664 
3665 
3666 /***********************************************************************
3667  * CM_Get_DevNode_Status [SETUPAPI.@]
3668  */
3669 CONFIGRET
3670 WINAPI
CM_Get_DevNode_Status(_Out_ PULONG pulStatus,_Out_ PULONG pulProblemNumber,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)3671 CM_Get_DevNode_Status(
3672     _Out_ PULONG pulStatus,
3673     _Out_ PULONG pulProblemNumber,
3674     _In_ DEVINST dnDevInst,
3675     _In_ ULONG ulFlags)
3676 {
3677     TRACE("CM_Get_DevNode_Status(%p %p %lx %lx)\n",
3678           pulStatus, pulProblemNumber, dnDevInst, ulFlags);
3679 
3680     return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
3681                                     ulFlags, NULL);
3682 }
3683 
3684 
3685 /***********************************************************************
3686  * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
3687  */
3688 CONFIGRET
3689 WINAPI
CM_Get_DevNode_Status_Ex(_Out_ PULONG pulStatus,_Out_ PULONG pulProblemNumber,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3690 CM_Get_DevNode_Status_Ex(
3691     _Out_ PULONG pulStatus,
3692     _Out_ PULONG pulProblemNumber,
3693     _In_ DEVINST dnDevInst,
3694     _In_ ULONG ulFlags,
3695     _In_opt_ HMACHINE hMachine)
3696 {
3697     RPC_BINDING_HANDLE BindingHandle = NULL;
3698     HSTRING_TABLE StringTable = NULL;
3699     LPWSTR lpDevInst;
3700     CONFIGRET ret;
3701 
3702     TRACE("CM_Get_DevNode_Status_Ex(%p %p %lx %lx %p)\n",
3703           pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
3704 
3705     if (pulStatus == NULL || pulProblemNumber == NULL)
3706         return CR_INVALID_POINTER;
3707 
3708     if (dnDevInst == 0)
3709         return CR_INVALID_DEVINST;
3710 
3711     if (ulFlags != 0)
3712         return CR_INVALID_FLAG;
3713 
3714     if (hMachine != NULL)
3715     {
3716         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3717         if (BindingHandle == NULL)
3718             return CR_FAILURE;
3719 
3720         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3721         if (StringTable == 0)
3722             return CR_FAILURE;
3723     }
3724     else
3725     {
3726         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3727             return CR_FAILURE;
3728     }
3729 
3730     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
3731     if (lpDevInst == NULL)
3732         return CR_INVALID_DEVNODE;
3733 
3734     RpcTryExcept
3735     {
3736         ret = PNP_GetDeviceStatus(BindingHandle,
3737                                   lpDevInst,
3738                                   pulStatus,
3739                                   pulProblemNumber,
3740                                   ulFlags);
3741     }
3742     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3743     {
3744         ret = RpcStatusToCmStatus(RpcExceptionCode());
3745     }
3746     RpcEndExcept;
3747 
3748     return ret;
3749 }
3750 
3751 
3752 /***********************************************************************
3753  * CM_Get_Device_IDA [SETUPAPI.@]
3754  */
3755 CONFIGRET
3756 WINAPI
CM_Get_Device_IDA(_In_ DEVINST dnDevInst,_Out_writes_ (BufferLen)PCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags)3757 CM_Get_Device_IDA(
3758     _In_ DEVINST dnDevInst,
3759     _Out_writes_(BufferLen) PCHAR Buffer,
3760     _In_ ULONG BufferLen,
3761     _In_ ULONG ulFlags)
3762 {
3763     TRACE("CM_Get_Device_IDA(%lx %p %lu %lx)\n",
3764           dnDevInst, Buffer, BufferLen, ulFlags);
3765 
3766     return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3767 }
3768 
3769 
3770 /***********************************************************************
3771  * CM_Get_Device_IDW [SETUPAPI.@]
3772  */
3773 CONFIGRET
3774 WINAPI
CM_Get_Device_IDW(_In_ DEVINST dnDevInst,_Out_writes_ (BufferLen)PWCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags)3775 CM_Get_Device_IDW(
3776     _In_ DEVINST dnDevInst,
3777     _Out_writes_(BufferLen) PWCHAR Buffer,
3778     _In_ ULONG BufferLen,
3779     _In_ ULONG ulFlags)
3780 {
3781     TRACE("CM_Get_Device_IDW(%lx %p %lu %lx)\n",
3782           dnDevInst, Buffer, BufferLen, ulFlags);
3783 
3784     return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
3785 }
3786 
3787 
3788 /***********************************************************************
3789  * CM_Get_Device_ID_ExA [SETUPAPI.@]
3790  */
3791 CONFIGRET
3792 WINAPI
CM_Get_Device_ID_ExA(_In_ DEVINST dnDevInst,_Out_writes_ (BufferLen)PCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3793 CM_Get_Device_ID_ExA(
3794     _In_ DEVINST dnDevInst,
3795     _Out_writes_(BufferLen) PCHAR Buffer,
3796     _In_ ULONG BufferLen,
3797     _In_ ULONG ulFlags,
3798     _In_opt_ HMACHINE hMachine)
3799 {
3800     WCHAR szBufferW[MAX_DEVICE_ID_LEN];
3801     CONFIGRET ret = CR_SUCCESS;
3802 
3803     TRACE("CM_Get_Device_ID_ExA(%lx %p %lu %lx %p)\n",
3804           dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3805 
3806     if (Buffer == NULL)
3807         return CR_INVALID_POINTER;
3808 
3809     ret = CM_Get_Device_ID_ExW(dnDevInst,
3810                                szBufferW,
3811                                MAX_DEVICE_ID_LEN,
3812                                ulFlags,
3813                                hMachine);
3814     if (ret == CR_SUCCESS)
3815     {
3816         if (WideCharToMultiByte(CP_ACP,
3817                                 0,
3818                                 szBufferW,
3819                                 lstrlenW(szBufferW) + 1,
3820                                 Buffer,
3821                                 BufferLen,
3822                                 NULL,
3823                                 NULL) == 0)
3824             ret = CR_FAILURE;
3825     }
3826 
3827     return ret;
3828 }
3829 
3830 
3831 /***********************************************************************
3832  * CM_Get_Device_ID_ExW [SETUPAPI.@]
3833  */
3834 CONFIGRET
3835 WINAPI
CM_Get_Device_ID_ExW(_In_ DEVINST dnDevInst,_Out_writes_ (BufferLen)PWCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3836 CM_Get_Device_ID_ExW(
3837     _In_ DEVINST dnDevInst,
3838     _Out_writes_(BufferLen) PWCHAR Buffer,
3839     _In_ ULONG BufferLen,
3840     _In_ ULONG ulFlags,
3841     _In_opt_ HMACHINE hMachine)
3842 {
3843     HSTRING_TABLE StringTable = NULL;
3844 
3845     TRACE("CM_Get_Device_ID_ExW(%lx %p %lu %lx %p)\n",
3846           dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
3847 
3848     if (dnDevInst == 0)
3849         return CR_INVALID_DEVINST;
3850 
3851     if (Buffer == NULL)
3852         return CR_INVALID_POINTER;
3853 
3854     if (ulFlags != 0)
3855         return CR_INVALID_FLAG;
3856 
3857     if (hMachine != NULL)
3858     {
3859         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3860         if (StringTable == NULL)
3861             return CR_FAILURE;
3862     }
3863     else
3864     {
3865         if (!PnpGetLocalHandles(NULL, &StringTable))
3866             return CR_FAILURE;
3867     }
3868 
3869     if (!pSetupStringTableStringFromIdEx(StringTable,
3870                                          dnDevInst,
3871                                          Buffer,
3872                                          &BufferLen))
3873         return CR_FAILURE;
3874 
3875     return CR_SUCCESS;
3876 }
3877 
3878 
3879 /***********************************************************************
3880  * CM_Get_Device_ID_ListA [SETUPAPI.@]
3881  */
3882 CONFIGRET
3883 WINAPI
CM_Get_Device_ID_ListA(_In_ PCSTR pszFilter,_Out_writes_ (BufferLen)PCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags)3884 CM_Get_Device_ID_ListA(
3885     _In_ PCSTR pszFilter,
3886     _Out_writes_(BufferLen) PCHAR Buffer,
3887     _In_ ULONG BufferLen,
3888     _In_ ULONG ulFlags)
3889 {
3890     TRACE("CM_Get_Device_ID_ListA(%p %p %lu %lx)\n",
3891           pszFilter, Buffer, BufferLen, ulFlags);
3892 
3893     return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
3894                                      ulFlags, NULL);
3895 }
3896 
3897 
3898 /***********************************************************************
3899  * CM_Get_Device_ID_ListW [SETUPAPI.@]
3900  */
3901 CONFIGRET
3902 WINAPI
CM_Get_Device_ID_ListW(_In_ PCWSTR pszFilter,_Out_writes_ (BufferLen)PWCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags)3903 CM_Get_Device_ID_ListW(
3904     _In_ PCWSTR pszFilter,
3905     _Out_writes_(BufferLen) PWCHAR Buffer,
3906     _In_ ULONG BufferLen,
3907     _In_ ULONG ulFlags)
3908 {
3909     TRACE("CM_Get_Device_ID_ListW(%p %p %lu %lx)\n",
3910           pszFilter, Buffer, BufferLen, ulFlags);
3911 
3912     return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
3913                                      ulFlags, NULL);
3914 }
3915 
3916 
3917 /***********************************************************************
3918  * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
3919  */
3920 CONFIGRET
3921 WINAPI
CM_Get_Device_ID_List_ExA(_In_ PCSTR pszFilter,_Out_writes_ (BufferLen)PCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3922 CM_Get_Device_ID_List_ExA(
3923     _In_ PCSTR pszFilter,
3924     _Out_writes_(BufferLen) PCHAR Buffer,
3925     _In_ ULONG BufferLen,
3926     _In_ ULONG ulFlags,
3927     _In_opt_ HMACHINE hMachine)
3928 {
3929     LPWSTR BufferW = NULL;
3930     LPWSTR pszFilterW = NULL;
3931     CONFIGRET ret = CR_SUCCESS;
3932 
3933     TRACE("CM_Get_Device_ID_List_ExA(%p %p %lu %lx %p)\n",
3934           pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3935 
3936     BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
3937     if (BufferW == NULL)
3938         return CR_OUT_OF_MEMORY;
3939 
3940     if (pszFilter == NULL)
3941     {
3942         ret = CM_Get_Device_ID_List_ExW(NULL,
3943                                         BufferW,
3944                                         BufferLen,
3945                                         ulFlags,
3946                                         hMachine);
3947     }
3948     else
3949     {
3950         if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
3951         {
3952             ret = CR_INVALID_DEVICE_ID;
3953             goto Done;
3954         }
3955 
3956         ret = CM_Get_Device_ID_List_ExW(pszFilterW,
3957                                         BufferW,
3958                                         BufferLen,
3959                                         ulFlags,
3960                                         hMachine);
3961 
3962         MyFree(pszFilterW);
3963     }
3964 
3965     if (WideCharToMultiByte(CP_ACP,
3966                             0,
3967                             BufferW,
3968                             BufferLen,
3969                             Buffer,
3970                             BufferLen,
3971                             NULL,
3972                             NULL) == 0)
3973         ret = CR_FAILURE;
3974 
3975 Done:
3976     MyFree(BufferW);
3977 
3978     return ret;
3979 }
3980 
3981 
3982 /***********************************************************************
3983  * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
3984  */
3985 CONFIGRET
3986 WINAPI
CM_Get_Device_ID_List_ExW(_In_ PCWSTR pszFilter,_Out_writes_ (BufferLen)PWCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)3987 CM_Get_Device_ID_List_ExW(
3988     _In_ PCWSTR pszFilter,
3989     _Out_writes_(BufferLen) PWCHAR Buffer,
3990     _In_ ULONG BufferLen,
3991     _In_ ULONG ulFlags,
3992     _In_opt_ HMACHINE hMachine)
3993 {
3994     RPC_BINDING_HANDLE BindingHandle = NULL;
3995     CONFIGRET ret;
3996 
3997     TRACE("CM_Get_Device_ID_List_ExW(%p %p %lu %lx %p)\n",
3998           pszFilter, Buffer, BufferLen, ulFlags, hMachine);
3999 
4000     if (Buffer == NULL || BufferLen == 0)
4001         return CR_INVALID_POINTER;
4002 
4003     if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
4004         return CR_INVALID_FLAG;
4005 
4006     if (hMachine != NULL)
4007     {
4008         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4009         if (BindingHandle == NULL)
4010             return CR_FAILURE;
4011     }
4012     else
4013     {
4014         if (!PnpGetLocalHandles(&BindingHandle, NULL))
4015             return CR_FAILURE;
4016     }
4017 
4018     *Buffer = 0;
4019 
4020     RpcTryExcept
4021     {
4022         ret = PNP_GetDeviceList(BindingHandle,
4023                                 (LPWSTR)pszFilter,
4024                                 Buffer,
4025                                 &BufferLen,
4026                                 ulFlags);
4027     }
4028     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4029     {
4030         ret = RpcStatusToCmStatus(RpcExceptionCode());
4031     }
4032     RpcEndExcept;
4033 
4034     return ret;
4035 }
4036 
4037 
4038 /***********************************************************************
4039  * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
4040  */
4041 CONFIGRET
4042 WINAPI
CM_Get_Device_ID_List_SizeA(_Out_ PULONG pulLen,_In_opt_ PCSTR pszFilter,_In_ ULONG ulFlags)4043 CM_Get_Device_ID_List_SizeA(
4044     _Out_ PULONG pulLen,
4045     _In_opt_ PCSTR pszFilter,
4046     _In_ ULONG ulFlags)
4047 {
4048     TRACE("CM_Get_Device_ID_List_SizeA(%p %s %lx)\n",
4049           pulLen, debugstr_a(pszFilter), ulFlags);
4050 
4051     return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
4052 }
4053 
4054 
4055 /***********************************************************************
4056  * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
4057  */
4058 CONFIGRET
4059 WINAPI
CM_Get_Device_ID_List_SizeW(_Out_ PULONG pulLen,_In_opt_ PCWSTR pszFilter,_In_ ULONG ulFlags)4060 CM_Get_Device_ID_List_SizeW(
4061     _Out_ PULONG pulLen,
4062     _In_opt_ PCWSTR pszFilter,
4063     _In_ ULONG ulFlags)
4064 {
4065     TRACE("CM_Get_Device_ID_List_SizeW(%p %s %lx)\n",
4066           pulLen, debugstr_w(pszFilter), ulFlags);
4067 
4068     return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
4069 }
4070 
4071 
4072 /***********************************************************************
4073  * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
4074  */
4075 CONFIGRET
4076 WINAPI
CM_Get_Device_ID_List_Size_ExA(_Out_ PULONG pulLen,_In_opt_ PCSTR pszFilter,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4077 CM_Get_Device_ID_List_Size_ExA(
4078     _Out_ PULONG pulLen,
4079     _In_opt_ PCSTR pszFilter,
4080     _In_ ULONG ulFlags,
4081     _In_opt_ HMACHINE hMachine)
4082 {
4083     LPWSTR pszFilterW = NULL;
4084     CONFIGRET ret = CR_SUCCESS;
4085 
4086     FIXME("CM_Get_Device_ID_List_Size_ExA(%p %s %lx %p)\n",
4087           pulLen, debugstr_a(pszFilter), ulFlags, hMachine);
4088 
4089     if (pszFilter == NULL)
4090     {
4091         ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
4092                                              NULL,
4093                                              ulFlags,
4094                                              hMachine);
4095     }
4096     else
4097     {
4098         if (pSetupCaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
4099             return CR_INVALID_DEVICE_ID;
4100 
4101         ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
4102                                              pszFilterW,
4103                                              ulFlags,
4104                                              hMachine);
4105 
4106         MyFree(pszFilterW);
4107     }
4108 
4109     return ret;
4110 }
4111 
4112 
4113 /***********************************************************************
4114  * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
4115  */
4116 CONFIGRET
4117 WINAPI
CM_Get_Device_ID_List_Size_ExW(_Out_ PULONG pulLen,_In_opt_ PCWSTR pszFilter,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4118 CM_Get_Device_ID_List_Size_ExW(
4119     _Out_ PULONG pulLen,
4120     _In_opt_ PCWSTR pszFilter,
4121     _In_ ULONG ulFlags,
4122     _In_opt_ HMACHINE hMachine)
4123 {
4124     RPC_BINDING_HANDLE BindingHandle = NULL;
4125     CONFIGRET ret;
4126 
4127     FIXME("CM_Get_Device_ID_List_Size_ExW(%p %s %lx %p)\n",
4128           pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
4129 
4130     if (pulLen == NULL)
4131         return CR_INVALID_POINTER;
4132 
4133     if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
4134         return CR_INVALID_FLAG;
4135 
4136     if (hMachine != NULL)
4137     {
4138         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4139         if (BindingHandle == NULL)
4140             return CR_FAILURE;
4141     }
4142     else
4143     {
4144         if (!PnpGetLocalHandles(&BindingHandle, NULL))
4145             return CR_FAILURE;
4146     }
4147 
4148     *pulLen = 0;
4149 
4150     RpcTryExcept
4151     {
4152         ret = PNP_GetDeviceListSize(BindingHandle,
4153                                     (LPWSTR)pszFilter,
4154                                     pulLen,
4155                                     ulFlags);
4156     }
4157     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4158     {
4159         ret = RpcStatusToCmStatus(RpcExceptionCode());
4160     }
4161     RpcEndExcept;
4162 
4163     return ret;
4164 }
4165 
4166 
4167 /***********************************************************************
4168  * CM_Get_Device_ID_Size [SETUPAPI.@]
4169  */
4170 CONFIGRET
4171 WINAPI
CM_Get_Device_ID_Size(_Out_ PULONG pulLen,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)4172 CM_Get_Device_ID_Size(
4173     _Out_ PULONG pulLen,
4174     _In_ DEVINST dnDevInst,
4175     _In_ ULONG ulFlags)
4176 {
4177     TRACE("CM_Get_Device_ID_Size(%p %lx %lx)\n",
4178           pulLen, dnDevInst, ulFlags);
4179 
4180     return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
4181 }
4182 
4183 
4184 /***********************************************************************
4185  * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
4186  */
4187 CONFIGRET
4188 WINAPI
CM_Get_Device_ID_Size_Ex(_Out_ PULONG pulLen,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4189 CM_Get_Device_ID_Size_Ex(
4190     _Out_ PULONG pulLen,
4191     _In_ DEVINST dnDevInst,
4192     _In_ ULONG ulFlags,
4193     _In_opt_ HMACHINE hMachine)
4194 {
4195     HSTRING_TABLE StringTable = NULL;
4196     LPWSTR DeviceId;
4197 
4198     TRACE("CM_Get_Device_ID_Size_Ex(%p %lx %lx %p)\n",
4199           pulLen, dnDevInst, ulFlags, hMachine);
4200 
4201     if (pulLen == NULL)
4202         return CR_INVALID_POINTER;
4203 
4204     if (dnDevInst == 0)
4205         return CR_INVALID_DEVINST;
4206 
4207     if (ulFlags != 0)
4208         return CR_INVALID_FLAG;
4209 
4210     if (hMachine != NULL)
4211     {
4212         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4213         if (StringTable == NULL)
4214             return CR_FAILURE;
4215     }
4216     else
4217     {
4218         if (!PnpGetLocalHandles(NULL, &StringTable))
4219             return CR_FAILURE;
4220     }
4221 
4222     DeviceId = pSetupStringTableStringFromId(StringTable, dnDevInst);
4223     if (DeviceId == NULL)
4224     {
4225         *pulLen = 0;
4226         return CR_SUCCESS;
4227     }
4228 
4229     *pulLen = lstrlenW(DeviceId);
4230 
4231     return CR_SUCCESS;
4232 }
4233 
4234 
4235 /***********************************************************************
4236  * CM_Get_Device_Interface_AliasA [SETUPAPI.@]
4237  */
4238 CONFIGRET
4239 WINAPI
CM_Get_Device_Interface_AliasA(_In_ LPCSTR pszDeviceInterface,_In_ LPGUID AliasInterfaceGuid,_Out_writes_ (* pulLength)LPSTR pszAliasDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)4240 CM_Get_Device_Interface_AliasA(
4241     _In_ LPCSTR pszDeviceInterface,
4242     _In_ LPGUID AliasInterfaceGuid,
4243     _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4244     _Inout_ PULONG pulLength,
4245     _In_ ULONG ulFlags)
4246 {
4247     TRACE("CM_Get_Device_Interface_AliasA(%p %p %p %p %lx)\n",
4248           pszDeviceInterface, AliasInterfaceGuid,
4249           pszAliasDeviceInterface, pulLength, ulFlags);
4250 
4251     return CM_Get_Device_Interface_Alias_ExA(pszDeviceInterface,
4252         AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4253         ulFlags, NULL);
4254 }
4255 
4256 
4257 /***********************************************************************
4258  * CM_Get_Device_Interface_AliasW [SETUPAPI.@]
4259  */
4260 CONFIGRET
4261 WINAPI
CM_Get_Device_Interface_AliasW(_In_ LPCWSTR pszDeviceInterface,_In_ LPGUID AliasInterfaceGuid,_Out_writes_ (* pulLength)LPWSTR pszAliasDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)4262 CM_Get_Device_Interface_AliasW(
4263     _In_ LPCWSTR pszDeviceInterface,
4264     _In_ LPGUID AliasInterfaceGuid,
4265     _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4266     _Inout_ PULONG pulLength,
4267     _In_ ULONG ulFlags)
4268 {
4269     TRACE("CM_Get_Device_Interface_AliasW(%p %p %p %p %lx)\n",
4270           pszDeviceInterface, AliasInterfaceGuid,
4271           pszAliasDeviceInterface, pulLength, ulFlags);
4272 
4273     return CM_Get_Device_Interface_Alias_ExW(pszDeviceInterface,
4274         AliasInterfaceGuid, pszAliasDeviceInterface, pulLength,
4275         ulFlags, NULL);
4276 }
4277 
4278 
4279 /***********************************************************************
4280  * CM_Get_Device_Interface_Alias_ExA [SETUPAPI.@]
4281  */
4282 CONFIGRET
4283 WINAPI
CM_Get_Device_Interface_Alias_ExA(_In_ LPCSTR pszDeviceInterface,_In_ LPGUID AliasInterfaceGuid,_Out_writes_ (* pulLength)LPSTR pszAliasDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4284 CM_Get_Device_Interface_Alias_ExA(
4285     _In_ LPCSTR pszDeviceInterface,
4286     _In_ LPGUID AliasInterfaceGuid,
4287     _Out_writes_(*pulLength) LPSTR pszAliasDeviceInterface,
4288     _Inout_ PULONG pulLength,
4289     _In_ ULONG ulFlags,
4290     _In_opt_ HMACHINE hMachine)
4291 {
4292     FIXME("CM_Get_Device_Interface_Alias_ExA(%p %p %p %p %lx %p)\n",
4293           pszDeviceInterface, AliasInterfaceGuid,
4294           pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4295 
4296     return CR_CALL_NOT_IMPLEMENTED;
4297 }
4298 
4299 
4300 /***********************************************************************
4301  * CM_Get_Device_Interface_Alias_ExW [SETUPAPI.@]
4302  */
4303 CONFIGRET
4304 WINAPI
CM_Get_Device_Interface_Alias_ExW(_In_ LPCWSTR pszDeviceInterface,_In_ LPGUID AliasInterfaceGuid,_Out_writes_ (* pulLength)LPWSTR pszAliasDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4305 CM_Get_Device_Interface_Alias_ExW(
4306     _In_ LPCWSTR pszDeviceInterface,
4307     _In_ LPGUID AliasInterfaceGuid,
4308     _Out_writes_(*pulLength) LPWSTR pszAliasDeviceInterface,
4309     _Inout_ PULONG pulLength,
4310     _In_ ULONG ulFlags,
4311     _In_opt_ HMACHINE hMachine)
4312 {
4313     RPC_BINDING_HANDLE BindingHandle = NULL;
4314     ULONG ulTransferLength;
4315     CONFIGRET ret = CR_SUCCESS;
4316 
4317     TRACE("CM_Get_Device_Interface_Alias_ExW(%p %p %p %p %lx %p)\n",
4318           pszDeviceInterface, AliasInterfaceGuid,
4319           pszAliasDeviceInterface, pulLength, ulFlags, hMachine);
4320 
4321     if (pszDeviceInterface == NULL ||
4322         AliasInterfaceGuid == NULL ||
4323         pszAliasDeviceInterface == NULL ||
4324         pulLength == NULL)
4325         return CR_INVALID_POINTER;
4326 
4327     if (ulFlags != 0)
4328         return CR_INVALID_FLAG;
4329 
4330     if (hMachine != NULL)
4331     {
4332         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4333         if (BindingHandle == NULL)
4334             return CR_FAILURE;
4335     }
4336     else
4337     {
4338         if (!PnpGetLocalHandles(&BindingHandle, NULL))
4339             return CR_FAILURE;
4340     }
4341 
4342     ulTransferLength = *pulLength;
4343 
4344     RpcTryExcept
4345     {
4346         ret = PNP_GetInterfaceDeviceAlias(BindingHandle,
4347                                           (LPWSTR)pszDeviceInterface,
4348                                           AliasInterfaceGuid,
4349                                           pszAliasDeviceInterface,
4350                                           pulLength,
4351                                           &ulTransferLength,
4352                                           0);
4353     }
4354     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4355     {
4356         ret = RpcStatusToCmStatus(RpcExceptionCode());
4357     }
4358     RpcEndExcept;
4359 
4360     return ret;
4361 }
4362 
4363 
4364 /***********************************************************************
4365  *      CM_Get_Device_Interface_ListA (SETUPAPI.@)
4366  */
4367 CONFIGRET
4368 WINAPI
CM_Get_Device_Interface_ListA(_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_A pDeviceID,_Out_writes_ (BufferLen)PCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags)4369 CM_Get_Device_Interface_ListA(
4370     _In_ LPGUID InterfaceClassGuid,
4371     _In_opt_ DEVINSTID_A pDeviceID,
4372     _Out_writes_(BufferLen) PCHAR Buffer,
4373     _In_ ULONG BufferLen,
4374     _In_ ULONG ulFlags)
4375 {
4376     TRACE("CM_Get_Device_Interface_ListA(%s %s %p %lu 0x%08lx)\n",
4377           debugstr_guid(InterfaceClassGuid), debugstr_a(pDeviceID),
4378           Buffer, BufferLen, ulFlags);
4379 
4380     return CM_Get_Device_Interface_List_ExA(InterfaceClassGuid, pDeviceID,
4381                                             Buffer, BufferLen, ulFlags, NULL);
4382 }
4383 
4384 
4385 /***********************************************************************
4386  *      CM_Get_Device_Interface_ListW (SETUPAPI.@)
4387  */
4388 CONFIGRET
4389 WINAPI
CM_Get_Device_Interface_ListW(_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_W pDeviceID,_Out_writes_ (BufferLen)PWCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags)4390 CM_Get_Device_Interface_ListW(
4391     _In_ LPGUID InterfaceClassGuid,
4392     _In_opt_ DEVINSTID_W pDeviceID,
4393     _Out_writes_(BufferLen) PWCHAR Buffer,
4394     _In_ ULONG BufferLen,
4395     _In_ ULONG ulFlags)
4396 {
4397     TRACE("CM_Get_Device_Interface_ListW(%s %s %p %lu 0x%08lx)\n",
4398           debugstr_guid(InterfaceClassGuid), debugstr_w(pDeviceID),
4399           Buffer, BufferLen, ulFlags);
4400 
4401     return CM_Get_Device_Interface_List_ExW(InterfaceClassGuid, pDeviceID,
4402                                             Buffer, BufferLen, ulFlags, NULL);
4403 }
4404 
4405 
4406 /***********************************************************************
4407  *      CM_Get_Device_Interface_List_ExA (SETUPAPI.@)
4408  */
4409 CONFIGRET
4410 WINAPI
CM_Get_Device_Interface_List_ExA(_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_A pDeviceID,_Out_writes_ (BufferLen)PCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4411 CM_Get_Device_Interface_List_ExA(
4412     _In_ LPGUID InterfaceClassGuid,
4413     _In_opt_ DEVINSTID_A pDeviceID,
4414     _Out_writes_(BufferLen) PCHAR Buffer,
4415     _In_ ULONG BufferLen,
4416     _In_ ULONG ulFlags,
4417     _In_opt_ HMACHINE hMachine)
4418 {
4419     DEVINSTID_W pDeviceIdW = NULL;
4420     PWCHAR BufferW = NULL;
4421     CONFIGRET ret = CR_SUCCESS;
4422 
4423     TRACE("CM_Get_Device_Interface_List_ExA(%s %s %p %lu 0x%08lx %p)\n",
4424           debugstr_guid(InterfaceClassGuid), debugstr_a(pDeviceID),
4425           Buffer, BufferLen, ulFlags, hMachine);
4426 
4427     if (Buffer == NULL ||
4428         BufferLen == 0)
4429         return CR_INVALID_POINTER;
4430 
4431     if (pDeviceID != NULL)
4432     {
4433         if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4434             return CR_INVALID_DEVICE_ID;
4435     }
4436 
4437     BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
4438     if (BufferW == NULL)
4439     {
4440         ret = CR_OUT_OF_MEMORY;
4441         goto Done;
4442     }
4443 
4444     ret = CM_Get_Device_Interface_List_ExW(InterfaceClassGuid, pDeviceIdW,
4445                                            BufferW, BufferLen, ulFlags,
4446                                            hMachine);
4447     if (ret != CR_SUCCESS)
4448         goto Done;
4449 
4450     if (WideCharToMultiByte(CP_ACP,
4451                             0,
4452                             BufferW,
4453                             BufferLen,
4454                             Buffer,
4455                             BufferLen,
4456                             NULL,
4457                             NULL) == 0)
4458         ret = CR_FAILURE;
4459 
4460 Done:
4461     if (BufferW != NULL)
4462         MyFree(BufferW);
4463 
4464     if (pDeviceIdW != NULL)
4465         MyFree(pDeviceIdW);
4466 
4467     return ret;
4468 }
4469 
4470 
4471 /***********************************************************************
4472  *      CM_Get_Device_Interface_List_ExW (SETUPAPI.@)
4473  */
4474 CONFIGRET
4475 WINAPI
CM_Get_Device_Interface_List_ExW(_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_W pDeviceID,_Out_writes_ (BufferLen)PWCHAR Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4476 CM_Get_Device_Interface_List_ExW(
4477     _In_ LPGUID InterfaceClassGuid,
4478     _In_opt_ DEVINSTID_W pDeviceID,
4479     _Out_writes_(BufferLen) PWCHAR Buffer,
4480     _In_ ULONG BufferLen,
4481     _In_ ULONG ulFlags,
4482     _In_opt_ HMACHINE hMachine)
4483 {
4484     RPC_BINDING_HANDLE BindingHandle = NULL;
4485     PNP_RPC_BUFFER_SIZE BufferSize = 0;
4486     CONFIGRET ret = CR_SUCCESS;
4487 
4488     TRACE("CM_Get_Device_Interface_List_ExW(%s %s %p %lu 0x%08lx %p)\n",
4489           debugstr_guid(InterfaceClassGuid), debugstr_w(pDeviceID),
4490           Buffer, BufferLen, ulFlags, hMachine);
4491 
4492     if (Buffer == NULL ||
4493         BufferLen == 0)
4494         return CR_INVALID_POINTER;
4495 
4496     if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4497         return CR_INVALID_FLAG;
4498 
4499     if (hMachine != NULL)
4500     {
4501         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4502         if (BindingHandle == NULL)
4503             return CR_FAILURE;
4504     }
4505     else
4506     {
4507         if (!PnpGetLocalHandles(&BindingHandle, NULL))
4508             return CR_FAILURE;
4509     }
4510 
4511     *Buffer = 0;
4512     BufferSize = BufferLen;
4513 
4514     RpcTryExcept
4515     {
4516         ret = PNP_GetInterfaceDeviceList(BindingHandle,
4517                                          InterfaceClassGuid,
4518                                          pDeviceID,
4519                                          (LPBYTE)Buffer,
4520                                          &BufferSize,
4521                                          ulFlags);
4522     }
4523     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4524     {
4525         ret = RpcStatusToCmStatus(RpcExceptionCode());
4526     }
4527     RpcEndExcept;
4528 
4529     return ret;
4530 }
4531 
4532 
4533 /***********************************************************************
4534  *      CM_Get_Device_Interface_List_SizeA (SETUPAPI.@)
4535  */
4536 CONFIGRET
4537 WINAPI
CM_Get_Device_Interface_List_SizeA(_Out_ PULONG pulLen,_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_A pDeviceID,_In_ ULONG ulFlags)4538 CM_Get_Device_Interface_List_SizeA(
4539     _Out_ PULONG pulLen,
4540     _In_ LPGUID InterfaceClassGuid,
4541     _In_opt_ DEVINSTID_A pDeviceID,
4542     _In_ ULONG ulFlags)
4543 {
4544     TRACE("CM_Get_Device_Interface_List_SizeA(%p %p %s 0x%08lx)\n",
4545           pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags);
4546 
4547     return CM_Get_Device_Interface_List_Size_ExA(pulLen, InterfaceClassGuid,
4548                                                  pDeviceID, ulFlags, NULL);
4549 }
4550 
4551 
4552 /***********************************************************************
4553  *      CM_Get_Device_Interface_List_SizeW (SETUPAPI.@)
4554  */
4555 CONFIGRET
4556 WINAPI
CM_Get_Device_Interface_List_SizeW(_Out_ PULONG pulLen,_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_W pDeviceID,_In_ ULONG ulFlags)4557 CM_Get_Device_Interface_List_SizeW(
4558     _Out_ PULONG pulLen,
4559     _In_ LPGUID InterfaceClassGuid,
4560     _In_opt_ DEVINSTID_W pDeviceID,
4561     _In_ ULONG ulFlags)
4562 {
4563     TRACE("CM_Get_Device_Interface_List_SizeW(%p %p %s 0x%08lx)\n",
4564           pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags);
4565 
4566     return CM_Get_Device_Interface_List_Size_ExW(pulLen, InterfaceClassGuid,
4567                                                  pDeviceID, ulFlags, NULL);
4568 }
4569 
4570 
4571 /***********************************************************************
4572  *      CM_Get_Device_Interface_List_Size_ExA (SETUPAPI.@)
4573  */
4574 CONFIGRET
4575 WINAPI
CM_Get_Device_Interface_List_Size_ExA(_Out_ PULONG pulLen,_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_A pDeviceID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4576 CM_Get_Device_Interface_List_Size_ExA(
4577     _Out_ PULONG pulLen,
4578     _In_ LPGUID InterfaceClassGuid,
4579     _In_opt_ DEVINSTID_A pDeviceID,
4580     _In_ ULONG ulFlags,
4581     _In_opt_ HMACHINE hMachine)
4582 {
4583     DEVINSTID_W pDeviceIdW = NULL;
4584     CONFIGRET ret = CR_SUCCESS;
4585 
4586     TRACE("CM_Get_Device_Interface_List_Size_ExA(%p %p %s 0x%08lx %p)\n",
4587           pulLen, InterfaceClassGuid, debugstr_a(pDeviceID), ulFlags, hMachine);
4588 
4589     if (pulLen == NULL)
4590         return CR_INVALID_POINTER;
4591 
4592     if (pDeviceID != NULL)
4593     {
4594         if (!pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDeviceIdW))
4595             return CR_INVALID_DEVICE_ID;
4596     }
4597 
4598     *pulLen = 0;
4599 
4600     ret = CM_Get_Device_Interface_List_Size_ExW(pulLen, InterfaceClassGuid,
4601                                                 pDeviceIdW, ulFlags, hMachine);
4602 
4603     if (pDeviceIdW != NULL)
4604         MyFree(pDeviceIdW);
4605 
4606     return ret;
4607 }
4608 
4609 
4610 /***********************************************************************
4611  *      CM_Get_Device_Interface_List_Size_ExW (SETUPAPI.@)
4612  */
4613 CONFIGRET
4614 WINAPI
CM_Get_Device_Interface_List_Size_ExW(_Out_ PULONG pulLen,_In_ LPGUID InterfaceClassGuid,_In_opt_ DEVINSTID_W pDeviceID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4615 CM_Get_Device_Interface_List_Size_ExW(
4616     _Out_ PULONG pulLen,
4617     _In_ LPGUID InterfaceClassGuid,
4618     _In_opt_ DEVINSTID_W pDeviceID,
4619     _In_ ULONG ulFlags,
4620     _In_opt_ HMACHINE hMachine)
4621 {
4622     RPC_BINDING_HANDLE BindingHandle = NULL;
4623     CONFIGRET ret = CR_SUCCESS;
4624 
4625     TRACE("CM_Get_Device_Interface_List_Size_ExW(%p %p %s 0x%08lx %p)\n",
4626           pulLen, InterfaceClassGuid, debugstr_w(pDeviceID), ulFlags, hMachine);
4627 
4628     if (pulLen == NULL)
4629         return CR_INVALID_POINTER;
4630 
4631     if (ulFlags & ~CM_GET_DEVICE_INTERFACE_LIST_BITS)
4632         return CR_INVALID_FLAG;
4633 
4634     if (hMachine != NULL)
4635     {
4636         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4637         if (BindingHandle == NULL)
4638             return CR_FAILURE;
4639     }
4640     else
4641     {
4642         if (!PnpGetLocalHandles(&BindingHandle, NULL))
4643             return CR_FAILURE;
4644     }
4645 
4646     *pulLen = 0;
4647 
4648     RpcTryExcept
4649     {
4650         ret = PNP_GetInterfaceDeviceListSize(BindingHandle,
4651                                              pulLen,
4652                                              InterfaceClassGuid,
4653                                              pDeviceID,
4654                                              ulFlags);
4655     }
4656     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4657     {
4658         ret = RpcStatusToCmStatus(RpcExceptionCode());
4659     }
4660     RpcEndExcept;
4661 
4662     return ret;
4663 }
4664 
4665 
4666 /***********************************************************************
4667  * CM_Get_First_Log_Conf [SETUPAPI.@]
4668  */
4669 CONFIGRET
4670 WINAPI
CM_Get_First_Log_Conf(_Out_opt_ PLOG_CONF plcLogConf,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)4671 CM_Get_First_Log_Conf(
4672     _Out_opt_ PLOG_CONF plcLogConf,
4673     _In_ DEVINST dnDevInst,
4674     _In_ ULONG ulFlags)
4675 {
4676     TRACE("CM_Get_First_Log_Conf(%p %lx %lx)\n",
4677           plcLogConf, dnDevInst, ulFlags);
4678 
4679     return CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, NULL);
4680 }
4681 
4682 
4683 /***********************************************************************
4684  * CM_Get_First_Log_Conf_Ex [SETUPAPI.@]
4685  */
4686 CONFIGRET
4687 WINAPI
CM_Get_First_Log_Conf_Ex(_Out_opt_ PLOG_CONF plcLogConf,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4688 CM_Get_First_Log_Conf_Ex(
4689     _Out_opt_ PLOG_CONF plcLogConf,
4690     _In_ DEVINST dnDevInst,
4691     _In_ ULONG ulFlags,
4692     _In_opt_ HMACHINE hMachine)
4693 {
4694     RPC_BINDING_HANDLE BindingHandle = NULL;
4695     HSTRING_TABLE StringTable = NULL;
4696     LPWSTR lpDevInst = NULL;
4697     CONFIGRET ret = CR_SUCCESS;
4698     ULONG ulTag;
4699     PLOG_CONF_INFO pLogConfInfo;
4700 
4701     FIXME("CM_Get_First_Log_Conf_Ex(%p %lx %lx %p)\n",
4702           plcLogConf, dnDevInst, ulFlags, hMachine);
4703 
4704     if (dnDevInst == 0)
4705         return CR_INVALID_DEVINST;
4706 
4707     if (ulFlags & ~LOG_CONF_BITS)
4708         return CR_INVALID_FLAG;
4709 
4710     if (plcLogConf)
4711         *plcLogConf = 0;
4712 
4713     if (hMachine != NULL)
4714     {
4715         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4716         if (BindingHandle == NULL)
4717             return CR_FAILURE;
4718 
4719         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4720         if (StringTable == 0)
4721             return CR_FAILURE;
4722     }
4723     else
4724     {
4725         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
4726             return CR_FAILURE;
4727     }
4728 
4729     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
4730     if (lpDevInst == NULL)
4731         return CR_INVALID_DEVNODE;
4732 
4733     RpcTryExcept
4734     {
4735         ret = PNP_GetFirstLogConf(BindingHandle,
4736                                   lpDevInst,
4737                                   ulFlags,
4738                                   &ulTag,
4739                                   ulFlags);
4740     }
4741     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4742     {
4743         ret = RpcStatusToCmStatus(RpcExceptionCode());
4744     }
4745     RpcEndExcept;
4746 
4747     if (ret != CR_SUCCESS)
4748         return ret;
4749 
4750     if (plcLogConf)
4751     {
4752         pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
4753         if (pLogConfInfo == NULL)
4754             return CR_OUT_OF_MEMORY;
4755 
4756         pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
4757         pLogConfInfo->dnDevInst = dnDevInst;
4758         pLogConfInfo->ulType = ulFlags;
4759         pLogConfInfo->ulTag = ulTag;
4760 
4761         *plcLogConf = (LOG_CONF)pLogConfInfo;
4762     }
4763 
4764     return CR_SUCCESS;
4765 }
4766 
4767 
4768 /***********************************************************************
4769  * CM_Get_Global_State [SETUPAPI.@]
4770  */
4771 CONFIGRET
4772 WINAPI
CM_Get_Global_State(_Out_ PULONG pulState,_In_ ULONG ulFlags)4773 CM_Get_Global_State(
4774     _Out_ PULONG pulState,
4775     _In_ ULONG ulFlags)
4776 {
4777     TRACE("CM_Get_Global_State(%p %lx)\n",
4778           pulState, ulFlags);
4779 
4780     return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
4781 }
4782 
4783 
4784 /***********************************************************************
4785  * CM_Get_Global_State_Ex [SETUPAPI.@]
4786  */
4787 CONFIGRET
4788 WINAPI
CM_Get_Global_State_Ex(_Out_ PULONG pulState,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4789 CM_Get_Global_State_Ex(
4790     _Out_ PULONG pulState,
4791     _In_ ULONG ulFlags,
4792     _In_opt_ HMACHINE hMachine)
4793 {
4794     RPC_BINDING_HANDLE BindingHandle = NULL;
4795     CONFIGRET ret;
4796 
4797     TRACE("CM_Get_Global_State_Ex(%p %lx %p)\n",
4798           pulState, ulFlags, hMachine);
4799 
4800     if (pulState == NULL)
4801         return CR_INVALID_POINTER;
4802 
4803     if (ulFlags != 0)
4804         return CR_INVALID_FLAG;
4805 
4806     if (hMachine != NULL)
4807     {
4808         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4809         if (BindingHandle == NULL)
4810             return CR_FAILURE;
4811     }
4812     else
4813     {
4814         if (!PnpGetLocalHandles(&BindingHandle, NULL))
4815             return CR_FAILURE;
4816     }
4817 
4818     RpcTryExcept
4819     {
4820         ret = PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
4821     }
4822     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4823     {
4824         ret = RpcStatusToCmStatus(RpcExceptionCode());
4825     }
4826     RpcEndExcept;
4827 
4828     return ret;
4829 }
4830 
4831 
4832 /***********************************************************************
4833  * CM_Get_HW_Prof_FlagsA [SETUPAPI.@]
4834  */
4835 CONFIGRET
4836 WINAPI
CM_Get_HW_Prof_FlagsA(_In_ DEVINSTID_A szDevInstName,_In_ ULONG ulHardwareProfile,_Out_ PULONG pulValue,_In_ ULONG ulFlags)4837 CM_Get_HW_Prof_FlagsA(
4838     _In_ DEVINSTID_A szDevInstName,
4839     _In_ ULONG ulHardwareProfile,
4840     _Out_ PULONG pulValue,
4841     _In_ ULONG ulFlags)
4842 {
4843     TRACE("CM_Get_HW_Prof_FlagsA(%s %lu %p %lx)\n",
4844           debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4845 
4846     return CM_Get_HW_Prof_Flags_ExA(szDevInstName, ulHardwareProfile,
4847                                     pulValue, ulFlags, NULL);
4848 }
4849 
4850 
4851 /***********************************************************************
4852  * CM_Get_HW_Prof_FlagsW [SETUPAPI.@]
4853  */
4854 CONFIGRET
4855 WINAPI
CM_Get_HW_Prof_FlagsW(_In_ DEVINSTID_W szDevInstName,_In_ ULONG ulHardwareProfile,_Out_ PULONG pulValue,_In_ ULONG ulFlags)4856 CM_Get_HW_Prof_FlagsW(
4857     _In_ DEVINSTID_W szDevInstName,
4858     _In_ ULONG ulHardwareProfile,
4859     _Out_ PULONG pulValue,
4860     _In_ ULONG ulFlags)
4861 {
4862     TRACE("CM_Get_HW_Prof_FlagsW(%s %lu %p %lx)\n",
4863           debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags);
4864 
4865     return CM_Get_HW_Prof_Flags_ExW(szDevInstName, ulHardwareProfile,
4866                                     pulValue, ulFlags, NULL);
4867 }
4868 
4869 
4870 /***********************************************************************
4871  * CM_Get_HW_Prof_Flags_ExA [SETUPAPI.@]
4872  */
4873 CONFIGRET
4874 WINAPI
CM_Get_HW_Prof_Flags_ExA(_In_ DEVINSTID_A szDevInstName,_In_ ULONG ulHardwareProfile,_Out_ PULONG pulValue,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4875 CM_Get_HW_Prof_Flags_ExA(
4876     _In_ DEVINSTID_A szDevInstName,
4877     _In_ ULONG ulHardwareProfile,
4878     _Out_ PULONG pulValue,
4879     _In_ ULONG ulFlags,
4880     _In_opt_ HMACHINE hMachine)
4881 {
4882     DEVINSTID_W pszDevIdW = NULL;
4883     CONFIGRET ret = CR_SUCCESS;
4884 
4885     TRACE("CM_Get_HW_Prof_Flags_ExA(%s %lu %p %lx %p)\n",
4886           debugstr_a(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4887 
4888     if (szDevInstName != NULL)
4889     {
4890        if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
4891          return CR_INVALID_DEVICE_ID;
4892     }
4893 
4894     ret = CM_Get_HW_Prof_Flags_ExW(pszDevIdW, ulHardwareProfile,
4895                                    pulValue, ulFlags, hMachine);
4896 
4897     if (pszDevIdW != NULL)
4898         MyFree(pszDevIdW);
4899 
4900     return ret;
4901 }
4902 
4903 
4904 /***********************************************************************
4905  * CM_Get_HW_Prof_Flags_ExW [SETUPAPI.@]
4906  */
4907 CONFIGRET
4908 WINAPI
CM_Get_HW_Prof_Flags_ExW(_In_ DEVINSTID_W szDevInstName,_In_ ULONG ulHardwareProfile,_Out_ PULONG pulValue,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4909 CM_Get_HW_Prof_Flags_ExW(
4910     _In_ DEVINSTID_W szDevInstName,
4911     _In_ ULONG ulHardwareProfile,
4912     _Out_ PULONG pulValue,
4913     _In_ ULONG ulFlags,
4914     _In_opt_ HMACHINE hMachine)
4915 {
4916     RPC_BINDING_HANDLE BindingHandle = NULL;
4917     CONFIGRET ret;
4918 
4919     FIXME("CM_Get_HW_Prof_Flags_ExW(%s %lu %p %lx %p)\n",
4920           debugstr_w(szDevInstName), ulHardwareProfile, pulValue, ulFlags, hMachine);
4921 
4922     if ((szDevInstName == NULL) || (pulValue == NULL))
4923         return CR_INVALID_POINTER;
4924 
4925     if (ulFlags != 0)
4926         return CR_INVALID_FLAG;
4927 
4928     /* FIXME: Check whether szDevInstName is valid */
4929 
4930     if (hMachine != NULL)
4931     {
4932         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4933         if (BindingHandle == NULL)
4934             return CR_FAILURE;
4935     }
4936     else
4937     {
4938         if (!PnpGetLocalHandles(&BindingHandle, NULL))
4939             return CR_FAILURE;
4940     }
4941 
4942     RpcTryExcept
4943     {
4944         ret = PNP_HwProfFlags(BindingHandle, PNP_GET_HWPROFFLAGS, szDevInstName,
4945                               ulHardwareProfile, pulValue, NULL, NULL, 0, 0);
4946     }
4947     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4948     {
4949         ret = RpcStatusToCmStatus(RpcExceptionCode());
4950     }
4951     RpcEndExcept;
4952 
4953     return ret;
4954 }
4955 
4956 
4957 /***********************************************************************
4958  * CM_Get_Hardware_Profile_InfoA [SETUPAPI.@]
4959  */
4960 CONFIGRET
4961 WINAPI
CM_Get_Hardware_Profile_InfoA(_In_ ULONG ulIndex,_Out_ PHWPROFILEINFO_A pHWProfileInfo,_In_ ULONG ulFlags)4962 CM_Get_Hardware_Profile_InfoA(
4963     _In_ ULONG ulIndex,
4964     _Out_ PHWPROFILEINFO_A pHWProfileInfo,
4965     _In_ ULONG ulFlags)
4966 {
4967     TRACE("CM_Get_Hardware_Profile_InfoA(%lu %p %lx)\n",
4968           ulIndex, pHWProfileInfo, ulFlags);
4969 
4970     return CM_Get_Hardware_Profile_Info_ExA(ulIndex, pHWProfileInfo,
4971                                             ulFlags, NULL);
4972 }
4973 
4974 
4975 /***********************************************************************
4976  * CM_Get_Hardware_Profile_InfoW [SETUPAPI.@]
4977  */
4978 CONFIGRET
4979 WINAPI
CM_Get_Hardware_Profile_InfoW(_In_ ULONG ulIndex,_Out_ PHWPROFILEINFO_W pHWProfileInfo,_In_ ULONG ulFlags)4980 CM_Get_Hardware_Profile_InfoW(
4981     _In_ ULONG ulIndex,
4982     _Out_ PHWPROFILEINFO_W pHWProfileInfo,
4983     _In_ ULONG ulFlags)
4984 {
4985     TRACE("CM_Get_Hardware_Profile_InfoW(%lu %p %lx)\n",
4986           ulIndex, pHWProfileInfo, ulFlags);
4987 
4988     return CM_Get_Hardware_Profile_Info_ExW(ulIndex, pHWProfileInfo,
4989                                             ulFlags, NULL);
4990 }
4991 
4992 
4993 /***********************************************************************
4994  * CM_Get_Hardware_Profile_Info_ExA [SETUPAPI.@]
4995  */
4996 CONFIGRET
4997 WINAPI
CM_Get_Hardware_Profile_Info_ExA(_In_ ULONG ulIndex,_Out_ PHWPROFILEINFO_A pHWProfileInfo,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)4998 CM_Get_Hardware_Profile_Info_ExA(
4999     _In_ ULONG ulIndex,
5000     _Out_ PHWPROFILEINFO_A pHWProfileInfo,
5001     _In_ ULONG ulFlags,
5002     _In_opt_ HMACHINE hMachine)
5003 {
5004     HWPROFILEINFO_W LocalProfileInfo;
5005     CONFIGRET ret;
5006 
5007     TRACE("CM_Get_Hardware_Profile_Info_ExA(%lu %p %lx %p)\n",
5008           ulIndex, pHWProfileInfo, ulFlags, hMachine);
5009 
5010     if (pHWProfileInfo == NULL)
5011         return CR_INVALID_POINTER;
5012 
5013     ret = CM_Get_Hardware_Profile_Info_ExW(ulIndex, &LocalProfileInfo,
5014                                            ulFlags, hMachine);
5015     if (ret == CR_SUCCESS)
5016     {
5017         pHWProfileInfo->HWPI_ulHWProfile = LocalProfileInfo.HWPI_ulHWProfile;
5018         pHWProfileInfo->HWPI_dwFlags = LocalProfileInfo.HWPI_dwFlags;
5019 
5020         if (WideCharToMultiByte(CP_ACP,
5021                                 0,
5022                                 LocalProfileInfo.HWPI_szFriendlyName,
5023                                 lstrlenW(LocalProfileInfo.HWPI_szFriendlyName) + 1,
5024                                 pHWProfileInfo->HWPI_szFriendlyName,
5025                                 MAX_PROFILE_LEN,
5026                                 NULL,
5027                                 NULL) == 0)
5028             ret = CR_FAILURE;
5029     }
5030 
5031     return ret;
5032 }
5033 
5034 
5035 /***********************************************************************
5036  * CM_Get_Hardware_Profile_Info_ExW [SETUPAPI.@]
5037  */
5038 CONFIGRET
5039 WINAPI
CM_Get_Hardware_Profile_Info_ExW(_In_ ULONG ulIndex,_Out_ PHWPROFILEINFO_W pHWProfileInfo,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5040 CM_Get_Hardware_Profile_Info_ExW(
5041     _In_ ULONG ulIndex,
5042     _Out_ PHWPROFILEINFO_W pHWProfileInfo,
5043     _In_ ULONG ulFlags,
5044     _In_opt_ HMACHINE hMachine)
5045 {
5046     RPC_BINDING_HANDLE BindingHandle = NULL;
5047     CONFIGRET ret;
5048 
5049     TRACE("CM_Get_Hardware_Profile_Info_ExW(%lu %p %lx %p)\n",
5050           ulIndex, pHWProfileInfo, ulFlags, hMachine);
5051 
5052     if (pHWProfileInfo == NULL)
5053         return CR_INVALID_POINTER;
5054 
5055     if (ulFlags != 0)
5056         return CR_INVALID_FLAG;
5057 
5058     if (hMachine != NULL)
5059     {
5060         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5061         if (BindingHandle == NULL)
5062             return CR_FAILURE;
5063     }
5064     else
5065     {
5066         if (!PnpGetLocalHandles(&BindingHandle, NULL))
5067             return CR_FAILURE;
5068     }
5069 
5070     RpcTryExcept
5071     {
5072         ret = PNP_GetHwProfInfo(BindingHandle, ulIndex, pHWProfileInfo,
5073                                 sizeof(HWPROFILEINFO_W), 0);
5074     }
5075     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5076     {
5077         ret = RpcStatusToCmStatus(RpcExceptionCode());
5078     }
5079     RpcEndExcept;
5080 
5081     return ret;
5082 }
5083 
5084 
5085 /***********************************************************************
5086  * CM_Get_Log_Conf_Priority [SETUPAPI.@]
5087  */
5088 CONFIGRET
5089 WINAPI
CM_Get_Log_Conf_Priority(_In_ LOG_CONF lcLogConf,_Out_ PPRIORITY pPriority,_In_ ULONG ulFlags)5090 CM_Get_Log_Conf_Priority(
5091     _In_ LOG_CONF lcLogConf,
5092     _Out_ PPRIORITY pPriority,
5093     _In_ ULONG ulFlags)
5094 {
5095     TRACE("CM_Get_Log_Conf_Priority(%p %p %lx)\n",
5096           lcLogConf, pPriority, ulFlags);
5097 
5098     return CM_Get_Log_Conf_Priority_Ex(lcLogConf, pPriority, ulFlags, NULL);
5099 }
5100 
5101 
5102 /***********************************************************************
5103  * CM_Get_Log_Conf_Priority_Ex [SETUPAPI.@]
5104  */
5105 CONFIGRET
5106 WINAPI
CM_Get_Log_Conf_Priority_Ex(_In_ LOG_CONF lcLogConf,_Out_ PPRIORITY pPriority,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5107 CM_Get_Log_Conf_Priority_Ex(
5108     _In_ LOG_CONF lcLogConf,
5109     _Out_ PPRIORITY pPriority,
5110     _In_ ULONG ulFlags,
5111     _In_opt_ HMACHINE hMachine)
5112 {
5113     RPC_BINDING_HANDLE BindingHandle = NULL;
5114     HSTRING_TABLE StringTable = NULL;
5115     PLOG_CONF_INFO pLogConfInfo;
5116     LPWSTR lpDevInst;
5117     CONFIGRET ret;
5118 
5119     FIXME("CM_Get_Log_Conf_Priority_Ex(%p %p %lx %p)\n",
5120           lcLogConf, pPriority, ulFlags, hMachine);
5121 
5122     pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
5123     if (!IsValidLogConf(pLogConfInfo))
5124         return CR_INVALID_LOG_CONF;
5125 
5126     if (pPriority == NULL)
5127         return CR_INVALID_POINTER;
5128 
5129     if (ulFlags != 0)
5130         return CR_INVALID_FLAG;
5131 
5132     if (hMachine != NULL)
5133     {
5134         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5135         if (BindingHandle == NULL)
5136             return CR_FAILURE;
5137 
5138         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5139         if (StringTable == 0)
5140             return CR_FAILURE;
5141     }
5142     else
5143     {
5144         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5145             return CR_FAILURE;
5146     }
5147 
5148     lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
5149     if (lpDevInst == NULL)
5150         return CR_INVALID_DEVNODE;
5151 
5152     RpcTryExcept
5153     {
5154         ret = PNP_GetLogConfPriority(BindingHandle,
5155                                      lpDevInst,
5156                                      pLogConfInfo->ulType,
5157                                      pLogConfInfo->ulTag,
5158                                      pPriority,
5159                                      0);
5160     }
5161     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5162     {
5163         ret = RpcStatusToCmStatus(RpcExceptionCode());
5164     }
5165     RpcEndExcept;
5166 
5167     return ret;
5168 }
5169 
5170 
5171 /***********************************************************************
5172  * CM_Get_Next_Log_Conf [SETUPAPI.@]
5173  */
5174 CONFIGRET
5175 WINAPI
CM_Get_Next_Log_Conf(_Out_opt_ PLOG_CONF plcLogConf,_In_ LOG_CONF lcLogConf,_In_ ULONG ulFlags)5176 CM_Get_Next_Log_Conf(
5177     _Out_opt_ PLOG_CONF plcLogConf,
5178     _In_ LOG_CONF lcLogConf,
5179     _In_ ULONG ulFlags)
5180 {
5181     TRACE("CM_Get_Next_Log_Conf(%p %p %lx)\n",
5182           plcLogConf, lcLogConf, ulFlags);
5183 
5184     return CM_Get_Next_Log_Conf_Ex(plcLogConf, lcLogConf, ulFlags, NULL);
5185 }
5186 
5187 
5188 /***********************************************************************
5189  * CM_Get_Next_Log_Conf_Ex [SETUPAPI.@]
5190  */
5191 CONFIGRET
5192 WINAPI
CM_Get_Next_Log_Conf_Ex(_Out_opt_ PLOG_CONF plcLogConf,_In_ LOG_CONF lcLogConf,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5193 CM_Get_Next_Log_Conf_Ex(
5194     _Out_opt_ PLOG_CONF plcLogConf,
5195     _In_ LOG_CONF lcLogConf,
5196     _In_ ULONG ulFlags,
5197     _In_opt_ HMACHINE hMachine)
5198 {
5199     RPC_BINDING_HANDLE BindingHandle = NULL;
5200     HSTRING_TABLE StringTable = NULL;
5201     PLOG_CONF_INFO pLogConfInfo;
5202     PLOG_CONF_INFO pNewLogConfInfo;
5203     ULONG ulNewTag;
5204     LPWSTR lpDevInst;
5205     CONFIGRET ret;
5206 
5207     FIXME("CM_Get_Next_Log_Conf_Ex(%p %p %lx %p)\n",
5208           plcLogConf, lcLogConf, ulFlags, hMachine);
5209 
5210     if (plcLogConf)
5211         *plcLogConf = 0;
5212 
5213     pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
5214     if (!IsValidLogConf(pLogConfInfo))
5215         return CR_INVALID_LOG_CONF;
5216 
5217     if (ulFlags != 0)
5218         return CR_INVALID_FLAG;
5219 
5220     if (hMachine != NULL)
5221     {
5222         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5223         if (BindingHandle == NULL)
5224             return CR_FAILURE;
5225 
5226         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5227         if (StringTable == 0)
5228             return CR_FAILURE;
5229     }
5230     else
5231     {
5232         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5233             return CR_FAILURE;
5234     }
5235 
5236     lpDevInst = pSetupStringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
5237     if (lpDevInst == NULL)
5238         return CR_INVALID_DEVNODE;
5239 
5240     RpcTryExcept
5241     {
5242         ret = PNP_GetNextLogConf(BindingHandle,
5243                                  lpDevInst,
5244                                  pLogConfInfo->ulType,
5245                                  pLogConfInfo->ulTag,
5246                                  &ulNewTag,
5247                                  0);
5248     }
5249     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5250     {
5251         ret = RpcStatusToCmStatus(RpcExceptionCode());
5252     }
5253     RpcEndExcept;
5254 
5255     if (ret != CR_SUCCESS)
5256         return ret;
5257 
5258     if (plcLogConf)
5259     {
5260         pNewLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
5261         if (pNewLogConfInfo == NULL)
5262             return CR_OUT_OF_MEMORY;
5263 
5264         pNewLogConfInfo->ulMagic = LOG_CONF_MAGIC;
5265         pNewLogConfInfo->dnDevInst = pLogConfInfo->dnDevInst;
5266         pNewLogConfInfo->ulType = pLogConfInfo->ulType;
5267         pNewLogConfInfo->ulTag = ulNewTag;
5268 
5269         *plcLogConf = (LOG_CONF)pNewLogConfInfo;
5270     }
5271 
5272     return CR_SUCCESS;
5273 }
5274 
5275 
5276 /***********************************************************************
5277  * CM_Get_Next_Res_Des [SETUPAPI.@]
5278  */
5279 CONFIGRET
5280 WINAPI
CM_Get_Next_Res_Des(_Out_ PRES_DES prdResDes,_In_ RES_DES rdResDes,_In_ RESOURCEID ForResource,_Out_opt_ PRESOURCEID pResourceID,_In_ ULONG ulFlags)5281 CM_Get_Next_Res_Des(
5282     _Out_ PRES_DES prdResDes,
5283     _In_ RES_DES rdResDes,
5284     _In_ RESOURCEID ForResource,
5285     _Out_opt_ PRESOURCEID pResourceID,
5286     _In_ ULONG ulFlags)
5287 {
5288     TRACE("CM_Get_Next_Res_Des(%p %p %lu %p %lx)\n",
5289           prdResDes, rdResDes, ForResource, pResourceID, ulFlags);
5290 
5291     return CM_Get_Next_Res_Des_Ex(prdResDes, rdResDes, ForResource,
5292                                   pResourceID, ulFlags, NULL);
5293 }
5294 
5295 
5296 /***********************************************************************
5297  * CM_Get_Next_Re_Des_Ex [SETUPAPI.@]
5298  */
5299 CONFIGRET
5300 WINAPI
CM_Get_Next_Res_Des_Ex(_Out_ PRES_DES prdResDes,_In_ RES_DES rdResDes,_In_ RESOURCEID ForResource,_Out_opt_ PRESOURCEID pResourceID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5301 CM_Get_Next_Res_Des_Ex(
5302     _Out_ PRES_DES prdResDes,
5303     _In_ RES_DES rdResDes,
5304     _In_ RESOURCEID ForResource,
5305     _Out_opt_ PRESOURCEID pResourceID,
5306     _In_ ULONG ulFlags,
5307     _In_opt_ HMACHINE hMachine)
5308 {
5309     RPC_BINDING_HANDLE BindingHandle = NULL;
5310     HSTRING_TABLE StringTable = NULL;
5311     PRES_DES_INFO pNewResDesInfo = NULL;
5312     ULONG ulLogConfTag, ulLogConfType, ulResDesTag;
5313     ULONG ulNextResDesType = 0, ulNextResDesTag = 0;
5314     LPWSTR lpDevInst;
5315     DEVINST dnDevInst;
5316     CONFIGRET ret;
5317 
5318     FIXME("CM_Get_Next_Res_Des_Ex(%p %p %lu %p %lx %p)\n",
5319           prdResDes, rdResDes, ForResource, pResourceID, ulFlags, hMachine);
5320 
5321     if (prdResDes == NULL)
5322         return CR_INVALID_POINTER;
5323 
5324     if (IsValidLogConf((PLOG_CONF_INFO)rdResDes))
5325     {
5326         FIXME("LogConf found!\n");
5327         dnDevInst = ((PLOG_CONF_INFO)rdResDes)->dnDevInst;
5328         ulLogConfTag = ((PLOG_CONF_INFO)rdResDes)->ulTag;
5329         ulLogConfType = ((PLOG_CONF_INFO)rdResDes)->ulType;
5330         ulResDesTag = (ULONG)-1;
5331     }
5332     else if (IsValidResDes((PRES_DES_INFO)rdResDes))
5333     {
5334         FIXME("ResDes found!\n");
5335         dnDevInst = ((PRES_DES_INFO)rdResDes)->dnDevInst;
5336         ulLogConfTag = ((PRES_DES_INFO)rdResDes)->ulLogConfTag;
5337         ulLogConfType = ((PRES_DES_INFO)rdResDes)->ulLogConfType;
5338         ulResDesTag = ((PRES_DES_INFO)rdResDes)->ulResDesTag;
5339     }
5340     else
5341     {
5342         return CR_INVALID_RES_DES;
5343     }
5344 
5345     if ((ForResource == ResType_All) && (pResourceID == NULL))
5346         return CR_INVALID_POINTER;
5347 
5348     if (ulFlags != 0)
5349         return CR_INVALID_FLAG;
5350 
5351     if (hMachine != NULL)
5352     {
5353         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5354         if (BindingHandle == NULL)
5355             return CR_FAILURE;
5356 
5357         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5358         if (StringTable == 0)
5359             return CR_FAILURE;
5360     }
5361     else
5362     {
5363         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5364             return CR_FAILURE;
5365     }
5366 
5367     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
5368     if (lpDevInst == NULL)
5369         return CR_INVALID_DEVNODE;
5370 
5371     RpcTryExcept
5372     {
5373         ret = PNP_GetNextResDes(BindingHandle,
5374                                 lpDevInst,
5375                                 ulLogConfTag,
5376                                 ulLogConfType,
5377                                 ForResource,
5378                                 ulResDesTag,
5379                                 &ulNextResDesTag,
5380                                 &ulNextResDesType,
5381                                 0);
5382     }
5383     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5384     {
5385         ret = RpcStatusToCmStatus(RpcExceptionCode());
5386     }
5387     RpcEndExcept;
5388 
5389     if (ret != CR_SUCCESS)
5390         return ret;
5391 
5392     if (ForResource == ResType_All)
5393         *pResourceID = ulNextResDesType;
5394 
5395     if (prdResDes)
5396     {
5397         pNewResDesInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(RES_DES_INFO));
5398         if (pNewResDesInfo == NULL)
5399             return CR_OUT_OF_MEMORY;
5400 
5401         pNewResDesInfo->ulMagic = LOG_CONF_MAGIC;
5402         pNewResDesInfo->dnDevInst = dnDevInst;
5403         pNewResDesInfo->ulLogConfType = ulLogConfType;
5404         pNewResDesInfo->ulLogConfTag = ulLogConfTag;
5405         pNewResDesInfo->ulResDesType = ulNextResDesType;
5406         pNewResDesInfo->ulResDesTag = ulNextResDesTag;
5407 
5408         *prdResDes = (RES_DES)pNewResDesInfo;
5409     }
5410 
5411     return CR_SUCCESS;
5412 }
5413 
5414 
5415 /***********************************************************************
5416  * CM_Get_Parent [SETUPAPI.@]
5417  */
5418 CONFIGRET
5419 WINAPI
CM_Get_Parent(_Out_ PDEVINST pdnDevInst,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)5420 CM_Get_Parent(
5421     _Out_ PDEVINST pdnDevInst,
5422     _In_ DEVINST dnDevInst,
5423     _In_ ULONG ulFlags)
5424 {
5425     TRACE("CM_Get_Parent(%p %p %lx)\n",
5426           pdnDevInst, dnDevInst, ulFlags);
5427 
5428     return CM_Get_Parent_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
5429 }
5430 
5431 
5432 /***********************************************************************
5433  * CM_Get_Parent_Ex [SETUPAPI.@]
5434  */
5435 CONFIGRET
5436 WINAPI
CM_Get_Parent_Ex(_Out_ PDEVINST pdnDevInst,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5437 CM_Get_Parent_Ex(
5438     _Out_ PDEVINST pdnDevInst,
5439     _In_ DEVINST dnDevInst,
5440     _In_ ULONG ulFlags,
5441     _In_opt_ HMACHINE hMachine)
5442 {
5443     WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
5444     RPC_BINDING_HANDLE BindingHandle = NULL;
5445     HSTRING_TABLE StringTable = NULL;
5446     LPWSTR lpDevInst;
5447     DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
5448     CONFIGRET ret;
5449 
5450     TRACE("CM_Get_Parent_Ex(%p %lx %lx %p)\n",
5451           pdnDevInst, dnDevInst, ulFlags, hMachine);
5452 
5453     if (pdnDevInst == NULL)
5454         return CR_INVALID_POINTER;
5455 
5456     if (dnDevInst == 0)
5457         return CR_INVALID_DEVINST;
5458 
5459     if (ulFlags != 0)
5460         return CR_INVALID_FLAG;
5461 
5462     *pdnDevInst = -1;
5463 
5464     if (hMachine != NULL)
5465     {
5466         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5467         if (BindingHandle == NULL)
5468             return CR_FAILURE;
5469 
5470         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5471         if (StringTable == 0)
5472             return CR_FAILURE;
5473     }
5474     else
5475     {
5476         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5477             return CR_FAILURE;
5478     }
5479 
5480     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
5481     if (lpDevInst == NULL)
5482         return CR_INVALID_DEVNODE;
5483 
5484     RpcTryExcept
5485     {
5486         ret = PNP_GetRelatedDeviceInstance(BindingHandle,
5487                                            PNP_GET_PARENT_DEVICE_INSTANCE,
5488                                            lpDevInst,
5489                                            szRelatedDevInst,
5490                                            &dwLength,
5491                                            0);
5492     }
5493     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5494     {
5495         ret = RpcStatusToCmStatus(RpcExceptionCode());
5496     }
5497     RpcEndExcept;
5498 
5499     if (ret != CR_SUCCESS)
5500         return ret;
5501 
5502     TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
5503 
5504     dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
5505     if (dwIndex == -1)
5506         return CR_FAILURE;
5507 
5508     *pdnDevInst = dwIndex;
5509 
5510     return CR_SUCCESS;
5511 }
5512 
5513 
5514 /***********************************************************************
5515  * CM_Get_Res_Des_Data [SETUPAPI.@]
5516  */
5517 CONFIGRET
5518 WINAPI
CM_Get_Res_Des_Data(_In_ RES_DES rdResDes,_Out_writes_bytes_ (BufferLen)PVOID Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags)5519 CM_Get_Res_Des_Data(
5520     _In_ RES_DES rdResDes,
5521     _Out_writes_bytes_(BufferLen) PVOID Buffer,
5522     _In_ ULONG BufferLen,
5523     _In_ ULONG ulFlags)
5524 {
5525     TRACE("CM_Get_Res_Des_Data(%p %p %lu %lx)\n",
5526           rdResDes, Buffer, BufferLen, ulFlags);
5527 
5528     return CM_Get_Res_Des_Data_Ex(rdResDes, Buffer, BufferLen, ulFlags, NULL);
5529 }
5530 
5531 
5532 /***********************************************************************
5533  * CM_Get_Res_Des_Data_Ex [SETUPAPI.@]
5534  */
5535 CONFIGRET
5536 WINAPI
CM_Get_Res_Des_Data_Ex(_In_ RES_DES rdResDes,_Out_writes_bytes_ (BufferLen)PVOID Buffer,_In_ ULONG BufferLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5537 CM_Get_Res_Des_Data_Ex(
5538     _In_ RES_DES rdResDes,
5539     _Out_writes_bytes_(BufferLen) PVOID Buffer,
5540     _In_ ULONG BufferLen,
5541     _In_ ULONG ulFlags,
5542     _In_opt_ HMACHINE hMachine)
5543 {
5544     FIXME("CM_Get_Res_Des_Data_Ex(%p %p %lu %lx %p)\n",
5545           rdResDes, Buffer, BufferLen, ulFlags, hMachine);
5546 
5547     return CR_CALL_NOT_IMPLEMENTED;
5548 }
5549 
5550 
5551 /***********************************************************************
5552  * CM_Get_Res_Des_Size [SETUPAPI.@]
5553  */
5554 CONFIGRET
5555 WINAPI
CM_Get_Res_Des_Data_Size(_Out_ PULONG pulSize,_In_ RES_DES rdResDes,_In_ ULONG ulFlags)5556 CM_Get_Res_Des_Data_Size(
5557     _Out_ PULONG pulSize,
5558     _In_ RES_DES rdResDes,
5559     _In_ ULONG ulFlags)
5560 {
5561     TRACE("CM_Get_Res_Des_Data_Size(%p %p %lx)\n",
5562           pulSize, rdResDes, ulFlags);
5563 
5564     return CM_Get_Res_Des_Data_Size_Ex(pulSize, rdResDes, ulFlags, NULL);
5565 }
5566 
5567 
5568 /***********************************************************************
5569  * CM_Get_Res_Des_Size_Ex [SETUPAPI.@]
5570  */
5571 CONFIGRET
5572 WINAPI
CM_Get_Res_Des_Data_Size_Ex(_Out_ PULONG pulSize,_In_ RES_DES rdResDes,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5573 CM_Get_Res_Des_Data_Size_Ex(
5574     _Out_ PULONG pulSize,
5575     _In_ RES_DES rdResDes,
5576     _In_ ULONG ulFlags,
5577     _In_opt_ HMACHINE hMachine)
5578 {
5579     TRACE("CM_Get_Res_Des_Data_Size_Ex(%p %p %lx %p)\n",
5580           pulSize, rdResDes, ulFlags, hMachine);
5581 
5582     return CR_CALL_NOT_IMPLEMENTED;
5583 }
5584 
5585 
5586 /***********************************************************************
5587  * CM_Get_Resource_Conflict_Count [SETUPAPI.@]
5588  */
5589 CONFIGRET
5590 WINAPI
CM_Get_Resource_Conflict_Count(_In_ CONFLICT_LIST clConflictList,_Out_ PULONG pulCount)5591 CM_Get_Resource_Conflict_Count(
5592     _In_ CONFLICT_LIST clConflictList,
5593     _Out_ PULONG pulCount)
5594 {
5595     PCONFLICT_DATA pConflictData;
5596 
5597     FIXME("CM_Get_Resource_Conflict_Count(%p %p)\n",
5598           clConflictList, pulCount);
5599 
5600     pConflictData = (PCONFLICT_DATA)clConflictList;
5601     if (!IsValidConflictData(pConflictData))
5602         return CR_INVALID_CONFLICT_LIST;
5603 
5604     if (pulCount == NULL)
5605         return CR_INVALID_POINTER;
5606 
5607     *pulCount = pConflictData->pConflictList->ConflictsListed;
5608 
5609     return CR_SUCCESS;
5610 }
5611 
5612 
5613 /***********************************************************************
5614  * CM_Get_Resource_Conflict_DetailsA [SETUPAPI.@]
5615  */
5616 CONFIGRET
5617 WINAPI
CM_Get_Resource_Conflict_DetailsA(_In_ CONFLICT_LIST clConflictList,_In_ ULONG ulIndex,_Inout_ PCONFLICT_DETAILS_A pConflictDetails)5618 CM_Get_Resource_Conflict_DetailsA(
5619     _In_ CONFLICT_LIST clConflictList,
5620     _In_ ULONG ulIndex,
5621     _Inout_ PCONFLICT_DETAILS_A pConflictDetails)
5622 {
5623     FIXME("CM_Get_Resource_Conflict_CountA(%p %lu %p)\n",
5624           clConflictList, ulIndex, pConflictDetails);
5625 
5626     return CR_CALL_NOT_IMPLEMENTED;
5627 }
5628 
5629 
5630 /***********************************************************************
5631  * CM_Get_Resource_Conflict_DetailsW [SETUPAPI.@]
5632  */
5633 CONFIGRET
5634 WINAPI
CM_Get_Resource_Conflict_DetailsW(_In_ CONFLICT_LIST clConflictList,_In_ ULONG ulIndex,_Inout_ PCONFLICT_DETAILS_W pConflictDetails)5635 CM_Get_Resource_Conflict_DetailsW(
5636     _In_ CONFLICT_LIST clConflictList,
5637     _In_ ULONG ulIndex,
5638     _Inout_ PCONFLICT_DETAILS_W pConflictDetails)
5639 {
5640     FIXME("CM_Get_Resource_Conflict_CountW(%p %lu %p)\n",
5641           clConflictList, ulIndex, pConflictDetails);
5642 
5643     return CR_CALL_NOT_IMPLEMENTED;
5644 }
5645 
5646 
5647 /***********************************************************************
5648  * CM_Get_Sibling [SETUPAPI.@]
5649  */
5650 CONFIGRET
5651 WINAPI
CM_Get_Sibling(_Out_ PDEVINST pdnDevInst,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)5652 CM_Get_Sibling(
5653     _Out_ PDEVINST pdnDevInst,
5654     _In_ DEVINST dnDevInst,
5655     _In_ ULONG ulFlags)
5656 {
5657     TRACE("CM_Get_Sibling(%p %p %lx)\n",
5658           pdnDevInst, dnDevInst, ulFlags);
5659 
5660     return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
5661 }
5662 
5663 
5664 /***********************************************************************
5665  * CM_Get_Sibling_Ex [SETUPAPI.@]
5666  */
5667 CONFIGRET
5668 WINAPI
CM_Get_Sibling_Ex(_Out_ PDEVINST pdnDevInst,_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)5669 CM_Get_Sibling_Ex(
5670     _Out_ PDEVINST pdnDevInst,
5671     _In_ DEVINST dnDevInst,
5672     _In_ ULONG ulFlags,
5673     _In_opt_ HMACHINE hMachine)
5674 {
5675     WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
5676     RPC_BINDING_HANDLE BindingHandle = NULL;
5677     HSTRING_TABLE StringTable = NULL;
5678     LPWSTR lpDevInst;
5679     DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
5680     CONFIGRET ret;
5681 
5682     TRACE("CM_Get_Sibling_Ex(%p %lx %lx %p)\n",
5683           pdnDevInst, dnDevInst, ulFlags, hMachine);
5684 
5685     if (pdnDevInst == NULL)
5686         return CR_INVALID_POINTER;
5687 
5688     if (dnDevInst == 0)
5689         return CR_INVALID_DEVINST;
5690 
5691     if (ulFlags != 0)
5692         return CR_INVALID_FLAG;
5693 
5694     *pdnDevInst = -1;
5695 
5696     if (hMachine != NULL)
5697     {
5698         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5699         if (BindingHandle == NULL)
5700             return CR_FAILURE;
5701 
5702         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
5703         if (StringTable == 0)
5704             return CR_FAILURE;
5705     }
5706     else
5707     {
5708         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
5709             return CR_FAILURE;
5710     }
5711 
5712     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
5713     if (lpDevInst == NULL)
5714         return CR_INVALID_DEVNODE;
5715 
5716     RpcTryExcept
5717     {
5718         ret = PNP_GetRelatedDeviceInstance(BindingHandle,
5719                                            PNP_GET_SIBLING_DEVICE_INSTANCE,
5720                                            lpDevInst,
5721                                            szRelatedDevInst,
5722                                            &dwLength,
5723                                            0);
5724     }
5725     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5726     {
5727         ret = RpcStatusToCmStatus(RpcExceptionCode());
5728     }
5729     RpcEndExcept;
5730 
5731     if (ret != CR_SUCCESS)
5732         return ret;
5733 
5734     TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
5735 
5736     dwIndex = pSetupStringTableAddString(StringTable, szRelatedDevInst, 1);
5737     if (dwIndex == -1)
5738         return CR_FAILURE;
5739 
5740     *pdnDevInst = dwIndex;
5741 
5742     return CR_SUCCESS;
5743 }
5744 
5745 
5746 /***********************************************************************
5747  * CM_Get_Version [SETUPAPI.@]
5748  */
5749 WORD
5750 WINAPI
CM_Get_Version(VOID)5751 CM_Get_Version(VOID)
5752 {
5753     TRACE("CM_Get_Version()\n");
5754 
5755     return CM_Get_Version_Ex(NULL);
5756 }
5757 
5758 
5759 /***********************************************************************
5760  * CM_Get_Version_Ex [SETUPAPI.@]
5761  */
5762 WORD
5763 WINAPI
CM_Get_Version_Ex(_In_opt_ HMACHINE hMachine)5764 CM_Get_Version_Ex(
5765     _In_opt_ HMACHINE hMachine)
5766 {
5767     RPC_BINDING_HANDLE BindingHandle = NULL;
5768     WORD Version = 0;
5769     CONFIGRET ret;
5770 
5771     TRACE("CM_Get_Version_Ex(%p)\n", hMachine);
5772 
5773     if (hMachine != NULL)
5774     {
5775         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5776         if (BindingHandle == NULL)
5777             return 0;
5778     }
5779     else
5780     {
5781         if (!PnpGetLocalHandles(&BindingHandle, NULL))
5782             return CR_FAILURE;
5783     }
5784 
5785     RpcTryExcept
5786     {
5787         ret = PNP_GetVersion(BindingHandle, &Version);
5788     }
5789     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5790     {
5791         ret = RpcStatusToCmStatus(RpcExceptionCode());
5792     }
5793     RpcEndExcept;
5794 
5795     if (ret != CR_SUCCESS)
5796         return 0;
5797 
5798     return Version;
5799 }
5800 
5801 
5802 /***********************************************************************
5803  * CM_Intersect_Range_List [SETUPAPI.@]
5804  */
5805 CONFIGRET
5806 WINAPI
CM_Intersect_Range_List(_In_ RANGE_LIST rlhOld1,_In_ RANGE_LIST rlhOld2,_In_ RANGE_LIST rlhNew,_In_ ULONG ulFlags)5807 CM_Intersect_Range_List(
5808     _In_ RANGE_LIST rlhOld1,
5809     _In_ RANGE_LIST rlhOld2,
5810     _In_ RANGE_LIST rlhNew,
5811     _In_ ULONG ulFlags)
5812 {
5813     FIXME("CM_Intersect_Range_List(%p %p %p %lx)\n",
5814           rlhOld1, rlhOld2, rlhNew, ulFlags);
5815 
5816     return CR_CALL_NOT_IMPLEMENTED;
5817 }
5818 
5819 
5820 /***********************************************************************
5821  * CM_Invert_Range_List [SETUPAPI.@]
5822  */
5823 CONFIGRET
5824 WINAPI
CM_Invert_Range_List(_In_ RANGE_LIST rlhOld,_In_ RANGE_LIST rlhNew,_In_ DWORDLONG ullMaxValue,_In_ ULONG ulFlags)5825 CM_Invert_Range_List(
5826     _In_ RANGE_LIST rlhOld,
5827     _In_ RANGE_LIST rlhNew,
5828     _In_ DWORDLONG ullMaxValue,
5829     _In_ ULONG ulFlags)
5830 {
5831     FIXME("CM_Invert_Range_List(%p %p %I64u %lx)\n",
5832           rlhOld, rlhNew, ullMaxValue, ulFlags);
5833 
5834     return CR_CALL_NOT_IMPLEMENTED;
5835 }
5836 
5837 
5838 /***********************************************************************
5839  * CM_Is_Dock_Station_Present [SETUPAPI.@]
5840  */
5841 CONFIGRET
5842 WINAPI
CM_Is_Dock_Station_Present(_Out_ PBOOL pbPresent)5843 CM_Is_Dock_Station_Present(
5844     _Out_ PBOOL pbPresent)
5845 {
5846     TRACE("CM_Is_Dock_Station_Present(%p)\n",
5847           pbPresent);
5848 
5849     return CM_Is_Dock_Station_Present_Ex(pbPresent, NULL);
5850 }
5851 
5852 
5853 /***********************************************************************
5854  * CM_Is_Dock_Station_Present_Ex [SETUPAPI.@]
5855  */
5856 CONFIGRET
5857 WINAPI
CM_Is_Dock_Station_Present_Ex(_Out_ PBOOL pbPresent,_In_opt_ HMACHINE hMachine)5858 CM_Is_Dock_Station_Present_Ex(
5859     _Out_ PBOOL pbPresent,
5860     _In_opt_ HMACHINE hMachine)
5861 {
5862     RPC_BINDING_HANDLE BindingHandle = NULL;
5863     CONFIGRET ret;
5864 
5865     TRACE("CM_Is_Dock_Station_Present_Ex(%p %p)\n",
5866           pbPresent, hMachine);
5867 
5868     if (pbPresent == NULL)
5869         return CR_INVALID_POINTER;
5870 
5871     *pbPresent = FALSE;
5872 
5873     if (hMachine != NULL)
5874     {
5875         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5876         if (BindingHandle == NULL)
5877             return CR_FAILURE;
5878     }
5879     else
5880     {
5881         if (!PnpGetLocalHandles(&BindingHandle, NULL))
5882             return CR_FAILURE;
5883     }
5884 
5885     RpcTryExcept
5886     {
5887         ret = PNP_IsDockStationPresent(BindingHandle,
5888                                        pbPresent);
5889     }
5890     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5891     {
5892         ret = RpcStatusToCmStatus(RpcExceptionCode());
5893     }
5894     RpcEndExcept;
5895 
5896     return ret;
5897 }
5898 
5899 
5900 /***********************************************************************
5901  * CM_Is_Version_Available_Ex [SETUPAPI.@]
5902  */
5903 BOOL
5904 WINAPI
CM_Is_Version_Available(_In_ WORD wVersion)5905 CM_Is_Version_Available(
5906      _In_ WORD wVersion)
5907 {
5908     TRACE("CM_Is_Version_Available(%hu)\n",
5909           wVersion);
5910 
5911     return CM_Is_Version_Available_Ex(wVersion, NULL);
5912 }
5913 
5914 
5915 /***********************************************************************
5916  * CM_Is_Version_Available_Ex [SETUPAPI.@]
5917  */
5918 BOOL
5919 WINAPI
CM_Is_Version_Available_Ex(_In_ WORD wVersion,_In_opt_ HMACHINE hMachine)5920 CM_Is_Version_Available_Ex(
5921     _In_ WORD wVersion,
5922     _In_opt_ HMACHINE hMachine)
5923 {
5924     RPC_BINDING_HANDLE BindingHandle = NULL;
5925     WORD wServerVersion;
5926     CONFIGRET ret;
5927 
5928     TRACE("CM_Is_Version_Available_Ex(%hu %p)\n",
5929           wVersion, hMachine);
5930 
5931     if (wVersion <= 0x400)
5932         return TRUE;
5933 
5934     if (hMachine != NULL)
5935     {
5936         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
5937         if (BindingHandle == NULL)
5938             return FALSE;
5939     }
5940     else
5941     {
5942         if (!PnpGetLocalHandles(&BindingHandle, NULL))
5943             return FALSE;
5944     }
5945 
5946     RpcTryExcept
5947     {
5948         ret = PNP_GetVersion(BindingHandle, &wServerVersion);
5949     }
5950     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
5951     {
5952         ret = RpcStatusToCmStatus(RpcExceptionCode());
5953     }
5954     RpcEndExcept;
5955 
5956     if (ret != CR_SUCCESS)
5957         return FALSE;
5958 
5959     return (wServerVersion >= wVersion);
5960 }
5961 
5962 
5963 /***********************************************************************
5964  * CM_Locate_DevNodeA [SETUPAPI.@]
5965  */
5966 CONFIGRET
5967 WINAPI
CM_Locate_DevNodeA(_Out_ PDEVINST pdnDevInst,_In_opt_ DEVINSTID_A pDeviceID,_In_ ULONG ulFlags)5968 CM_Locate_DevNodeA(
5969     _Out_ PDEVINST pdnDevInst,
5970     _In_opt_ DEVINSTID_A pDeviceID,
5971     _In_ ULONG ulFlags)
5972 {
5973     TRACE("CM_Locate_DevNodeA(%p %s %lx)\n",
5974           pdnDevInst, debugstr_a(pDeviceID), ulFlags);
5975 
5976     return CM_Locate_DevNode_ExA(pdnDevInst, pDeviceID, ulFlags, NULL);
5977 }
5978 
5979 
5980 /***********************************************************************
5981  * CM_Locate_DevNodeW [SETUPAPI.@]
5982  */
5983 CONFIGRET
5984 WINAPI
CM_Locate_DevNodeW(_Out_ PDEVINST pdnDevInst,_In_opt_ DEVINSTID_W pDeviceID,_In_ ULONG ulFlags)5985 CM_Locate_DevNodeW(
5986     _Out_ PDEVINST pdnDevInst,
5987     _In_opt_ DEVINSTID_W pDeviceID,
5988     _In_ ULONG ulFlags)
5989 {
5990     TRACE("CM_Locate_DevNodeW(%p %s %lx)\n",
5991           pdnDevInst, debugstr_w(pDeviceID), ulFlags);
5992 
5993     return CM_Locate_DevNode_ExW(pdnDevInst, pDeviceID, ulFlags, NULL);
5994 }
5995 
5996 
5997 /***********************************************************************
5998  * CM_Locate_DevNode_ExA [SETUPAPI.@]
5999  */
6000 CONFIGRET
6001 WINAPI
CM_Locate_DevNode_ExA(_Out_ PDEVINST pdnDevInst,_In_opt_ DEVINSTID_A pDeviceID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6002 CM_Locate_DevNode_ExA(
6003     _Out_ PDEVINST pdnDevInst,
6004     _In_opt_ DEVINSTID_A pDeviceID,
6005     _In_ ULONG ulFlags,
6006     _In_opt_ HMACHINE hMachine)
6007 {
6008     DEVINSTID_W pDevIdW = NULL;
6009     CONFIGRET ret = CR_SUCCESS;
6010 
6011     TRACE("CM_Locate_DevNode_ExA(%p %s %lx %p)\n",
6012           pdnDevInst, debugstr_a(pDeviceID), ulFlags, hMachine);
6013 
6014     if (pDeviceID != NULL)
6015     {
6016        if (pSetupCaptureAndConvertAnsiArg(pDeviceID, &pDevIdW))
6017          return CR_INVALID_DEVICE_ID;
6018     }
6019 
6020     ret = CM_Locate_DevNode_ExW(pdnDevInst, pDevIdW, ulFlags, hMachine);
6021 
6022     if (pDevIdW != NULL)
6023         MyFree(pDevIdW);
6024 
6025     return ret;
6026 }
6027 
6028 
6029 /***********************************************************************
6030  * CM_Locate_DevNode_ExW [SETUPAPI.@]
6031  */
6032 CONFIGRET
6033 WINAPI
CM_Locate_DevNode_ExW(_Out_ PDEVINST pdnDevInst,_In_opt_ DEVINSTID_W pDeviceID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6034 CM_Locate_DevNode_ExW(
6035     _Out_ PDEVINST pdnDevInst,
6036     _In_opt_ DEVINSTID_W pDeviceID,
6037     _In_ ULONG ulFlags,
6038     _In_opt_ HMACHINE hMachine)
6039 {
6040     WCHAR DeviceIdBuffer[MAX_DEVICE_ID_LEN];
6041     RPC_BINDING_HANDLE BindingHandle = NULL;
6042     HSTRING_TABLE StringTable = NULL;
6043     CONFIGRET ret = CR_SUCCESS;
6044 
6045     TRACE("CM_Locate_DevNode_ExW(%p %s %lx %p)\n",
6046           pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine);
6047 
6048     if (pdnDevInst == NULL)
6049         return CR_INVALID_POINTER;
6050 
6051     if (ulFlags & ~CM_LOCATE_DEVNODE_BITS)
6052         return CR_INVALID_FLAG;
6053 
6054     if (hMachine != NULL)
6055     {
6056         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
6057         if (BindingHandle == NULL)
6058             return CR_FAILURE;
6059 
6060         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
6061         if (StringTable == 0)
6062             return CR_FAILURE;
6063     }
6064     else
6065     {
6066         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
6067             return CR_FAILURE;
6068     }
6069 
6070     if (pDeviceID != NULL && lstrlenW(pDeviceID) != 0)
6071     {
6072         lstrcpyW(DeviceIdBuffer, pDeviceID);
6073 
6074         RpcTryExcept
6075         {
6076             /* Validate the device ID */
6077             ret = PNP_ValidateDeviceInstance(BindingHandle,
6078                                              DeviceIdBuffer,
6079                                              ulFlags);
6080         }
6081         RpcExcept(EXCEPTION_EXECUTE_HANDLER)
6082         {
6083             ret = RpcStatusToCmStatus(RpcExceptionCode());
6084         }
6085         RpcEndExcept;
6086     }
6087     else
6088     {
6089         RpcTryExcept
6090         {
6091             /* Get the root device ID */
6092             ret = PNP_GetRootDeviceInstance(BindingHandle,
6093                                             DeviceIdBuffer,
6094                                             MAX_DEVICE_ID_LEN);
6095         }
6096         RpcExcept(EXCEPTION_EXECUTE_HANDLER)
6097         {
6098             ret = RpcStatusToCmStatus(RpcExceptionCode());
6099         }
6100         RpcEndExcept;
6101     }
6102 
6103     TRACE("DeviceIdBuffer: %s\n", debugstr_w(DeviceIdBuffer));
6104 
6105     if (ret == CR_SUCCESS)
6106     {
6107         *pdnDevInst = pSetupStringTableAddString(StringTable, DeviceIdBuffer, 1);
6108         if (*pdnDevInst == -1)
6109             ret = CR_FAILURE;
6110     }
6111 
6112     return ret;
6113 }
6114 
6115 
6116 /***********************************************************************
6117  * CM_Merge_Range_List [SETUPAPI.@]
6118  */
6119 CONFIGRET
6120 WINAPI
CM_Merge_Range_List(_In_ RANGE_LIST rlhOld1,_In_ RANGE_LIST rlhOld2,_In_ RANGE_LIST rlhNew,_In_ ULONG ulFlags)6121 CM_Merge_Range_List(
6122     _In_ RANGE_LIST rlhOld1,
6123     _In_ RANGE_LIST rlhOld2,
6124     _In_ RANGE_LIST rlhNew,
6125     _In_ ULONG ulFlags)
6126 {
6127     FIXME("CM_Merge_Range_List(%p %p %p %lx)\n",
6128           rlhOld1, rlhOld2, rlhNew, ulFlags);
6129 
6130     return CR_CALL_NOT_IMPLEMENTED;
6131 }
6132 
6133 
6134 /***********************************************************************
6135  * CM_Modify_Res_Des [SETUPAPI.@]
6136  */
6137 CONFIGRET
6138 WINAPI
CM_Modify_Res_Des(_Out_ PRES_DES prdResDes,_In_ RES_DES rdResDes,_In_ RESOURCEID ResourceID,_In_reads_bytes_ (ResourceLen)PCVOID ResourceData,_In_ ULONG ResourceLen,_In_ ULONG ulFlags)6139 CM_Modify_Res_Des(
6140     _Out_ PRES_DES prdResDes,
6141     _In_ RES_DES rdResDes,
6142     _In_ RESOURCEID ResourceID,
6143     _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
6144     _In_ ULONG ResourceLen,
6145     _In_ ULONG ulFlags)
6146 {
6147     TRACE("CM_Modify_Res_Des(%p %p %lx %p %lu %lx)\n",
6148           prdResDes, rdResDes, ResourceID, ResourceData,
6149           ResourceLen, ulFlags);
6150 
6151     return CM_Modify_Res_Des_Ex(prdResDes, rdResDes, ResourceID, ResourceData,
6152                                 ResourceLen, ulFlags, NULL);
6153 }
6154 
6155 
6156 /***********************************************************************
6157  * CM_Modify_Res_Des_Ex [SETUPAPI.@]
6158  */
6159 CONFIGRET
6160 WINAPI
CM_Modify_Res_Des_Ex(_Out_ PRES_DES prdResDes,_In_ RES_DES rdResDes,_In_ RESOURCEID ResourceID,_In_reads_bytes_ (ResourceLen)PCVOID ResourceData,_In_ ULONG ResourceLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6161 CM_Modify_Res_Des_Ex(
6162     _Out_ PRES_DES prdResDes,
6163     _In_ RES_DES rdResDes,
6164     _In_ RESOURCEID ResourceID,
6165     _In_reads_bytes_(ResourceLen) PCVOID ResourceData,
6166     _In_ ULONG ResourceLen,
6167     _In_ ULONG ulFlags,
6168     _In_opt_ HMACHINE hMachine)
6169 {
6170     FIXME("CM_Modify_Res_Des_Ex(%p %p %lx %p %lu %lx %p)\n",
6171           prdResDes, rdResDes, ResourceID, ResourceData,
6172           ResourceLen, ulFlags, hMachine);
6173 
6174     return CR_CALL_NOT_IMPLEMENTED;
6175 }
6176 
6177 
6178 /***********************************************************************
6179  * CM_Move_DevNode [SETUPAPI.@]
6180  */
6181 CONFIGRET
6182 WINAPI
CM_Move_DevNode(_In_ DEVINST dnFromDevInst,_In_ DEVINST dnToDevInst,_In_ ULONG ulFlags)6183 CM_Move_DevNode(
6184     _In_ DEVINST dnFromDevInst,
6185     _In_ DEVINST dnToDevInst,
6186     _In_ ULONG ulFlags)
6187 {
6188     TRACE("CM_Move_DevNode(%lx %lx %lx)\n",
6189           dnFromDevInst, dnToDevInst, ulFlags);
6190 
6191     return CM_Move_DevNode_Ex(dnFromDevInst, dnToDevInst, ulFlags, NULL);
6192 }
6193 
6194 
6195 /***********************************************************************
6196  * CM_Move_DevNode_Ex [SETUPAPI.@]
6197  */
6198 CONFIGRET
6199 WINAPI
CM_Move_DevNode_Ex(_In_ DEVINST dnFromDevInst,_In_ DEVINST dnToDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6200 CM_Move_DevNode_Ex(
6201     _In_ DEVINST dnFromDevInst,
6202     _In_ DEVINST dnToDevInst,
6203     _In_ ULONG ulFlags,
6204     _In_opt_ HMACHINE hMachine)
6205 {
6206     RPC_BINDING_HANDLE BindingHandle = NULL;
6207     HSTRING_TABLE StringTable = NULL;
6208     LPWSTR lpFromDevInst;
6209     LPWSTR lpToDevInst;
6210     CONFIGRET ret;
6211 
6212     FIXME("CM_Move_DevNode_Ex(%lx %lx %lx %p)\n",
6213           dnFromDevInst, dnToDevInst, ulFlags, hMachine);
6214 
6215     if (!pSetupIsUserAdmin())
6216         return CR_ACCESS_DENIED;
6217 
6218     if (dnFromDevInst == 0 || dnToDevInst == 0)
6219         return CR_INVALID_DEVNODE;
6220 
6221     if (ulFlags != 0)
6222         return CR_INVALID_FLAG;
6223 
6224     if (hMachine != NULL)
6225     {
6226         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
6227         if (BindingHandle == NULL)
6228             return CR_FAILURE;
6229 
6230         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
6231         if (StringTable == 0)
6232             return CR_FAILURE;
6233     }
6234     else
6235     {
6236         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
6237             return CR_FAILURE;
6238     }
6239 
6240     lpFromDevInst = pSetupStringTableStringFromId(StringTable, dnFromDevInst);
6241     if (lpFromDevInst == NULL)
6242         return CR_INVALID_DEVNODE;
6243 
6244     lpToDevInst = pSetupStringTableStringFromId(StringTable, dnToDevInst);
6245     if (lpToDevInst == NULL)
6246         return CR_INVALID_DEVNODE;
6247 
6248     RpcTryExcept
6249     {
6250         ret = PNP_DeviceInstanceAction(BindingHandle,
6251                                        PNP_DEVINST_MOVE,
6252                                        ulFlags,
6253                                        lpFromDevInst,
6254                                        lpToDevInst);
6255     }
6256     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
6257     {
6258         ret = RpcStatusToCmStatus(RpcExceptionCode());
6259     }
6260     RpcEndExcept;
6261 
6262     return ret;
6263 }
6264 
6265 
6266 /***********************************************************************
6267  * CM_Next_Range [SETUPAPI.@]
6268  */
6269 CONFIGRET
6270 WINAPI
CM_Next_Range(_Inout_ PRANGE_ELEMENT preElement,_Out_ PDWORDLONG pullStart,_Out_ PDWORDLONG pullEnd,_In_ ULONG ulFlags)6271 CM_Next_Range(
6272     _Inout_ PRANGE_ELEMENT preElement,
6273     _Out_ PDWORDLONG pullStart,
6274     _Out_ PDWORDLONG pullEnd,
6275     _In_ ULONG ulFlags)
6276 {
6277     PINTERNAL_RANGE_LIST pRangeList;
6278     PINTERNAL_RANGE pRange;
6279     PLIST_ENTRY ListEntry;
6280     CONFIGRET ret = CR_SUCCESS;
6281 
6282     FIXME("CM_Next_Range(%p %p %p %lx)\n",
6283           preElement, pullStart, pullEnd, ulFlags);
6284 
6285     pRange = (PINTERNAL_RANGE)preElement;
6286 
6287     if (pRange == NULL || pRange->pRangeList == NULL)
6288         return CR_FAILURE;
6289 
6290     if (pullStart == NULL || pullEnd == NULL)
6291         return CR_INVALID_POINTER;
6292 
6293     if (ulFlags != 0)
6294         return CR_INVALID_FLAG;
6295 
6296     pRangeList = pRange->pRangeList;
6297 
6298     /* Lock the range list */
6299     WaitForSingleObject(pRangeList->hMutex, INFINITE);
6300 
6301     /* Fail, if we reached the end of the list */
6302     if (pRange->ListEntry.Flink == &pRangeList->ListHead)
6303     {
6304         ret = CR_FAILURE;
6305         goto done;
6306     }
6307 
6308     /* Get the next range */
6309     ListEntry = pRangeList->ListHead.Flink;
6310     pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
6311 
6312     /* Return the range data */
6313     *pullStart = pRange->ullStart;
6314     *pullEnd = pRange->ullEnd;
6315     *preElement = (RANGE_ELEMENT)pRange;
6316 
6317 done:
6318     /* Unlock the range list */
6319     ReleaseMutex(pRangeList->hMutex);
6320 
6321     return ret;
6322 }
6323 
6324 
6325 /***********************************************************************
6326  * CM_Open_Class_KeyA [SETUPAPI.@]
6327  */
6328 CONFIGRET
6329 WINAPI
CM_Open_Class_KeyA(_In_opt_ LPGUID pClassGuid,_In_opt_ LPCSTR pszClassName,_In_ REGSAM samDesired,_In_ REGDISPOSITION Disposition,_Out_ PHKEY phkClass,_In_ ULONG ulFlags)6330 CM_Open_Class_KeyA(
6331     _In_opt_ LPGUID pClassGuid,
6332     _In_opt_ LPCSTR pszClassName,
6333     _In_ REGSAM samDesired,
6334     _In_ REGDISPOSITION Disposition,
6335     _Out_ PHKEY phkClass,
6336     _In_ ULONG ulFlags)
6337 {
6338     TRACE("CM_Open_Class_KeyA(%p %s %lx %lx %p %lx)\n",
6339           debugstr_guid(pClassGuid), debugstr_a(pszClassName),
6340           samDesired, Disposition, phkClass, ulFlags);
6341 
6342     return CM_Open_Class_Key_ExA(pClassGuid, pszClassName, samDesired,
6343                                  Disposition, phkClass, ulFlags, NULL);
6344 }
6345 
6346 
6347 /***********************************************************************
6348  * CM_Open_Class_KeyW [SETUPAPI.@]
6349  */
6350 CONFIGRET
6351 WINAPI
CM_Open_Class_KeyW(_In_opt_ LPGUID pClassGuid,_In_opt_ LPCWSTR pszClassName,_In_ REGSAM samDesired,_In_ REGDISPOSITION Disposition,_Out_ PHKEY phkClass,_In_ ULONG ulFlags)6352 CM_Open_Class_KeyW(
6353     _In_opt_ LPGUID pClassGuid,
6354     _In_opt_ LPCWSTR pszClassName,
6355     _In_ REGSAM samDesired,
6356     _In_ REGDISPOSITION Disposition,
6357     _Out_ PHKEY phkClass,
6358     _In_ ULONG ulFlags)
6359 {
6360     TRACE("CM_Open_Class_KeyW(%p %s %lx %lx %p %lx)\n",
6361           debugstr_guid(pClassGuid), debugstr_w(pszClassName),
6362           samDesired, Disposition, phkClass, ulFlags);
6363 
6364     return CM_Open_Class_Key_ExW(pClassGuid, pszClassName, samDesired,
6365                                  Disposition, phkClass, ulFlags, NULL);
6366 }
6367 
6368 
6369 /***********************************************************************
6370  * CM_Open_Class_Key_ExA [SETUPAPI.@]
6371  */
6372 CONFIGRET
6373 WINAPI
CM_Open_Class_Key_ExA(_In_opt_ LPGUID pClassGuid,_In_opt_ LPCSTR pszClassName,_In_ REGSAM samDesired,_In_ REGDISPOSITION Disposition,_Out_ PHKEY phkClass,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6374 CM_Open_Class_Key_ExA(
6375     _In_opt_ LPGUID pClassGuid,
6376     _In_opt_ LPCSTR pszClassName,
6377     _In_ REGSAM samDesired,
6378     _In_ REGDISPOSITION Disposition,
6379     _Out_ PHKEY phkClass,
6380     _In_ ULONG ulFlags,
6381     _In_opt_ HMACHINE hMachine)
6382 {
6383     LPWSTR pszClassNameW = NULL;
6384     CONFIGRET ret;
6385 
6386     TRACE("CM_Open_Class_Key_ExA(%p %s %lx %lx %p %lx %p)\n",
6387           debugstr_guid(pClassGuid), debugstr_a(pszClassName),
6388           samDesired, Disposition, phkClass, ulFlags, hMachine);
6389 
6390     if (pszClassName != NULL)
6391     {
6392        if (pSetupCaptureAndConvertAnsiArg(pszClassName, &pszClassNameW))
6393          return CR_INVALID_DATA;
6394     }
6395 
6396     ret = CM_Open_Class_Key_ExW(pClassGuid, pszClassNameW, samDesired,
6397                                 Disposition, phkClass, ulFlags, hMachine);
6398 
6399     if (pszClassNameW != NULL)
6400         MyFree(pszClassNameW);
6401 
6402     return ret;
6403 }
6404 
6405 
6406 /***********************************************************************
6407  * CM_Open_Class_Key_ExW [SETUPAPI.@]
6408  */
6409 CONFIGRET
6410 WINAPI
CM_Open_Class_Key_ExW(_In_opt_ LPGUID pClassGuid,_In_opt_ LPCWSTR pszClassName,_In_ REGSAM samDesired,_In_ REGDISPOSITION Disposition,_Out_ PHKEY phkClass,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6411 CM_Open_Class_Key_ExW(
6412     _In_opt_ LPGUID pClassGuid,
6413     _In_opt_ LPCWSTR pszClassName,
6414     _In_ REGSAM samDesired,
6415     _In_ REGDISPOSITION Disposition,
6416     _Out_ PHKEY phkClass,
6417     _In_ ULONG ulFlags,
6418     _In_opt_ HMACHINE hMachine)
6419 {
6420     WCHAR szKeyName[MAX_PATH];
6421     LPWSTR lpGuidString;
6422     DWORD dwDisposition;
6423     DWORD dwError;
6424     HKEY hKey;
6425 
6426     TRACE("CM_Open_Class_Key_ExW(%p %s %lx %lx %p %lx %p)\n",
6427           debugstr_guid(pClassGuid), debugstr_w(pszClassName),
6428           samDesired, Disposition, phkClass, ulFlags, hMachine);
6429 
6430     /* Check Disposition and ulFlags */
6431     if ((Disposition & ~RegDisposition_Bits) ||
6432         (ulFlags & ~CM_OPEN_CLASS_KEY_BITS))
6433         return CR_INVALID_FLAG;
6434 
6435     /* Check phkClass */
6436     if (phkClass == NULL)
6437         return CR_INVALID_POINTER;
6438 
6439     *phkClass = NULL;
6440 
6441     if (ulFlags == CM_OPEN_CLASS_KEY_INTERFACE &&
6442         pszClassName != NULL)
6443         return CR_INVALID_DATA;
6444 
6445     if (hMachine == NULL)
6446     {
6447         hKey = HKEY_LOCAL_MACHINE;
6448     }
6449     else
6450     {
6451         if (RegConnectRegistryW(((PMACHINE_INFO)hMachine)->szMachineName,
6452                                 HKEY_LOCAL_MACHINE,
6453                                 &hKey))
6454             return CR_REGISTRY_ERROR;
6455     }
6456 
6457     if (ulFlags & CM_OPEN_CLASS_KEY_INTERFACE)
6458     {
6459         lstrcpyW(szKeyName, DeviceClasses);
6460     }
6461     else
6462     {
6463         lstrcpyW(szKeyName, ControlClass);
6464     }
6465 
6466     if (pClassGuid != NULL)
6467     {
6468         if (UuidToStringW((UUID*)pClassGuid, &lpGuidString) != RPC_S_OK)
6469         {
6470             RegCloseKey(hKey);
6471             return CR_INVALID_DATA;
6472         }
6473 
6474         lstrcatW(szKeyName, BackslashOpenBrace);
6475         lstrcatW(szKeyName, lpGuidString);
6476         lstrcatW(szKeyName, CloseBrace);
6477     }
6478 
6479     if (Disposition == RegDisposition_OpenAlways)
6480     {
6481         dwError = RegCreateKeyExW(hKey, szKeyName, 0, NULL, 0, samDesired,
6482                                   NULL, phkClass, &dwDisposition);
6483     }
6484     else
6485     {
6486         dwError = RegOpenKeyExW(hKey, szKeyName, 0, samDesired, phkClass);
6487     }
6488 
6489     RegCloseKey(hKey);
6490 
6491     if (pClassGuid != NULL)
6492         RpcStringFreeW(&lpGuidString);
6493 
6494     if (dwError != ERROR_SUCCESS)
6495     {
6496         *phkClass = NULL;
6497         return CR_NO_SUCH_REGISTRY_KEY;
6498     }
6499 
6500     if (pszClassName != NULL)
6501     {
6502         RegSetValueExW(*phkClass, Class, 0, REG_SZ, (LPBYTE)pszClassName,
6503                        (lstrlenW(pszClassName) + 1) * sizeof(WCHAR));
6504     }
6505 
6506     return CR_SUCCESS;
6507 }
6508 
6509 
6510 /***********************************************************************
6511  * CM_Open_DevNode_Key [SETUPAPI.@]
6512  */
6513 CONFIGRET
6514 WINAPI
CM_Open_DevNode_Key(_In_ DEVINST dnDevNode,_In_ REGSAM samDesired,_In_ ULONG ulHardwareProfile,_In_ REGDISPOSITION Disposition,_Out_ PHKEY phkDevice,_In_ ULONG ulFlags)6515 CM_Open_DevNode_Key(
6516     _In_ DEVINST dnDevNode,
6517     _In_ REGSAM samDesired,
6518     _In_ ULONG ulHardwareProfile,
6519     _In_ REGDISPOSITION Disposition,
6520     _Out_ PHKEY phkDevice,
6521     _In_ ULONG ulFlags)
6522 {
6523     TRACE("CM_Open_DevNode_Key(%lx %lx %lu %lx %p %lx)\n",
6524           dnDevNode, samDesired, ulHardwareProfile, Disposition, phkDevice, ulFlags);
6525 
6526     return CM_Open_DevNode_Key_Ex(dnDevNode, samDesired, ulHardwareProfile,
6527                                   Disposition, phkDevice, ulFlags, NULL);
6528 }
6529 
6530 
6531 /***********************************************************************
6532  * CM_Open_DevNode_Key_Ex [SETUPAPI.@]
6533  */
6534 CONFIGRET
6535 WINAPI
CM_Open_DevNode_Key_Ex(_In_ DEVINST dnDevNode,_In_ REGSAM samDesired,_In_ ULONG ulHardwareProfile,_In_ REGDISPOSITION Disposition,_Out_ PHKEY phkDevice,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6536 CM_Open_DevNode_Key_Ex(
6537     _In_ DEVINST dnDevNode,
6538     _In_ REGSAM samDesired,
6539     _In_ ULONG ulHardwareProfile,
6540     _In_ REGDISPOSITION Disposition,
6541     _Out_ PHKEY phkDevice,
6542     _In_ ULONG ulFlags,
6543     _In_opt_ HMACHINE hMachine)
6544 {
6545     RPC_BINDING_HANDLE BindingHandle = NULL;
6546     HSTRING_TABLE StringTable = NULL;
6547     LPWSTR pszDevInst, pszKeyPath = NULL, pszInstancePath = NULL;
6548     LONG lError;
6549     DWORD dwDisposition;
6550     HKEY hRootKey = NULL;
6551     CONFIGRET ret = CR_CALL_NOT_IMPLEMENTED;
6552 
6553     TRACE("CM_Open_DevNode_Key_Ex(%lx %lx %lu %lx %p %lx %p)\n",
6554           dnDevNode, samDesired, ulHardwareProfile, Disposition, phkDevice, ulFlags, hMachine);
6555 
6556     if (phkDevice == NULL)
6557         return CR_INVALID_POINTER;
6558 
6559     *phkDevice = NULL;
6560 
6561     if (dnDevNode == 0)
6562         return CR_INVALID_DEVNODE;
6563 
6564     if (ulFlags & ~CM_REGISTRY_BITS)
6565         return CR_INVALID_FLAG;
6566 
6567     if (Disposition & ~RegDisposition_Bits)
6568         return CR_INVALID_DATA;
6569 
6570     if (hMachine != NULL)
6571     {
6572         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
6573         if (BindingHandle == NULL)
6574             return CR_FAILURE;
6575 
6576         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
6577         if (StringTable == 0)
6578             return CR_FAILURE;
6579     }
6580     else
6581     {
6582         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
6583             return CR_FAILURE;
6584     }
6585 
6586     pszDevInst = pSetupStringTableStringFromId(StringTable, dnDevNode);
6587     if (pszDevInst == NULL)
6588         return CR_INVALID_DEVNODE;
6589 
6590     TRACE("pszDevInst: %S\n", pszDevInst);
6591 
6592     pszKeyPath = MyMalloc(512 * sizeof(WCHAR));
6593     if (pszKeyPath == NULL)
6594     {
6595         ret = CR_OUT_OF_MEMORY;
6596         goto done;
6597     }
6598 
6599     pszInstancePath = MyMalloc(512 * sizeof(WCHAR));
6600     if (pszInstancePath == NULL)
6601     {
6602         ret = CR_OUT_OF_MEMORY;
6603         goto done;
6604     }
6605 
6606     ret = GetDeviceInstanceKeyPath(BindingHandle,
6607                                    pszDevInst,
6608                                    pszKeyPath,
6609                                    pszInstancePath,
6610                                    ulHardwareProfile,
6611                                    ulFlags);
6612     if (ret != CR_SUCCESS)
6613         goto done;
6614 
6615     TRACE("pszKeyPath: %S\n", pszKeyPath);
6616     TRACE("pszInstancePath: %S\n", pszInstancePath);
6617 
6618     wcscat(pszKeyPath, L"\\");
6619     wcscat(pszKeyPath, pszInstancePath);
6620 
6621     TRACE("pszKeyPath: %S\n", pszKeyPath);
6622 
6623     if (hMachine == NULL)
6624     {
6625         hRootKey = HKEY_LOCAL_MACHINE;
6626     }
6627     else
6628     {
6629         if (RegConnectRegistryW(((PMACHINE_INFO)hMachine)->szMachineName,
6630                                 HKEY_LOCAL_MACHINE,
6631                                 &hRootKey))
6632         {
6633             ret = CR_REGISTRY_ERROR;
6634             goto done;
6635         }
6636     }
6637 
6638     if (Disposition == RegDisposition_OpenAlways)
6639     {
6640         lError = RegCreateKeyExW(hRootKey,
6641                                  pszKeyPath,
6642                                  0,
6643                                  NULL,
6644                                  0,
6645                                  samDesired,
6646                                  NULL,
6647                                  phkDevice,
6648                                  &dwDisposition);
6649     }
6650     else
6651     {
6652         lError = RegOpenKeyExW(hRootKey,
6653                                pszKeyPath,
6654                                0,
6655                                samDesired,
6656                                phkDevice);
6657     }
6658 
6659     if (lError != ERROR_SUCCESS)
6660     {
6661         *phkDevice = NULL;
6662         ret = CR_NO_SUCH_REGISTRY_KEY;
6663     }
6664 
6665 done:
6666     if ((hRootKey != NULL) && (hRootKey != HKEY_LOCAL_MACHINE))
6667         RegCloseKey(hRootKey);
6668 
6669     if (pszInstancePath != NULL)
6670         MyFree(pszInstancePath);
6671 
6672     if (pszKeyPath != NULL)
6673         MyFree(pszKeyPath);
6674 
6675     return ret;
6676 }
6677 
6678 
6679 /***********************************************************************
6680  * CM_Query_And_Remove_SubTreeA [SETUPAPI.@]
6681  */
6682 CONFIGRET
6683 WINAPI
CM_Query_And_Remove_SubTreeA(_In_ DEVINST dnAncestor,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags)6684 CM_Query_And_Remove_SubTreeA(
6685     _In_ DEVINST dnAncestor,
6686     _Out_opt_ PPNP_VETO_TYPE pVetoType,
6687     _Out_writes_opt_(ulNameLength) LPSTR pszVetoName,
6688     _In_ ULONG ulNameLength,
6689     _In_ ULONG ulFlags)
6690 {
6691     TRACE("CM_Query_And_Remove_SubTreeA(%lx %p %p %lu %lx)\n",
6692           dnAncestor, pVetoType, pszVetoName, ulNameLength, ulFlags);
6693 
6694     return CM_Query_And_Remove_SubTree_ExA(dnAncestor, pVetoType, pszVetoName,
6695                                            ulNameLength, ulFlags, NULL);
6696 }
6697 
6698 
6699 /***********************************************************************
6700  * CM_Query_And_Remove_SubTreeW [SETUPAPI.@]
6701  */
6702 CONFIGRET
6703 WINAPI
CM_Query_And_Remove_SubTreeW(_In_ DEVINST dnAncestor,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPWSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags)6704 CM_Query_And_Remove_SubTreeW(
6705     _In_ DEVINST dnAncestor,
6706     _Out_opt_ PPNP_VETO_TYPE pVetoType,
6707     _Out_writes_opt_(ulNameLength) LPWSTR pszVetoName,
6708     _In_ ULONG ulNameLength,
6709     _In_ ULONG ulFlags)
6710 {
6711     TRACE("CM_Query_And_Remove_SubTreeW(%lx %p %p %lu %lx)\n",
6712           dnAncestor, pVetoType, pszVetoName, ulNameLength, ulFlags);
6713 
6714     return CM_Query_And_Remove_SubTree_ExW(dnAncestor, pVetoType, pszVetoName,
6715                                            ulNameLength, ulFlags, NULL);
6716 }
6717 
6718 
6719 /***********************************************************************
6720  * CM_Query_And_Remove_SubTree_ExA [SETUPAPI.@]
6721  */
6722 CONFIGRET
6723 WINAPI
CM_Query_And_Remove_SubTree_ExA(_In_ DEVINST dnAncestor,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6724 CM_Query_And_Remove_SubTree_ExA(
6725     _In_ DEVINST dnAncestor,
6726     _Out_opt_ PPNP_VETO_TYPE pVetoType,
6727     _Out_writes_opt_(ulNameLength) LPSTR pszVetoName,
6728     _In_ ULONG ulNameLength,
6729     _In_ ULONG ulFlags,
6730     _In_opt_ HMACHINE hMachine)
6731 {
6732     LPWSTR lpLocalVetoName;
6733     CONFIGRET ret;
6734 
6735     TRACE("CM_Query_And_Remove_SubTree_ExA(%lx %p %p %lu %lx %p)\n",
6736           dnAncestor, pVetoType, pszVetoName, ulNameLength,
6737           ulFlags, hMachine);
6738 
6739     if (pszVetoName == NULL && ulNameLength == 0)
6740         return CR_INVALID_POINTER;
6741 
6742     lpLocalVetoName = HeapAlloc(GetProcessHeap(), 0, ulNameLength * sizeof(WCHAR));
6743     if (lpLocalVetoName == NULL)
6744         return CR_OUT_OF_MEMORY;
6745 
6746     ret = CM_Query_And_Remove_SubTree_ExW(dnAncestor, pVetoType, lpLocalVetoName,
6747                                           ulNameLength, ulFlags, hMachine);
6748     if (ret == CR_REMOVE_VETOED)
6749     {
6750         if (WideCharToMultiByte(CP_ACP,
6751                                 0,
6752                                 lpLocalVetoName,
6753                                 ulNameLength,
6754                                 pszVetoName,
6755                                 ulNameLength,
6756                                 NULL,
6757                                 NULL) == 0)
6758             ret = CR_FAILURE;
6759     }
6760 
6761     HeapFree(GetProcessHeap(), 0, lpLocalVetoName);
6762 
6763     return ret;
6764 }
6765 
6766 
6767 /***********************************************************************
6768  * CM_Query_And_Remove_SubTree_ExW [SETUPAPI.@]
6769  */
6770 CONFIGRET
6771 WINAPI
CM_Query_And_Remove_SubTree_ExW(_In_ DEVINST dnAncestor,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPWSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6772 CM_Query_And_Remove_SubTree_ExW(
6773     _In_ DEVINST dnAncestor,
6774     _Out_opt_ PPNP_VETO_TYPE pVetoType,
6775     _Out_writes_opt_(ulNameLength) LPWSTR pszVetoName,
6776     _In_ ULONG ulNameLength,
6777     _In_ ULONG ulFlags,
6778     _In_opt_ HMACHINE hMachine)
6779 {
6780     RPC_BINDING_HANDLE BindingHandle = NULL;
6781     HSTRING_TABLE StringTable = NULL;
6782     LPWSTR lpDevInst;
6783     CONFIGRET ret;
6784 
6785     TRACE("CM_Query_And_Remove_SubTree_ExW(%lx %p %p %lu %lx %p)\n",
6786           dnAncestor, pVetoType, pszVetoName, ulNameLength,
6787           ulFlags, hMachine);
6788 
6789     if (dnAncestor == 0)
6790         return CR_INVALID_DEVNODE;
6791 
6792     if (ulFlags & ~CM_REMOVE_BITS)
6793         return CR_INVALID_FLAG;
6794 
6795     if (pszVetoName == NULL && ulNameLength == 0)
6796         return CR_INVALID_POINTER;
6797 
6798     if (hMachine != NULL)
6799     {
6800         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
6801         if (BindingHandle == NULL)
6802             return CR_FAILURE;
6803 
6804         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
6805         if (StringTable == 0)
6806             return CR_FAILURE;
6807     }
6808     else
6809     {
6810         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
6811             return CR_FAILURE;
6812     }
6813 
6814     lpDevInst = pSetupStringTableStringFromId(StringTable, dnAncestor);
6815     if (lpDevInst == NULL)
6816         return CR_INVALID_DEVNODE;
6817 
6818     RpcTryExcept
6819     {
6820         ret = PNP_QueryRemove(BindingHandle,
6821                               lpDevInst,
6822                               pVetoType,
6823                               pszVetoName,
6824                               ulNameLength,
6825                               ulFlags);
6826     }
6827     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
6828     {
6829         ret = RpcStatusToCmStatus(RpcExceptionCode());
6830     }
6831     RpcEndExcept;
6832 
6833     return ret;
6834 }
6835 
6836 
6837 /***********************************************************************
6838  * CM_Query_Arbitrator_Free_Data [SETUPAPI.@]
6839  */
6840 CONFIGRET
6841 WINAPI
CM_Query_Arbitrator_Free_Data(_Out_writes_bytes_ (DataLen)PVOID pData,_In_ ULONG DataLen,_In_ DEVINST dnDevInst,_In_ RESOURCEID ResourceID,_In_ ULONG ulFlags)6842 CM_Query_Arbitrator_Free_Data(
6843     _Out_writes_bytes_(DataLen) PVOID pData,
6844     _In_ ULONG DataLen,
6845     _In_ DEVINST dnDevInst,
6846     _In_ RESOURCEID ResourceID,
6847     _In_ ULONG ulFlags)
6848 {
6849     TRACE("CM_Query_Arbitrator_Free_Data(%p %lu %lx %lu 0x%08lx)\n",
6850           pData, DataLen, dnDevInst, ResourceID, ulFlags);
6851 
6852     return CM_Query_Arbitrator_Free_Data_Ex(pData, DataLen, dnDevInst,
6853                                             ResourceID, ulFlags, NULL);
6854 }
6855 
6856 
6857 /***********************************************************************
6858  * CM_Query_Arbitrator_Free_Data_Ex [SETUPAPI.@]
6859  */
6860 CONFIGRET
6861 WINAPI
CM_Query_Arbitrator_Free_Data_Ex(_Out_writes_bytes_ (DataLen)PVOID pData,_In_ ULONG DataLen,_In_ DEVINST dnDevInst,_In_ RESOURCEID ResourceID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6862 CM_Query_Arbitrator_Free_Data_Ex(
6863     _Out_writes_bytes_(DataLen) PVOID pData,
6864     _In_ ULONG DataLen,
6865     _In_ DEVINST dnDevInst,
6866     _In_ RESOURCEID ResourceID,
6867     _In_ ULONG ulFlags,
6868     _In_opt_ HMACHINE hMachine)
6869 {
6870     RPC_BINDING_HANDLE BindingHandle = NULL;
6871     HSTRING_TABLE StringTable = NULL;
6872     LPWSTR lpDevInst;
6873     CONFIGRET ret;
6874 
6875     TRACE("CM_Query_Arbitrator_Free_Data_Ex(%p %lu %lx %lu 0x%08lx %p)\n",
6876           pData, DataLen, dnDevInst, ResourceID, ulFlags, hMachine);
6877 
6878     if (pData == NULL || DataLen == 0)
6879         return CR_INVALID_POINTER;
6880 
6881     if (dnDevInst == 0)
6882         return CR_INVALID_DEVINST;
6883 
6884     if (ulFlags & ~CM_QUERY_ARBITRATOR_BITS)
6885         return CR_INVALID_FLAG;
6886 
6887     if (hMachine != NULL)
6888     {
6889         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
6890         if (BindingHandle == NULL)
6891             return CR_FAILURE;
6892 
6893         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
6894         if (StringTable == 0)
6895             return CR_FAILURE;
6896     }
6897     else
6898     {
6899         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
6900             return CR_FAILURE;
6901     }
6902 
6903     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
6904     if (lpDevInst == NULL)
6905         return CR_INVALID_DEVNODE;
6906 
6907     RpcTryExcept
6908     {
6909         ret = PNP_QueryArbitratorFreeData(BindingHandle,
6910                                           pData,
6911                                           DataLen,
6912                                           lpDevInst,
6913                                           ResourceID,
6914                                           ulFlags);
6915     }
6916     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
6917     {
6918         ret = RpcStatusToCmStatus(RpcExceptionCode());
6919     }
6920     RpcEndExcept;
6921 
6922     return ret;
6923 }
6924 
6925 
6926 /***********************************************************************
6927  * CM_Query_Arbitrator_Free_Size [SETUPAPI.@]
6928  */
6929 CONFIGRET
6930 WINAPI
CM_Query_Arbitrator_Free_Size(_Out_ PULONG pulSize,_In_ DEVINST dnDevInst,_In_ RESOURCEID ResourceID,_In_ ULONG ulFlags)6931 CM_Query_Arbitrator_Free_Size(
6932     _Out_ PULONG pulSize,
6933     _In_ DEVINST dnDevInst,
6934     _In_ RESOURCEID ResourceID,
6935     _In_ ULONG ulFlags)
6936 {
6937     TRACE("CM_Query_Arbitrator_Free_Size(%p %lu %lx 0x%08lx)\n",
6938           pulSize, dnDevInst,ResourceID, ulFlags);
6939 
6940     return CM_Query_Arbitrator_Free_Size_Ex(pulSize, dnDevInst, ResourceID,
6941                                             ulFlags, NULL);
6942 }
6943 
6944 
6945 /***********************************************************************
6946  * CM_Query_Arbitrator_Free_Size_Ex [SETUPAPI.@]
6947  */
6948 CONFIGRET
6949 WINAPI
CM_Query_Arbitrator_Free_Size_Ex(_Out_ PULONG pulSize,_In_ DEVINST dnDevInst,_In_ RESOURCEID ResourceID,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)6950 CM_Query_Arbitrator_Free_Size_Ex(
6951     _Out_ PULONG pulSize,
6952     _In_ DEVINST dnDevInst,
6953     _In_ RESOURCEID ResourceID,
6954     _In_ ULONG ulFlags,
6955     _In_opt_ HMACHINE hMachine)
6956 {
6957     RPC_BINDING_HANDLE BindingHandle = NULL;
6958     HSTRING_TABLE StringTable = NULL;
6959     LPWSTR lpDevInst;
6960     CONFIGRET ret;
6961 
6962     TRACE("CM_Query_Arbitrator_Free_Size_Ex(%p %lu %lx 0x%08lx %p)\n",
6963           pulSize, dnDevInst,ResourceID, ulFlags, hMachine);
6964 
6965     if (pulSize == NULL)
6966         return CR_INVALID_POINTER;
6967 
6968     if (dnDevInst == 0)
6969         return CR_INVALID_DEVINST;
6970 
6971     if (ulFlags & ~CM_QUERY_ARBITRATOR_BITS)
6972         return CR_INVALID_FLAG;
6973 
6974     if (hMachine != NULL)
6975     {
6976         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
6977         if (BindingHandle == NULL)
6978             return CR_FAILURE;
6979 
6980         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
6981         if (StringTable == 0)
6982             return CR_FAILURE;
6983     }
6984     else
6985     {
6986         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
6987             return CR_FAILURE;
6988     }
6989 
6990     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
6991     if (lpDevInst == NULL)
6992         return CR_INVALID_DEVNODE;
6993 
6994     RpcTryExcept
6995     {
6996         ret = PNP_QueryArbitratorFreeSize(BindingHandle,
6997                                           pulSize,
6998                                           lpDevInst,
6999                                           ResourceID,
7000                                           ulFlags);
7001     }
7002     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7003     {
7004         ret = RpcStatusToCmStatus(RpcExceptionCode());
7005     }
7006     RpcEndExcept;
7007 
7008     return ret;
7009 }
7010 
7011 
7012 /***********************************************************************
7013  * CM_Query_Remove_SubTree [SETUPAPI.@]
7014  *
7015  * This function is obsolete in Windows XP and above.
7016  */
7017 CONFIGRET
7018 WINAPI
CM_Query_Remove_SubTree(_In_ DEVINST dnAncestor,_In_ ULONG ulFlags)7019 CM_Query_Remove_SubTree(
7020     _In_ DEVINST dnAncestor,
7021     _In_ ULONG ulFlags)
7022 {
7023     TRACE("CM_Query_Remove_SubTree(%lx %lx)\n",
7024           dnAncestor, ulFlags);
7025 
7026     return CR_CALL_NOT_IMPLEMENTED;
7027 }
7028 
7029 
7030 /***********************************************************************
7031  * CM_Query_Remove_SubTree_Ex [SETUPAPI.@]
7032  *
7033  * This function is obsolete in Windows XP and above.
7034  */
7035 CONFIGRET
7036 WINAPI
CM_Query_Remove_SubTree_Ex(_In_ DEVINST dnAncestor,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7037 CM_Query_Remove_SubTree_Ex(
7038     _In_ DEVINST dnAncestor,
7039     _In_ ULONG ulFlags,
7040     _In_opt_ HMACHINE hMachine)
7041 {
7042     TRACE("CM_Query_Remove_SubTree_Ex(%lx %lx %p)\n",
7043           dnAncestor, ulFlags, hMachine);
7044 
7045     return CR_CALL_NOT_IMPLEMENTED;
7046 }
7047 
7048 
7049 /***********************************************************************
7050  * CM_Query_Resource_Conflict_List [SETUPAPI.@]
7051  */
7052 CONFIGRET
7053 WINAPI
CM_Query_Resource_Conflict_List(_Out_ PCONFLICT_LIST pclConflictList,_In_ DEVINST dnDevInst,_In_ RESOURCEID ResourceID,_In_ PCVOID ResourceData,_In_ ULONG ResourceLen,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7054 CM_Query_Resource_Conflict_List(
7055     _Out_ PCONFLICT_LIST pclConflictList,
7056     _In_ DEVINST dnDevInst,
7057     _In_ RESOURCEID ResourceID,
7058     _In_ PCVOID ResourceData,
7059     _In_ ULONG ResourceLen,
7060     _In_ ULONG ulFlags,
7061     _In_opt_ HMACHINE hMachine)
7062 {
7063     RPC_BINDING_HANDLE BindingHandle = NULL;
7064     HSTRING_TABLE StringTable = NULL;
7065     PPNP_CONFLICT_LIST pConflictBuffer = NULL;
7066     PCONFLICT_DATA pConflictData = NULL;
7067     ULONG ulBufferLength;
7068     LPWSTR lpDevInst;
7069     CONFIGRET ret;
7070 
7071     FIXME("CM_Query_Resource_Conflict_List(%p %lx %lu %p %lu %lx %p)\n",
7072           pclConflictList, dnDevInst, ResourceID, ResourceData,
7073           ResourceLen, ulFlags, hMachine);
7074 
7075     if (dnDevInst == 0)
7076         return CR_INVALID_DEVNODE;
7077 
7078     if (ulFlags & ~CM_RESDES_WIDTH_BITS)
7079         return CR_INVALID_FLAG;
7080 
7081     if (pclConflictList == NULL ||
7082         ResourceData == NULL ||
7083         ResourceLen == 0)
7084         return CR_INVALID_POINTER;
7085 
7086     if (ResourceID == 0)
7087         return CR_INVALID_RESOURCEID;
7088 
7089     *pclConflictList = 0;
7090 
7091     if (hMachine != NULL)
7092     {
7093         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7094         if (BindingHandle == NULL)
7095             return CR_FAILURE;
7096 
7097         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
7098         if (StringTable == 0)
7099             return CR_FAILURE;
7100     }
7101     else
7102     {
7103         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
7104             return CR_FAILURE;
7105     }
7106 
7107     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
7108     if (lpDevInst == NULL)
7109         return CR_INVALID_DEVNODE;
7110 
7111     pConflictData = MyMalloc(sizeof(CONFLICT_DATA));
7112     if (pConflictData == NULL)
7113     {
7114         ret = CR_OUT_OF_MEMORY;
7115         goto done;
7116     }
7117 
7118     ulBufferLength = sizeof(PNP_CONFLICT_LIST) +
7119                      sizeof(PNP_CONFLICT_STRINGS) +
7120                      (sizeof(wchar_t) * 200);
7121     pConflictBuffer = MyMalloc(ulBufferLength);
7122     if (pConflictBuffer == NULL)
7123     {
7124         ret = CR_OUT_OF_MEMORY;
7125         goto done;
7126     }
7127 
7128     RpcTryExcept
7129     {
7130         ret = PNP_QueryResConfList(BindingHandle,
7131                                    lpDevInst,
7132                                    ResourceID,
7133                                    (PBYTE)ResourceData,
7134                                    ResourceLen,
7135                                    (PBYTE)pConflictBuffer,
7136                                    ulBufferLength,
7137                                    ulFlags);
7138     }
7139     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7140     {
7141         ret = RpcStatusToCmStatus(RpcExceptionCode());
7142     }
7143     RpcEndExcept;
7144 
7145     if (ret != CR_SUCCESS)
7146         goto done;
7147 
7148     pConflictData->ulMagic = CONFLICT_MAGIC;
7149     pConflictData->pConflictList = pConflictBuffer;
7150 
7151     *pclConflictList = (CONFLICT_LIST)pConflictData;
7152 
7153 done:
7154     if (ret != CR_SUCCESS)
7155     {
7156         if (pConflictBuffer != NULL)
7157             MyFree(pConflictBuffer);
7158 
7159         if (pConflictData != NULL)
7160             MyFree(pConflictData);
7161     }
7162 
7163     return ret;
7164 }
7165 
7166 
7167 /***********************************************************************
7168  * CM_Reenumerate_DevNode [SETUPAPI.@]
7169  */
7170 CONFIGRET
7171 WINAPI
CM_Reenumerate_DevNode(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)7172 CM_Reenumerate_DevNode(
7173     _In_ DEVINST dnDevInst,
7174     _In_ ULONG ulFlags)
7175 {
7176     TRACE("CM_Reenumerate_DevNode(%lx %lx)\n",
7177           dnDevInst, ulFlags);
7178 
7179     return CM_Reenumerate_DevNode_Ex(dnDevInst, ulFlags, NULL);
7180 }
7181 
7182 
7183 /***********************************************************************
7184  * CM_Reenumerate_DevNode_Ex [SETUPAPI.@]
7185  */
7186 CONFIGRET WINAPI
CM_Reenumerate_DevNode_Ex(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7187 CM_Reenumerate_DevNode_Ex(
7188     _In_ DEVINST dnDevInst,
7189     _In_ ULONG ulFlags,
7190     _In_opt_ HMACHINE hMachine)
7191 {
7192     RPC_BINDING_HANDLE BindingHandle = NULL;
7193     HSTRING_TABLE StringTable = NULL;
7194     LPWSTR lpDevInst;
7195     CONFIGRET ret;
7196 
7197     FIXME("CM_Reenumerate_DevNode_Ex(%lx %lx %p)\n",
7198           dnDevInst, ulFlags, hMachine);
7199 
7200     if (dnDevInst == 0)
7201         return CR_INVALID_DEVNODE;
7202 
7203     if (ulFlags & ~CM_REENUMERATE_BITS)
7204         return CR_INVALID_FLAG;
7205 
7206     if (hMachine != NULL)
7207     {
7208         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7209         if (BindingHandle == NULL)
7210             return CR_FAILURE;
7211 
7212         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
7213         if (StringTable == 0)
7214             return CR_FAILURE;
7215     }
7216     else
7217     {
7218         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
7219             return CR_FAILURE;
7220     }
7221 
7222     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
7223     if (lpDevInst == NULL)
7224         return CR_INVALID_DEVNODE;
7225 
7226     RpcTryExcept
7227     {
7228         ret = PNP_DeviceInstanceAction(BindingHandle,
7229                                        PNP_DEVINST_REENUMERATE,
7230                                        ulFlags,
7231                                        lpDevInst,
7232                                        NULL);
7233     }
7234     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7235     {
7236         ret = RpcStatusToCmStatus(RpcExceptionCode());
7237     }
7238     RpcEndExcept;
7239 
7240     return ret;
7241 }
7242 
7243 
7244 /***********************************************************************
7245  * CM_Register_Device_Driver [SETUPAPI.@]
7246  */
7247 CONFIGRET
7248 WINAPI
CM_Register_Device_Driver(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)7249 CM_Register_Device_Driver(
7250     _In_ DEVINST dnDevInst,
7251     _In_ ULONG ulFlags)
7252 {
7253     TRACE("CM_Register_Device_Driver(%lx 0x%08lx)\n",
7254           dnDevInst, ulFlags);
7255 
7256     return CM_Register_Device_Driver_Ex(dnDevInst, ulFlags, NULL);
7257 }
7258 
7259 
7260 /***********************************************************************
7261  * CM_Register_Device_Driver_Ex [SETUPAPI.@]
7262  */
7263 CONFIGRET
7264 WINAPI
CM_Register_Device_Driver_Ex(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7265 CM_Register_Device_Driver_Ex(
7266     _In_ DEVINST dnDevInst,
7267     _In_ ULONG ulFlags,
7268     _In_opt_ HMACHINE hMachine)
7269 {
7270     RPC_BINDING_HANDLE BindingHandle = NULL;
7271     HSTRING_TABLE StringTable = NULL;
7272     LPWSTR lpDevInst;
7273     CONFIGRET ret;
7274 
7275     TRACE("CM_Register_Device_Driver_Ex(%lx 0x%08lx %p)\n",
7276           dnDevInst, ulFlags, hMachine);
7277 
7278     if (dnDevInst == 0)
7279         return CR_INVALID_DEVNODE;
7280 
7281     if (ulFlags & ~CM_REGISTER_DEVICE_DRIVER_BITS)
7282         return CR_INVALID_FLAG;
7283 
7284     if (hMachine != NULL)
7285     {
7286         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7287         if (BindingHandle == NULL)
7288             return CR_FAILURE;
7289 
7290         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
7291         if (StringTable == 0)
7292             return CR_FAILURE;
7293     }
7294     else
7295     {
7296         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
7297             return CR_FAILURE;
7298     }
7299 
7300     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
7301     if (lpDevInst == NULL)
7302         return CR_INVALID_DEVNODE;
7303 
7304     RpcTryExcept
7305     {
7306         ret = PNP_RegisterDriver(BindingHandle,
7307                                  lpDevInst,
7308                                  ulFlags);
7309     }
7310     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7311     {
7312         ret = RpcStatusToCmStatus(RpcExceptionCode());
7313     }
7314     RpcEndExcept;
7315 
7316     return ret;
7317 }
7318 
7319 
7320 /***********************************************************************
7321  * CM_Register_Device_InterfaceA [SETUPAPI.@]
7322  */
7323 CONFIGRET
7324 WINAPI
CM_Register_Device_InterfaceA(_In_ DEVINST dnDevInst,_In_ LPGUID InterfaceClassGuid,_In_opt_ LPCSTR pszReference,_Out_writes_ (* pulLength)LPSTR pszDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)7325 CM_Register_Device_InterfaceA(
7326     _In_ DEVINST dnDevInst,
7327     _In_ LPGUID InterfaceClassGuid,
7328     _In_opt_ LPCSTR pszReference,
7329     _Out_writes_(*pulLength) LPSTR pszDeviceInterface,
7330     _Inout_ PULONG pulLength,
7331     _In_ ULONG ulFlags)
7332 {
7333     TRACE("CM_Register_Device_InterfaceA(%lx %s %s %p %p %lx)\n",
7334           dnDevInst, debugstr_guid(InterfaceClassGuid),
7335           pszReference, pszDeviceInterface, pulLength, ulFlags);
7336 
7337     return CM_Register_Device_Interface_ExA(dnDevInst, InterfaceClassGuid,
7338                                             pszReference, pszDeviceInterface,
7339                                             pulLength, ulFlags, NULL);
7340 }
7341 
7342 
7343 /***********************************************************************
7344  * CM_Register_Device_InterfaceW [SETUPAPI.@]
7345  */
7346 CONFIGRET
7347 WINAPI
CM_Register_Device_InterfaceW(_In_ DEVINST dnDevInst,_In_ LPGUID InterfaceClassGuid,_In_opt_ LPCWSTR pszReference,_Out_writes_ (* pulLength)LPWSTR pszDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags)7348 CM_Register_Device_InterfaceW(
7349     _In_ DEVINST dnDevInst,
7350     _In_ LPGUID InterfaceClassGuid,
7351     _In_opt_ LPCWSTR pszReference,
7352     _Out_writes_(*pulLength) LPWSTR pszDeviceInterface,
7353     _Inout_ PULONG pulLength,
7354     _In_ ULONG ulFlags)
7355 {
7356     TRACE("CM_Register_Device_InterfaceW(%lx %s %s %p %p %lx)\n",
7357           dnDevInst, debugstr_guid(InterfaceClassGuid),
7358           debugstr_w(pszReference), pszDeviceInterface, pulLength, ulFlags);
7359 
7360     return CM_Register_Device_Interface_ExW(dnDevInst, InterfaceClassGuid,
7361                                             pszReference, pszDeviceInterface,
7362                                             pulLength, ulFlags, NULL);
7363 }
7364 
7365 
7366 /***********************************************************************
7367  * CM_Register_Device_Interface_ExA [SETUPAPI.@]
7368  */
7369 CONFIGRET
7370 WINAPI
CM_Register_Device_Interface_ExA(_In_ DEVINST dnDevInst,_In_ LPGUID InterfaceClassGuid,_In_opt_ LPCSTR pszReference,_Out_writes_ (* pulLength)LPSTR pszDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7371 CM_Register_Device_Interface_ExA(
7372     _In_ DEVINST dnDevInst,
7373     _In_ LPGUID InterfaceClassGuid,
7374     _In_opt_ LPCSTR pszReference,
7375     _Out_writes_(*pulLength) LPSTR pszDeviceInterface,
7376     _Inout_ PULONG pulLength,
7377     _In_ ULONG ulFlags,
7378     _In_opt_ HMACHINE hMachine)
7379 {
7380     LPWSTR pszReferenceW = NULL;
7381     LPWSTR pszDeviceInterfaceW;
7382     ULONG ulLength;
7383     CONFIGRET ret;
7384 
7385     TRACE("CM_Register_Device_Interface_ExA(%lx %s %s %p %p %lx %p)\n",
7386           dnDevInst, debugstr_guid(InterfaceClassGuid), debugstr_a(pszReference),
7387           pszDeviceInterface, pulLength, ulFlags, hMachine);
7388 
7389     if (pulLength == NULL || pszDeviceInterface == NULL)
7390         return CR_INVALID_POINTER;
7391 
7392     if (pszReference != NULL)
7393     {
7394         if (pSetupCaptureAndConvertAnsiArg(pszReference, &pszReferenceW))
7395             return CR_INVALID_DATA;
7396     }
7397 
7398     ulLength = *pulLength;
7399 
7400     pszDeviceInterfaceW = HeapAlloc(GetProcessHeap(), 0, ulLength * sizeof(WCHAR));
7401     if (pszDeviceInterfaceW == NULL)
7402     {
7403         ret = CR_OUT_OF_MEMORY;
7404         goto Done;
7405     }
7406 
7407     ret = CM_Register_Device_Interface_ExW(dnDevInst,
7408                                            InterfaceClassGuid,
7409                                            pszReferenceW,
7410                                            pszDeviceInterfaceW,
7411                                            &ulLength,
7412                                            ulFlags,
7413                                            hMachine);
7414     if (ret == CR_SUCCESS)
7415     {
7416         if (WideCharToMultiByte(CP_ACP,
7417                                 0,
7418                                 pszDeviceInterfaceW,
7419                                 ulLength,
7420                                 pszDeviceInterface,
7421                                 *pulLength,
7422                                 NULL,
7423                                 NULL) == 0)
7424             ret = CR_FAILURE;
7425     }
7426 
7427     *pulLength = ulLength;
7428 
7429 Done:
7430     if (pszDeviceInterfaceW != NULL)
7431         HeapFree(GetProcessHeap(), 0, pszDeviceInterfaceW);
7432 
7433     if (pszReferenceW != NULL)
7434         MyFree(pszReferenceW);
7435 
7436     return ret;
7437 }
7438 
7439 
7440 /***********************************************************************
7441  * CM_Register_Device_Interface_ExW [SETUPAPI.@]
7442  */
7443 CONFIGRET
7444 WINAPI
CM_Register_Device_Interface_ExW(_In_ DEVINST dnDevInst,_In_ LPGUID InterfaceClassGuid,_In_opt_ LPCWSTR pszReference,_Out_writes_ (* pulLength)LPWSTR pszDeviceInterface,_Inout_ PULONG pulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7445 CM_Register_Device_Interface_ExW(
7446     _In_ DEVINST dnDevInst,
7447     _In_ LPGUID InterfaceClassGuid,
7448     _In_opt_ LPCWSTR pszReference,
7449     _Out_writes_(*pulLength) LPWSTR pszDeviceInterface,
7450     _Inout_ PULONG pulLength,
7451     _In_ ULONG ulFlags,
7452     _In_opt_ HMACHINE hMachine)
7453 {
7454     RPC_BINDING_HANDLE BindingHandle = NULL;
7455     HSTRING_TABLE StringTable = NULL;
7456     LPWSTR lpDevInst;
7457     ULONG ulTransferLength;
7458     CONFIGRET ret;
7459 
7460     TRACE("CM_Register_Device_Interface_ExW(%lx %s %s %p %p %lx %p)\n",
7461           dnDevInst, debugstr_guid(InterfaceClassGuid), debugstr_w(pszReference),
7462           pszDeviceInterface, pulLength, ulFlags, hMachine);
7463 
7464     if (dnDevInst == 0)
7465         return CR_INVALID_DEVNODE;
7466 
7467     if (InterfaceClassGuid == NULL ||
7468         pszDeviceInterface == NULL ||
7469         pulLength == NULL)
7470         return CR_INVALID_POINTER;
7471 
7472     if (ulFlags != 0)
7473         return CR_INVALID_FLAG;
7474 
7475     if (hMachine != NULL)
7476     {
7477         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7478         if (BindingHandle == NULL)
7479             return CR_FAILURE;
7480 
7481         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
7482         if (StringTable == 0)
7483             return CR_FAILURE;
7484     }
7485     else
7486     {
7487         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
7488             return CR_FAILURE;
7489     }
7490 
7491     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
7492     if (lpDevInst == NULL)
7493         return CR_INVALID_DEVNODE;
7494 
7495     ulTransferLength = *pulLength;
7496 
7497     RpcTryExcept
7498     {
7499         ret = PNP_RegisterDeviceClassAssociation(BindingHandle,
7500                                                  lpDevInst,
7501                                                  InterfaceClassGuid,
7502                                                  (LPWSTR)pszReference,
7503                                                  pszDeviceInterface,
7504                                                  pulLength,
7505                                                  &ulTransferLength,
7506                                                  0);
7507     }
7508     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7509     {
7510         ret = RpcStatusToCmStatus(RpcExceptionCode());
7511     }
7512     RpcEndExcept;
7513 
7514     return ret;
7515 }
7516 
7517 
7518 /***********************************************************************
7519  * CM_Remove_SubTree [SETUPAPI.@]
7520  *
7521  * This function is obsolete in Windows XP and above.
7522  */
7523 CONFIGRET
7524 WINAPI
CM_Remove_SubTree(_In_ DEVINST dnAncestor,_In_ ULONG ulFlags)7525 CM_Remove_SubTree(
7526     _In_ DEVINST dnAncestor,
7527     _In_ ULONG ulFlags)
7528 {
7529     TRACE("CM_Remove_SubTree(%lx %lx)\n",
7530           dnAncestor, ulFlags);
7531 
7532     return CR_CALL_NOT_IMPLEMENTED;
7533 }
7534 
7535 
7536 /***********************************************************************
7537  * CM_Remove_SubTree_Ex [SETUPAPI.@]
7538  *
7539  * This function is obsolete in Windows XP and above.
7540  */
7541 CONFIGRET
7542 WINAPI
CM_Remove_SubTree_Ex(_In_ DEVINST dnAncestor,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7543 CM_Remove_SubTree_Ex(
7544     _In_ DEVINST dnAncestor,
7545     _In_ ULONG ulFlags,
7546     _In_opt_ HMACHINE hMachine)
7547 {
7548     TRACE("CM_Remove_SubTree_Ex(%lx %lx %p)\n",
7549           dnAncestor, ulFlags, hMachine);
7550 
7551     return CR_CALL_NOT_IMPLEMENTED;
7552 }
7553 
7554 
7555 /***********************************************************************
7556  * CM_Request_Device_EjectA [SETUPAPI.@]
7557  */
7558 CONFIGRET
7559 WINAPI
CM_Request_Device_EjectA(_In_ DEVINST dnDevInst,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags)7560 CM_Request_Device_EjectA(
7561     _In_ DEVINST dnDevInst,
7562     _Out_opt_ PPNP_VETO_TYPE pVetoType,
7563     _Out_writes_opt_(ulNameLength) LPSTR pszVetoName,
7564     _In_ ULONG ulNameLength,
7565     _In_ ULONG ulFlags)
7566 {
7567     TRACE("CM_Request_Device_EjectA(%lx %p %p %lu %lx)\n",
7568           dnDevInst, pVetoType, pszVetoName, ulNameLength, ulFlags);
7569 
7570     return CM_Request_Device_Eject_ExA(dnDevInst, pVetoType, pszVetoName,
7571                                        ulNameLength, ulFlags, NULL);
7572 }
7573 
7574 
7575 /***********************************************************************
7576  * CM_Request_Device_EjectW [SETUPAPI.@]
7577  */
7578 CONFIGRET
7579 WINAPI
CM_Request_Device_EjectW(_In_ DEVINST dnDevInst,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPWSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags)7580 CM_Request_Device_EjectW(
7581     _In_ DEVINST dnDevInst,
7582     _Out_opt_ PPNP_VETO_TYPE pVetoType,
7583     _Out_writes_opt_(ulNameLength) LPWSTR pszVetoName,
7584     _In_ ULONG ulNameLength,
7585     _In_ ULONG ulFlags)
7586 {
7587     TRACE("CM_Request_Device_EjectW(%lx %p %p %lu %lx)\n",
7588           dnDevInst, pVetoType, pszVetoName, ulNameLength, ulFlags);
7589 
7590     return CM_Request_Device_Eject_ExW(dnDevInst, pVetoType, pszVetoName,
7591                                        ulNameLength, ulFlags, NULL);
7592 }
7593 
7594 
7595 /***********************************************************************
7596  * CM_Request_Device_Eject_ExA [SETUPAPI.@]
7597  */
7598 CONFIGRET
7599 WINAPI
CM_Request_Device_Eject_ExA(_In_ DEVINST dnDevInst,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7600 CM_Request_Device_Eject_ExA(
7601     _In_ DEVINST dnDevInst,
7602     _Out_opt_ PPNP_VETO_TYPE pVetoType,
7603     _Out_writes_opt_(ulNameLength) LPSTR pszVetoName,
7604     _In_ ULONG ulNameLength,
7605     _In_ ULONG ulFlags,
7606     _In_opt_ HMACHINE hMachine)
7607 {
7608     LPWSTR lpLocalVetoName = NULL;
7609     CONFIGRET ret;
7610 
7611     TRACE("CM_Request_Device_Eject_ExA(%lx %p %p %lu %lx %p)\n",
7612           dnDevInst, pVetoType, pszVetoName, ulNameLength, ulFlags, hMachine);
7613 
7614     if (ulNameLength != 0)
7615     {
7616         if (pszVetoName == NULL)
7617             return CR_INVALID_POINTER;
7618 
7619         lpLocalVetoName = HeapAlloc(GetProcessHeap(), 0, ulNameLength * sizeof(WCHAR));
7620         if (lpLocalVetoName == NULL)
7621             return CR_OUT_OF_MEMORY;
7622     }
7623 
7624     ret = CM_Request_Device_Eject_ExW(dnDevInst, pVetoType, lpLocalVetoName,
7625                                       ulNameLength, ulFlags, hMachine);
7626     if (ret == CR_REMOVE_VETOED && ulNameLength != 0)
7627     {
7628         if (WideCharToMultiByte(CP_ACP,
7629                                 0,
7630                                 lpLocalVetoName,
7631                                 ulNameLength,
7632                                 pszVetoName,
7633                                 ulNameLength,
7634                                 NULL,
7635                                 NULL) == 0)
7636             ret = CR_FAILURE;
7637     }
7638 
7639     HeapFree(GetProcessHeap(), 0, lpLocalVetoName);
7640 
7641     return ret;
7642 }
7643 
7644 
7645 /***********************************************************************
7646  * CM_Request_Device_Eject_ExW [SETUPAPI.@]
7647  */
7648 CONFIGRET
7649 WINAPI
CM_Request_Device_Eject_ExW(_In_ DEVINST dnDevInst,_Out_opt_ PPNP_VETO_TYPE pVetoType,_Out_writes_opt_ (ulNameLength)LPWSTR pszVetoName,_In_ ULONG ulNameLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7650 CM_Request_Device_Eject_ExW(
7651     _In_ DEVINST dnDevInst,
7652     _Out_opt_ PPNP_VETO_TYPE pVetoType,
7653     _Out_writes_opt_(ulNameLength) LPWSTR pszVetoName,
7654     _In_ ULONG ulNameLength,
7655     _In_ ULONG ulFlags,
7656     _In_opt_ HMACHINE hMachine)
7657 {
7658     RPC_BINDING_HANDLE BindingHandle = NULL;
7659     HSTRING_TABLE StringTable = NULL;
7660     LPWSTR lpDevInst;
7661     CONFIGRET ret;
7662 
7663     TRACE("CM_Request_Device_Eject_ExW(%lx %p %p %lu %lx %p)\n",
7664           dnDevInst, pVetoType, pszVetoName, ulNameLength, ulFlags, hMachine);
7665 
7666     if (dnDevInst == 0)
7667         return CR_INVALID_DEVNODE;
7668 
7669     if (ulFlags != 0)
7670         return CR_INVALID_FLAG;
7671 
7672     if (pszVetoName == NULL && ulNameLength != 0)
7673         return CR_INVALID_POINTER;
7674 
7675     /* Windows 2003 SP2 ignores pszVetoName when ulNameLength is zero
7676      * and behaves like when pszVetoName is NULL */
7677     if (ulNameLength == 0)
7678         pszVetoName = NULL;
7679 
7680     if (hMachine != NULL)
7681     {
7682         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7683         if (BindingHandle == NULL)
7684             return CR_FAILURE;
7685 
7686         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
7687         if (StringTable == 0)
7688             return CR_FAILURE;
7689     }
7690     else
7691     {
7692         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
7693             return CR_FAILURE;
7694     }
7695 
7696     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
7697     if (lpDevInst == NULL)
7698         return CR_INVALID_DEVNODE;
7699 
7700     RpcTryExcept
7701     {
7702         ret = PNP_RequestDeviceEject(BindingHandle,
7703                                      lpDevInst,
7704                                      pVetoType,
7705                                      pszVetoName,
7706                                      ulNameLength,
7707                                      ulFlags);
7708     }
7709     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7710     {
7711         ret = RpcStatusToCmStatus(RpcExceptionCode());
7712     }
7713     RpcEndExcept;
7714 
7715     return ret;
7716 }
7717 
7718 
7719 /***********************************************************************
7720  * CM_Request_Eject_PC [SETUPAPI.@]
7721  */
7722 CONFIGRET
7723 WINAPI
CM_Request_Eject_PC(VOID)7724 CM_Request_Eject_PC(VOID)
7725 {
7726     TRACE("CM_Request_Eject_PC()\n");
7727 
7728     return CM_Request_Eject_PC_Ex(NULL);
7729 }
7730 
7731 
7732 /***********************************************************************
7733  * CM_Request_Eject_PC_Ex [SETUPAPI.@]
7734  */
7735 CONFIGRET
7736 WINAPI
CM_Request_Eject_PC_Ex(_In_opt_ HMACHINE hMachine)7737 CM_Request_Eject_PC_Ex(
7738     _In_opt_ HMACHINE hMachine)
7739 {
7740     RPC_BINDING_HANDLE BindingHandle = NULL;
7741     CONFIGRET ret;
7742 
7743     TRACE("CM_Request_Eject_PC_Ex(%p)\n", hMachine);
7744 
7745     if (hMachine != NULL)
7746     {
7747         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7748         if (BindingHandle == NULL)
7749             return CR_FAILURE;
7750     }
7751     else
7752     {
7753         if (!PnpGetLocalHandles(&BindingHandle, NULL))
7754             return CR_FAILURE;
7755     }
7756 
7757     RpcTryExcept
7758     {
7759         ret = PNP_RequestEjectPC(BindingHandle);
7760     }
7761     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7762     {
7763         ret = RpcStatusToCmStatus(RpcExceptionCode());
7764     }
7765     RpcEndExcept;
7766 
7767     return ret;
7768 }
7769 
7770 
7771 /***********************************************************************
7772  * CM_Run_Detection [SETUPAPI.@]
7773  */
7774 CONFIGRET
7775 WINAPI
CM_Run_Detection(_In_ ULONG ulFlags)7776 CM_Run_Detection(
7777     _In_ ULONG ulFlags)
7778 {
7779     TRACE("CM_Run_Detection(%lx)\n", ulFlags);
7780 
7781     return CM_Run_Detection_Ex(ulFlags, NULL);
7782 }
7783 
7784 
7785 /***********************************************************************
7786  * CM_Run_Detection_Ex [SETUPAPI.@]
7787  */
7788 CONFIGRET
7789 WINAPI
CM_Run_Detection_Ex(_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7790 CM_Run_Detection_Ex(
7791     _In_ ULONG ulFlags,
7792     _In_opt_ HMACHINE hMachine)
7793 {
7794     RPC_BINDING_HANDLE BindingHandle = NULL;
7795     CONFIGRET ret;
7796 
7797     TRACE("CM_Run_Detection_Ex(%lx %p)\n",
7798           ulFlags, hMachine);
7799 
7800     if (!pSetupIsUserAdmin())
7801         return CR_ACCESS_DENIED;
7802 
7803     if (ulFlags & ~CM_DETECT_BITS)
7804         return CR_INVALID_FLAG;
7805 
7806     if (hMachine != NULL)
7807     {
7808         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7809         if (BindingHandle == NULL)
7810             return CR_FAILURE;
7811     }
7812     else
7813     {
7814         if (!PnpGetLocalHandles(&BindingHandle, NULL))
7815             return CR_FAILURE;
7816     }
7817 
7818     RpcTryExcept
7819     {
7820         ret = PNP_RunDetection(BindingHandle,
7821                                ulFlags);
7822     }
7823     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7824     {
7825         ret = RpcStatusToCmStatus(RpcExceptionCode());
7826     }
7827     RpcEndExcept;
7828 
7829     return ret;
7830 }
7831 
7832 
7833 /***********************************************************************
7834  * CM_Set_Class_Registry_PropertyA [SETUPAPI.@]
7835  */
7836 CONFIGRET
7837 WINAPI
CM_Set_Class_Registry_PropertyA(_In_ LPGUID ClassGuid,_In_ ULONG ulProperty,_In_reads_bytes_opt_ (ulLength)PCVOID Buffer,_In_ ULONG ulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7838 CM_Set_Class_Registry_PropertyA(
7839     _In_ LPGUID ClassGuid,
7840     _In_ ULONG ulProperty,
7841     _In_reads_bytes_opt_(ulLength) PCVOID Buffer,
7842     _In_ ULONG ulLength,
7843     _In_ ULONG ulFlags,
7844     _In_opt_ HMACHINE hMachine)
7845 {
7846     FIXME("CM_Set_Class_Registry_PropertyA(%p %lx %p %lu %lx %p)\n",
7847           ClassGuid, ulProperty, Buffer, ulLength, ulFlags, hMachine);
7848 
7849     return CR_CALL_NOT_IMPLEMENTED;
7850 }
7851 
7852 
7853 /***********************************************************************
7854  * CM_Set_Class_Registry_PropertyW [SETUPAPI.@]
7855  */
7856 CONFIGRET
7857 WINAPI
CM_Set_Class_Registry_PropertyW(_In_ LPGUID ClassGuid,_In_ ULONG ulProperty,_In_reads_bytes_opt_ (ulLength)PCVOID Buffer,_In_ ULONG ulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7858 CM_Set_Class_Registry_PropertyW(
7859     _In_ LPGUID ClassGuid,
7860     _In_ ULONG ulProperty,
7861     _In_reads_bytes_opt_(ulLength) PCVOID Buffer,
7862     _In_ ULONG ulLength,
7863     _In_ ULONG ulFlags,
7864     _In_opt_ HMACHINE hMachine)
7865 {
7866     FIXME("CM_Set_Class_Registry_PropertyW(%p %lx %p %lu %lx %p)\n",
7867           ClassGuid, ulProperty, Buffer, ulLength, ulFlags, hMachine);
7868 
7869     return CR_CALL_NOT_IMPLEMENTED;
7870 }
7871 
7872 
7873 /***********************************************************************
7874  * CM_Set_DevNode_Problem [SETUPAPI.@]
7875  */
7876 CONFIGRET
7877 WINAPI
CM_Set_DevNode_Problem(_In_ DEVINST dnDevInst,_In_ ULONG ulProblem,_In_ ULONG ulFlags)7878 CM_Set_DevNode_Problem(
7879     _In_ DEVINST dnDevInst,
7880     _In_ ULONG ulProblem,
7881     _In_ ULONG ulFlags)
7882 {
7883     TRACE("CM_Set_DevNode_Problem(%lx %lx %lx)\n",
7884           dnDevInst, ulProblem, ulFlags);
7885 
7886     return CM_Set_DevNode_Problem_Ex(dnDevInst, ulProblem, ulFlags, NULL);
7887 }
7888 
7889 
7890 /***********************************************************************
7891  * CM_Set_DevNode_Problem_Ex [SETUPAPI.@]
7892  */
7893 CONFIGRET
7894 WINAPI
CM_Set_DevNode_Problem_Ex(_In_ DEVINST dnDevInst,_In_ ULONG ulProblem,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7895 CM_Set_DevNode_Problem_Ex(
7896     _In_ DEVINST dnDevInst,
7897     _In_ ULONG ulProblem,
7898     _In_ ULONG ulFlags,
7899     _In_opt_ HMACHINE hMachine)
7900 {
7901     RPC_BINDING_HANDLE BindingHandle = NULL;
7902     HSTRING_TABLE StringTable = NULL;
7903     LPWSTR lpDevInst;
7904     CONFIGRET ret;
7905 
7906     TRACE("CM_Set_DevNode_Problem_Ex(%lx %lx %lx %p)\n",
7907           dnDevInst, ulProblem, ulFlags, hMachine);
7908 
7909     if (dnDevInst == 0)
7910         return CR_INVALID_DEVNODE;
7911 
7912     if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
7913         return CR_INVALID_FLAG;
7914 
7915     if (hMachine != NULL)
7916     {
7917         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
7918         if (BindingHandle == NULL)
7919             return CR_FAILURE;
7920 
7921         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
7922         if (StringTable == 0)
7923             return CR_FAILURE;
7924     }
7925     else
7926     {
7927         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
7928             return CR_FAILURE;
7929     }
7930 
7931     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
7932     if (lpDevInst == NULL)
7933         return CR_INVALID_DEVNODE;
7934 
7935     RpcTryExcept
7936     {
7937         ret = PNP_SetDeviceProblem(BindingHandle,
7938                                    lpDevInst,
7939                                    ulProblem,
7940                                    ulFlags);
7941     }
7942     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
7943     {
7944         ret = RpcStatusToCmStatus(RpcExceptionCode());
7945     }
7946     RpcEndExcept;
7947 
7948     return ret;
7949 }
7950 
7951 
7952 /***********************************************************************
7953  * CM_Set_DevNode_Registry_PropertyA [SETUPAPI.@]
7954  */
7955 CONFIGRET
7956 WINAPI
CM_Set_DevNode_Registry_PropertyA(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_In_reads_bytes_opt_ (ulLength)PCVOID Buffer,_In_ ULONG ulLength,_In_ ULONG ulFlags)7957 CM_Set_DevNode_Registry_PropertyA(
7958   _In_ DEVINST dnDevInst,
7959   _In_ ULONG ulProperty,
7960   _In_reads_bytes_opt_(ulLength) PCVOID Buffer,
7961   _In_ ULONG ulLength,
7962   _In_ ULONG ulFlags)
7963 {
7964     TRACE("CM_Set_DevNode_Registry_PropertyA(%lx %lu %p %lx %lx)\n",
7965           dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
7966 
7967     return CM_Set_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
7968                                                 Buffer, ulLength,
7969                                                 ulFlags, NULL);
7970 }
7971 
7972 
7973 /***********************************************************************
7974  * CM_Set_DevNode_Registry_PropertyW [SETUPAPI.@]
7975  */
7976 CONFIGRET
7977 WINAPI
CM_Set_DevNode_Registry_PropertyW(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_In_reads_bytes_opt_ (ulLength)PCVOID Buffer,_In_ ULONG ulLength,_In_ ULONG ulFlags)7978 CM_Set_DevNode_Registry_PropertyW(
7979     _In_ DEVINST dnDevInst,
7980     _In_ ULONG ulProperty,
7981     _In_reads_bytes_opt_(ulLength) PCVOID Buffer,
7982     _In_ ULONG ulLength,
7983     _In_ ULONG ulFlags)
7984 {
7985     TRACE("CM_Set_DevNode_Registry_PropertyW(%lx %lu %p %lx %lx)\n",
7986           dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
7987 
7988     return CM_Set_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
7989                                                 Buffer, ulLength,
7990                                                 ulFlags, NULL);
7991 }
7992 
7993 
7994 /***********************************************************************
7995  * CM_Set_DevNode_Registry_Property_ExA [SETUPAPI.@]
7996  */
7997 CONFIGRET
7998 WINAPI
CM_Set_DevNode_Registry_Property_ExA(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_In_reads_bytes_opt_ (ulLength)PCVOID Buffer,_In_ ULONG ulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)7999 CM_Set_DevNode_Registry_Property_ExA(
8000     _In_ DEVINST dnDevInst,
8001     _In_ ULONG ulProperty,
8002     _In_reads_bytes_opt_(ulLength) PCVOID Buffer,
8003     _In_ ULONG ulLength,
8004     _In_ ULONG ulFlags,
8005     _In_opt_ HMACHINE hMachine)
8006 {
8007     CONFIGRET ret = CR_SUCCESS;
8008     LPWSTR lpBuffer;
8009     ULONG ulType;
8010 
8011     FIXME("CM_Set_DevNode_Registry_Property_ExA(%lx %lu %p %lx %lx %p)\n",
8012           dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
8013 
8014     if (Buffer == NULL && ulLength != 0)
8015         return CR_INVALID_POINTER;
8016 
8017     if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
8018         return CR_INVALID_PROPERTY;
8019 
8020     if (Buffer == NULL)
8021     {
8022         ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
8023                                                    ulProperty,
8024                                                    NULL,
8025                                                    0,
8026                                                    ulFlags,
8027                                                    hMachine);
8028     }
8029     else
8030     {
8031         /* Get property type */
8032         ulType = GetRegistryPropertyType(ulProperty);
8033 
8034         /* Allocate buffer if needed */
8035         if (ulType == REG_SZ ||
8036             ulType == REG_MULTI_SZ)
8037         {
8038             lpBuffer = MyMalloc(ulLength * sizeof(WCHAR));
8039             if (lpBuffer == NULL)
8040             {
8041                 ret = CR_OUT_OF_MEMORY;
8042             }
8043             else
8044             {
8045                 if (!MultiByteToWideChar(CP_ACP, 0, Buffer,
8046                                          ulLength, lpBuffer, ulLength))
8047                 {
8048                     MyFree(lpBuffer);
8049                     ret = CR_FAILURE;
8050                 }
8051                 else
8052                 {
8053                     ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
8054                                                                ulProperty,
8055                                                                lpBuffer,
8056                                                                ulLength * sizeof(WCHAR),
8057                                                                ulFlags,
8058                                                                hMachine);
8059                     MyFree(lpBuffer);
8060                 }
8061             }
8062         }
8063         else
8064         {
8065             ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
8066                                                        ulProperty,
8067                                                        Buffer,
8068                                                        ulLength,
8069                                                        ulFlags,
8070                                                        hMachine);
8071         }
8072 
8073         ret = CR_CALL_NOT_IMPLEMENTED;
8074     }
8075 
8076     return ret;
8077 }
8078 
8079 
8080 /***********************************************************************
8081  * CM_Set_DevNode_Registry_Property_ExW [SETUPAPI.@]
8082  */
8083 CONFIGRET
8084 WINAPI
CM_Set_DevNode_Registry_Property_ExW(_In_ DEVINST dnDevInst,_In_ ULONG ulProperty,_In_reads_bytes_opt_ (ulLength)PCVOID Buffer,_In_ ULONG ulLength,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8085 CM_Set_DevNode_Registry_Property_ExW(
8086     _In_ DEVINST dnDevInst,
8087     _In_ ULONG ulProperty,
8088     _In_reads_bytes_opt_(ulLength) PCVOID Buffer,
8089     _In_ ULONG ulLength,
8090     _In_ ULONG ulFlags,
8091     _In_opt_ HMACHINE hMachine)
8092 {
8093     RPC_BINDING_HANDLE BindingHandle = NULL;
8094     HSTRING_TABLE StringTable = NULL;
8095     LPWSTR lpDevInst;
8096     ULONG ulType;
8097     CONFIGRET ret;
8098 
8099     TRACE("CM_Set_DevNode_Registry_Property_ExW(%lx %lu %p %lx %lx %p)\n",
8100           dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
8101 
8102     if (dnDevInst == 0)
8103         return CR_INVALID_DEVNODE;
8104 
8105     if (ulProperty <  CM_DRP_MIN || ulProperty > CM_DRP_MAX)
8106         return CR_INVALID_PROPERTY;
8107 
8108     if (Buffer != NULL && ulLength == 0)
8109         return CR_INVALID_POINTER;
8110 
8111     if (ulFlags != 0)
8112         return CR_INVALID_FLAG;
8113 
8114     if (hMachine != NULL)
8115     {
8116         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
8117         if (BindingHandle == NULL)
8118             return CR_FAILURE;
8119 
8120         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
8121         if (StringTable == 0)
8122             return CR_FAILURE;
8123     }
8124     else
8125     {
8126         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
8127             return CR_FAILURE;
8128     }
8129 
8130     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
8131     if (lpDevInst == NULL)
8132         return CR_INVALID_DEVNODE;
8133 
8134     /* Get property type */
8135     ulType = GetRegistryPropertyType(ulProperty);
8136 
8137     RpcTryExcept
8138     {
8139         ret = PNP_SetDeviceRegProp(BindingHandle,
8140                                    lpDevInst,
8141                                    ulProperty,
8142                                    ulType,
8143                                    (BYTE *)Buffer,
8144                                    ulLength,
8145                                    ulFlags);
8146     }
8147     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
8148     {
8149         ret = RpcStatusToCmStatus(RpcExceptionCode());
8150     }
8151     RpcEndExcept;
8152 
8153     return ret;
8154 }
8155 
8156 
8157 /***********************************************************************
8158  * CM_Set_HW_Prof [SETUPAPI.@]
8159  */
8160 CONFIGRET
8161 WINAPI
CM_Set_HW_Prof(_In_ ULONG ulHardwareProfile,_In_ ULONG ulFlags)8162 CM_Set_HW_Prof(
8163     _In_ ULONG ulHardwareProfile,
8164     _In_ ULONG ulFlags)
8165 {
8166     TRACE("CM_Set_HW_Prof(%lu %lx)\n",
8167           ulHardwareProfile, ulFlags);
8168 
8169     return CM_Set_HW_Prof_Ex(ulHardwareProfile, ulFlags, NULL);
8170 }
8171 
8172 
8173 /***********************************************************************
8174  * CM_Set_HW_Prof_Ex [SETUPAPI.@]
8175  */
8176 CONFIGRET
8177 WINAPI
CM_Set_HW_Prof_Ex(_In_ ULONG ulHardwareProfile,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8178 CM_Set_HW_Prof_Ex(
8179     _In_ ULONG ulHardwareProfile,
8180     _In_ ULONG ulFlags,
8181     _In_opt_ HMACHINE hMachine)
8182 {
8183     RPC_BINDING_HANDLE BindingHandle = NULL;
8184     CONFIGRET ret;
8185 
8186     TRACE("CM_Set_HW_Prof_Ex(%lu %lx %p)\n",
8187           ulHardwareProfile, ulFlags, hMachine);
8188 
8189     if (!pSetupIsUserAdmin())
8190         return CR_ACCESS_DENIED;
8191 
8192     if (ulFlags != 0)
8193         return CR_INVALID_FLAG;
8194 
8195     if (hMachine != NULL)
8196     {
8197         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
8198         if (BindingHandle == NULL)
8199             return CR_FAILURE;
8200     }
8201     else
8202     {
8203         if (!PnpGetLocalHandles(&BindingHandle, NULL))
8204             return CR_FAILURE;
8205     }
8206 
8207     RpcTryExcept
8208     {
8209         ret = PNP_SetHwProf(BindingHandle, ulHardwareProfile, ulFlags);
8210     }
8211     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
8212     {
8213         ret = RpcStatusToCmStatus(RpcExceptionCode());
8214     }
8215     RpcEndExcept;
8216 
8217     return ret;
8218 }
8219 
8220 
8221 /***********************************************************************
8222  * CM_Set_HW_Prof_FlagsA [SETUPAPI.@]
8223  */
8224 CONFIGRET
8225 WINAPI
CM_Set_HW_Prof_FlagsA(_In_ DEVINSTID_A szDevInstName,_In_ ULONG ulConfig,_In_ ULONG ulValue,_In_ ULONG ulFlags)8226 CM_Set_HW_Prof_FlagsA(
8227     _In_ DEVINSTID_A szDevInstName,
8228     _In_ ULONG ulConfig,
8229     _In_ ULONG ulValue,
8230     _In_ ULONG ulFlags)
8231 {
8232     TRACE("CM_Set_HW_Prof_FlagsA(%s %lu %lu %lx)\n",
8233           debugstr_a(szDevInstName), ulConfig, ulValue, ulFlags);
8234 
8235     return CM_Set_HW_Prof_Flags_ExA(szDevInstName, ulConfig, ulValue,
8236                                     ulFlags, NULL);
8237 }
8238 
8239 
8240 /***********************************************************************
8241  * CM_Set_HW_Prof_FlagsW [SETUPAPI.@]
8242  */
8243 CONFIGRET
8244 WINAPI
CM_Set_HW_Prof_FlagsW(_In_ DEVINSTID_W szDevInstName,_In_ ULONG ulConfig,_In_ ULONG ulValue,_In_ ULONG ulFlags)8245 CM_Set_HW_Prof_FlagsW(
8246     _In_ DEVINSTID_W szDevInstName,
8247     _In_ ULONG ulConfig,
8248     _In_ ULONG ulValue,
8249     _In_ ULONG ulFlags)
8250 {
8251     TRACE("CM_Set_HW_Prof_FlagsW(%s %lu %lu %lx)\n",
8252           debugstr_w(szDevInstName), ulConfig, ulValue, ulFlags);
8253 
8254     return CM_Set_HW_Prof_Flags_ExW(szDevInstName, ulConfig, ulValue,
8255                                     ulFlags, NULL);
8256 }
8257 
8258 
8259 /***********************************************************************
8260  * CM_Set_HW_Prof_Flags_ExA [SETUPAPI.@]
8261  */
8262 CONFIGRET
8263 WINAPI
CM_Set_HW_Prof_Flags_ExA(_In_ DEVINSTID_A szDevInstName,_In_ ULONG ulConfig,_In_ ULONG ulValue,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8264 CM_Set_HW_Prof_Flags_ExA(
8265     _In_ DEVINSTID_A szDevInstName,
8266     _In_ ULONG ulConfig,
8267     _In_ ULONG ulValue,
8268     _In_ ULONG ulFlags,
8269     _In_opt_ HMACHINE hMachine)
8270 {
8271     DEVINSTID_W pszDevIdW = NULL;
8272     CONFIGRET ret = CR_SUCCESS;
8273 
8274     TRACE("CM_Set_HW_Prof_Flags_ExA(%s %lu %lu %lx %p)\n",
8275           debugstr_a(szDevInstName), ulConfig, ulValue, ulFlags, hMachine);
8276 
8277     if (szDevInstName != NULL)
8278     {
8279        if (pSetupCaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
8280          return CR_INVALID_DEVICE_ID;
8281     }
8282 
8283     ret = CM_Set_HW_Prof_Flags_ExW(pszDevIdW, ulConfig, ulValue,
8284                                    ulFlags, hMachine);
8285 
8286     if (pszDevIdW != NULL)
8287         MyFree(pszDevIdW);
8288 
8289     return ret;
8290 }
8291 
8292 
8293 /***********************************************************************
8294  * CM_Set_HW_Prof_Flags_ExW [SETUPAPI.@]
8295  */
8296 CONFIGRET
8297 WINAPI
CM_Set_HW_Prof_Flags_ExW(_In_ DEVINSTID_W szDevInstName,_In_ ULONG ulConfig,_In_ ULONG ulValue,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8298 CM_Set_HW_Prof_Flags_ExW(
8299     _In_ DEVINSTID_W szDevInstName,
8300     _In_ ULONG ulConfig,
8301     _In_ ULONG ulValue,
8302     _In_ ULONG ulFlags,
8303     _In_opt_ HMACHINE hMachine)
8304 {
8305     RPC_BINDING_HANDLE BindingHandle = NULL;
8306     CONFIGRET ret;
8307 
8308     FIXME("CM_Set_HW_Prof_Flags_ExW(%s %lu %lu %lx %p)\n",
8309           debugstr_w(szDevInstName), ulConfig, ulValue, ulFlags, hMachine);
8310 
8311     if (szDevInstName == NULL)
8312         return CR_INVALID_POINTER;
8313 
8314     if (ulFlags & ~ CM_SET_HW_PROF_FLAGS_BITS)
8315         return CR_INVALID_FLAG;
8316 
8317     /* FIXME: Check whether szDevInstName is valid */
8318 
8319     if (hMachine != NULL)
8320     {
8321         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
8322         if (BindingHandle == NULL)
8323             return CR_FAILURE;
8324     }
8325     else
8326     {
8327         if (!PnpGetLocalHandles(&BindingHandle, NULL))
8328             return CR_FAILURE;
8329     }
8330 
8331     RpcTryExcept
8332     {
8333         ret = PNP_HwProfFlags(BindingHandle, PNP_SET_HWPROFFLAGS, szDevInstName,
8334                               ulConfig, &ulValue, NULL, NULL, 0, 0);
8335     }
8336     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
8337     {
8338         ret = RpcStatusToCmStatus(RpcExceptionCode());
8339     }
8340     RpcEndExcept;
8341 
8342     return ret;
8343 }
8344 
8345 
8346 /***********************************************************************
8347  * CM_Setup_DevNode [SETUPAPI.@]
8348  */
8349 CONFIGRET
8350 WINAPI
CM_Setup_DevNode(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags)8351 CM_Setup_DevNode(
8352     _In_ DEVINST dnDevInst,
8353     _In_ ULONG ulFlags)
8354 {
8355     TRACE("CM_Setup_DevNode(%lx %lx)\n",
8356           dnDevInst, ulFlags);
8357 
8358     return CM_Setup_DevNode_Ex(dnDevInst, ulFlags, NULL);
8359 }
8360 
8361 
8362 /***********************************************************************
8363  * CM_Setup_DevNode_Ex [SETUPAPI.@]
8364  */
8365 CONFIGRET
8366 WINAPI
CM_Setup_DevNode_Ex(_In_ DEVINST dnDevInst,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8367 CM_Setup_DevNode_Ex(
8368     _In_ DEVINST dnDevInst,
8369     _In_ ULONG ulFlags,
8370     _In_opt_ HMACHINE hMachine)
8371 {
8372     RPC_BINDING_HANDLE BindingHandle = NULL;
8373     HSTRING_TABLE StringTable = NULL;
8374     LPWSTR lpDevInst;
8375     CONFIGRET ret;
8376 
8377     FIXME("CM_Setup_DevNode_Ex(%lx %lx %p)\n",
8378           dnDevInst, ulFlags, hMachine);
8379 
8380     if (!pSetupIsUserAdmin())
8381         return CR_ACCESS_DENIED;
8382 
8383     if (dnDevInst == 0)
8384         return CR_INVALID_DEVNODE;
8385 
8386     if (ulFlags & ~CM_SETUP_BITS)
8387         return CR_INVALID_FLAG;
8388 
8389     if (hMachine != NULL)
8390     {
8391         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
8392         if (BindingHandle == NULL)
8393             return CR_FAILURE;
8394 
8395         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
8396         if (StringTable == 0)
8397             return CR_FAILURE;
8398     }
8399     else
8400     {
8401         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
8402             return CR_FAILURE;
8403     }
8404 
8405     lpDevInst = pSetupStringTableStringFromId(StringTable, dnDevInst);
8406     if (lpDevInst == NULL)
8407         return CR_INVALID_DEVNODE;
8408 
8409     RpcTryExcept
8410     {
8411         ret = PNP_DeviceInstanceAction(BindingHandle,
8412                                        PNP_DEVINST_SETUP,
8413                                        ulFlags,
8414                                        lpDevInst,
8415                                        NULL);
8416     }
8417     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
8418     {
8419         ret = RpcStatusToCmStatus(RpcExceptionCode());
8420     }
8421     RpcEndExcept;
8422 
8423     return ret;
8424 }
8425 
8426 
8427 /***********************************************************************
8428  * CM_Test_Range_Available [SETUPAPI.@]
8429  */
8430 CONFIGRET
8431 WINAPI
CM_Test_Range_Available(_In_ DWORDLONG ullStartValue,_In_ DWORDLONG ullEndValue,_In_ RANGE_LIST rlh,_In_ ULONG ulFlags)8432 CM_Test_Range_Available(
8433     _In_ DWORDLONG ullStartValue,
8434     _In_ DWORDLONG ullEndValue,
8435     _In_ RANGE_LIST rlh,
8436     _In_ ULONG ulFlags)
8437 {
8438     PINTERNAL_RANGE_LIST pRangeList;
8439     PINTERNAL_RANGE pRange;
8440     PLIST_ENTRY ListEntry;
8441     CONFIGRET ret = CR_SUCCESS;
8442 
8443     FIXME("CM_Test_Range_Available(%I64u %I64u %p %lx)\n",
8444           ullStartValue, ullEndValue, rlh, ulFlags);
8445 
8446     pRangeList = (PINTERNAL_RANGE_LIST)rlh;
8447 
8448     if (!IsValidRangeList(pRangeList))
8449         return CR_INVALID_RANGE_LIST;
8450 
8451     if (ulFlags != 0)
8452         return CR_INVALID_FLAG;
8453 
8454     if (ullStartValue > ullEndValue)
8455         return CR_INVALID_RANGE;
8456 
8457     /* Lock the range list */
8458     WaitForSingleObject(pRangeList->hMutex, INFINITE);
8459 
8460     /* Check the ranges */
8461     ListEntry = &pRangeList->ListHead;
8462     while (ListEntry->Flink == &pRangeList->ListHead)
8463     {
8464         pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
8465 
8466         /* Check if the start value is within the current range */
8467         if ((ullStartValue >= pRange->ullStart) && (ullStartValue <= pRange->ullEnd))
8468         {
8469             ret = CR_FAILURE;
8470             break;
8471         }
8472 
8473         /* Check if the end value is within the current range */
8474         if ((ullEndValue >= pRange->ullStart) && (ullEndValue <= pRange->ullEnd))
8475         {
8476             ret = CR_FAILURE;
8477             break;
8478         }
8479 
8480         /* Check if the current range lies inside of the start-end interval */
8481         if ((ullStartValue <= pRange->ullStart) && (ullEndValue >= pRange->ullEnd))
8482         {
8483             ret = CR_FAILURE;
8484             break;
8485         }
8486 
8487         ListEntry = ListEntry->Flink;
8488     }
8489 
8490     /* Unlock the range list */
8491     ReleaseMutex(pRangeList->hMutex);
8492 
8493     return ret;
8494 }
8495 
8496 
8497 /***********************************************************************
8498  * CM_Uninstall_DevNode [SETUPAPI.@]
8499  */
8500 CONFIGRET
8501 WINAPI
CM_Uninstall_DevNode(_In_ DEVINST dnPhantom,_In_ ULONG ulFlags)8502 CM_Uninstall_DevNode(
8503     _In_ DEVINST dnPhantom,
8504     _In_ ULONG ulFlags)
8505 {
8506     TRACE("CM_Uninstall_DevNode(%lx %lx)\n",
8507           dnPhantom, ulFlags);
8508 
8509     return CM_Uninstall_DevNode_Ex(dnPhantom, ulFlags, NULL);
8510 }
8511 
8512 
8513 /***********************************************************************
8514  * CM_Uninstall_DevNode_Ex [SETUPAPI.@]
8515  */
8516 CONFIGRET
8517 WINAPI
CM_Uninstall_DevNode_Ex(_In_ DEVINST dnPhantom,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8518 CM_Uninstall_DevNode_Ex(
8519     _In_ DEVINST dnPhantom,
8520     _In_ ULONG ulFlags,
8521     _In_opt_ HMACHINE hMachine)
8522 {
8523     RPC_BINDING_HANDLE BindingHandle = NULL;
8524     HSTRING_TABLE StringTable = NULL;
8525     LPWSTR lpDevInst;
8526     CONFIGRET ret;
8527 
8528     TRACE("CM_Uninstall_DevNode_Ex(%lx %lx %p)\n",
8529           dnPhantom, ulFlags, hMachine);
8530 
8531     if (dnPhantom == 0)
8532         return CR_INVALID_DEVNODE;
8533 
8534     if (ulFlags != 0)
8535         return CR_INVALID_FLAG;
8536 
8537     if (hMachine != NULL)
8538     {
8539         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
8540         if (BindingHandle == NULL)
8541             return CR_FAILURE;
8542 
8543         StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
8544         if (StringTable == 0)
8545             return CR_FAILURE;
8546     }
8547     else
8548     {
8549         if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
8550             return CR_FAILURE;
8551     }
8552 
8553     lpDevInst = pSetupStringTableStringFromId(StringTable, dnPhantom);
8554     if (lpDevInst == NULL)
8555         return CR_INVALID_DEVNODE;
8556 
8557     RpcTryExcept
8558     {
8559         ret = PNP_UninstallDevInst(BindingHandle,
8560                                    lpDevInst,
8561                                    ulFlags);
8562     }
8563     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
8564     {
8565         ret = RpcStatusToCmStatus(RpcExceptionCode());
8566     }
8567     RpcEndExcept;
8568 
8569     return ret;
8570 }
8571 
8572 
8573 /***********************************************************************
8574  * CM_Unregister_Device_InterfaceA [SETUPAPI.@]
8575  */
8576 CONFIGRET
8577 WINAPI
CM_Unregister_Device_InterfaceA(_In_ LPCSTR pszDeviceInterface,_In_ ULONG ulFlags)8578 CM_Unregister_Device_InterfaceA(
8579     _In_ LPCSTR pszDeviceInterface,
8580     _In_ ULONG ulFlags)
8581 {
8582     TRACE("CM_Unregister_Device_InterfaceA(%s %lx)\n",
8583           debugstr_a(pszDeviceInterface), ulFlags);
8584 
8585     return CM_Unregister_Device_Interface_ExA(pszDeviceInterface,
8586                                               ulFlags, NULL);
8587 }
8588 
8589 
8590 /***********************************************************************
8591  * CM_Unregister_Device_InterfaceW [SETUPAPI.@]
8592  */
8593 CONFIGRET
8594 WINAPI
CM_Unregister_Device_InterfaceW(_In_ LPCWSTR pszDeviceInterface,_In_ ULONG ulFlags)8595 CM_Unregister_Device_InterfaceW(
8596     _In_ LPCWSTR pszDeviceInterface,
8597     _In_ ULONG ulFlags)
8598 {
8599     TRACE("CM_Unregister_Device_InterfaceW(%s %lx)\n",
8600           debugstr_w(pszDeviceInterface), ulFlags);
8601 
8602     return CM_Unregister_Device_Interface_ExW(pszDeviceInterface,
8603                                               ulFlags, NULL);
8604 }
8605 
8606 
8607 /***********************************************************************
8608  * CM_Unregister_Device_Interface_ExA [SETUPAPI.@]
8609  */
8610 CONFIGRET
8611 WINAPI
CM_Unregister_Device_Interface_ExA(_In_ LPCSTR pszDeviceInterface,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8612 CM_Unregister_Device_Interface_ExA(
8613     _In_ LPCSTR pszDeviceInterface,
8614     _In_ ULONG ulFlags,
8615     _In_opt_ HMACHINE hMachine)
8616 {
8617     LPWSTR pszDeviceInterfaceW = NULL;
8618     CONFIGRET ret;
8619 
8620     TRACE("CM_Unregister_Device_Interface_ExA(%s %lx %p)\n",
8621           debugstr_a(pszDeviceInterface), ulFlags, hMachine);
8622 
8623     if (pszDeviceInterface == NULL)
8624         return CR_INVALID_POINTER;
8625 
8626     if (pSetupCaptureAndConvertAnsiArg(pszDeviceInterface, &pszDeviceInterfaceW))
8627         return CR_INVALID_DATA;
8628 
8629     ret = CM_Unregister_Device_Interface_ExW(pszDeviceInterfaceW,
8630                                              ulFlags, hMachine);
8631 
8632     if (pszDeviceInterfaceW != NULL)
8633         MyFree(pszDeviceInterfaceW);
8634 
8635     return ret;
8636 }
8637 
8638 
8639 /***********************************************************************
8640  * CM_Unregister_Device_Interface_ExW [SETUPAPI.@]
8641  */
8642 CONFIGRET
8643 WINAPI
CM_Unregister_Device_Interface_ExW(_In_ LPCWSTR pszDeviceInterface,_In_ ULONG ulFlags,_In_opt_ HMACHINE hMachine)8644 CM_Unregister_Device_Interface_ExW(
8645     _In_ LPCWSTR pszDeviceInterface,
8646     _In_ ULONG ulFlags,
8647     _In_opt_ HMACHINE hMachine)
8648 {
8649     RPC_BINDING_HANDLE BindingHandle = NULL;
8650     CONFIGRET ret;
8651 
8652     TRACE("CM_Unregister_Device_Interface_ExW(%s %lx %p)\n",
8653           debugstr_w(pszDeviceInterface), ulFlags, hMachine);
8654 
8655     if (pszDeviceInterface == NULL)
8656         return CR_INVALID_POINTER;
8657 
8658     if (ulFlags != 0)
8659         return CR_INVALID_FLAG;
8660 
8661     if (hMachine != NULL)
8662     {
8663         BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
8664         if (BindingHandle == NULL)
8665             return CR_FAILURE;
8666     }
8667     else
8668     {
8669         if (!PnpGetLocalHandles(&BindingHandle, NULL))
8670             return CR_FAILURE;
8671     }
8672 
8673     RpcTryExcept
8674     {
8675         ret = PNP_UnregisterDeviceClassAssociation(BindingHandle,
8676                                                    (LPWSTR)pszDeviceInterface,
8677                                                    ulFlags);
8678     }
8679     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
8680     {
8681         ret = RpcStatusToCmStatus(RpcExceptionCode());
8682     }
8683     RpcEndExcept;
8684 
8685     return ret;
8686 }
8687