[YAROTOWS] Reintegrate the branch. For a brighter future.
[reactos.git] / reactos / dll / win32 / setupapi / cfgmgr.c
1 /*
2 * Configuration manager functions
3 *
4 * Copyright 2000 James Hatheway
5 * Copyright 2005, 2006 Eric Kohl
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "setupapi_private.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
25
26 /* Registry key and value names */
27 static const WCHAR Backslash[] = {'\\', 0};
28 static const WCHAR Class[] = {'C','l','a','s','s',0};
29
30 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
31 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
32 'C','o','n','t','r','o','l','\\',
33 'C','l','a','s','s',0};
34
35 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
36 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
37 'C','o','n','t','r','o','l','\\',
38 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
39
40 typedef struct _MACHINE_INFO
41 {
42 WCHAR szMachineName[SP_MAX_MACHINENAME_LENGTH];
43 RPC_BINDING_HANDLE BindingHandle;
44 HSTRING_TABLE StringTable;
45 BOOL bLocal;
46 } MACHINE_INFO, *PMACHINE_INFO;
47
48
49 typedef struct _LOG_CONF_INFO
50 {
51 ULONG ulMagic;
52 DEVINST dnDevInst;
53 ULONG ulFlags;
54 ULONG ulTag;
55 } LOG_CONF_INFO, *PLOG_CONF_INFO;
56
57 #define LOG_CONF_MAGIC 0x464E434C /* "LCNF" */
58
59
60 static BOOL GuidToString(LPGUID Guid, LPWSTR String)
61 {
62 LPWSTR lpString;
63
64 if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
65 return FALSE;
66
67 lstrcpyW(&String[1], lpString);
68
69 String[0] = '{';
70 String[MAX_GUID_STRING_LEN - 2] = '}';
71 String[MAX_GUID_STRING_LEN - 1] = UNICODE_NULL;
72
73 RpcStringFreeW(&lpString);
74
75 return TRUE;
76 }
77
78
79 static CONFIGRET
80 RpcStatusToCmStatus(RPC_STATUS Status)
81 {
82 return CR_FAILURE;
83 }
84
85
86 /***********************************************************************
87 * CMP_WaitNoPendingInstallEvents [SETUPAPI.@]
88 */
89 DWORD WINAPI CMP_WaitNoPendingInstallEvents(
90 DWORD dwTimeout)
91 {
92 HANDLE hEvent;
93 DWORD ret;
94
95 hEvent = OpenEventW(SYNCHRONIZE, FALSE, L"Global\\PnP_No_Pending_Install_Events");
96 if (hEvent == NULL)
97 return WAIT_FAILED;
98
99 ret = WaitForSingleObject(hEvent, dwTimeout);
100 CloseHandle(hEvent);
101 return ret;
102 }
103
104
105 /***********************************************************************
106 * CMP_Init_Detection [SETUPAPI.@]
107 */
108 CONFIGRET WINAPI CMP_Init_Detection(
109 DWORD dwMagic)
110 {
111 RPC_BINDING_HANDLE BindingHandle = NULL;
112 CONFIGRET ret;
113
114 TRACE("%lu\n", dwMagic);
115
116 if (dwMagic != CMP_MAGIC)
117 return CR_INVALID_DATA;
118
119 if (!PnpGetLocalHandles(&BindingHandle, NULL))
120 return CR_FAILURE;
121
122 RpcTryExcept
123 {
124 ret = PNP_InitDetection(BindingHandle);
125 }
126 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
127 {
128 ret = RpcStatusToCmStatus(RpcExceptionCode());
129 }
130 RpcEndExcept;
131
132 return ret;
133 }
134
135
136 /***********************************************************************
137 * CMP_Report_LogOn [SETUPAPI.@]
138 */
139 CONFIGRET WINAPI CMP_Report_LogOn(
140 DWORD dwMagic,
141 DWORD dwProcessId)
142 {
143 RPC_BINDING_HANDLE BindingHandle = NULL;
144 CONFIGRET ret = CR_SUCCESS;
145 BOOL bAdmin;
146 DWORD i;
147
148 TRACE("%lu\n", dwMagic);
149
150 if (dwMagic != CMP_MAGIC)
151 return CR_INVALID_DATA;
152
153 if (!PnpGetLocalHandles(&BindingHandle, NULL))
154 return CR_FAILURE;
155
156 bAdmin = IsUserAdmin();
157
158 for (i = 0; i < 30; i++)
159 {
160 RpcTryExcept
161 {
162 ret = PNP_ReportLogOn(BindingHandle,
163 bAdmin,
164 dwProcessId);
165 }
166 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
167 {
168 ret = RpcStatusToCmStatus(RpcExceptionCode());
169 }
170 RpcEndExcept;
171
172 if (ret == CR_SUCCESS)
173 break;
174
175 Sleep(5000);
176 }
177
178 return ret;
179 }
180
181
182 /***********************************************************************
183 * CM_Add_Empty_Log_Conf [SETUPAPI.@]
184 */
185 CONFIGRET WINAPI CM_Add_Empty_Log_Conf(
186 PLOG_CONF plcLogConf, DEVINST dnDevInst, PRIORITY Priority,
187 ULONG ulFlags)
188 {
189 TRACE("%p %p %lu %lx\n", plcLogConf, dnDevInst, Priority, ulFlags);
190 return CM_Add_Empty_Log_Conf_Ex(plcLogConf, dnDevInst, Priority,
191 ulFlags, NULL);
192 }
193
194
195 /***********************************************************************
196 * CM_Add_Empty_Log_Conf_Ex [SETUPAPI.@]
197 */
198 CONFIGRET WINAPI CM_Add_Empty_Log_Conf_Ex(
199 PLOG_CONF plcLogConf, DEVINST dnDevInst, PRIORITY Priority,
200 ULONG ulFlags, HMACHINE hMachine)
201 {
202 RPC_BINDING_HANDLE BindingHandle = NULL;
203 HSTRING_TABLE StringTable = NULL;
204 ULONG ulLogConfTag = 0;
205 LPWSTR lpDevInst;
206 PLOG_CONF_INFO pLogConfInfo;
207 CONFIGRET ret = CR_SUCCESS;
208
209 FIXME("%p %p %lu %lx %p\n",
210 plcLogConf, dnDevInst, Priority, ulFlags, hMachine);
211
212 if (!IsUserAdmin())
213 return CR_ACCESS_DENIED;
214
215 if (plcLogConf == NULL)
216 return CR_INVALID_POINTER;
217
218 if (dnDevInst == 0)
219 return CR_INVALID_DEVINST;
220
221 if (Priority > 0xFFFF)
222 return CR_INVALID_PRIORITY;
223
224 if (ulFlags & ~(LOG_CONF_BITS | PRIORITY_BIT))
225 return CR_INVALID_FLAG;
226
227 if (hMachine != NULL)
228 {
229 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
230 if (BindingHandle == NULL)
231 return CR_FAILURE;
232
233 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
234 if (StringTable == 0)
235 return CR_FAILURE;
236 }
237 else
238 {
239 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
240 return CR_FAILURE;
241 }
242
243 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
244 if (lpDevInst == NULL)
245 return CR_INVALID_DEVNODE;
246
247 RpcTryExcept
248 {
249 ret = PNP_AddEmptyLogConf(BindingHandle, lpDevInst, Priority,
250 &ulLogConfTag, ulFlags);
251 }
252 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
253 {
254 ret = RpcStatusToCmStatus(RpcExceptionCode());
255 }
256 RpcEndExcept;
257
258 if (ret == CR_SUCCESS)
259 {
260 pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
261 if (pLogConfInfo == NULL)
262 {
263 ret = CR_OUT_OF_MEMORY;
264 }
265 else
266 {
267 pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
268 pLogConfInfo->dnDevInst = dnDevInst;
269 pLogConfInfo->ulFlags = ulFlags;
270 pLogConfInfo->ulTag = ulLogConfTag;
271
272 *plcLogConf = (LOG_CONF)pLogConfInfo;
273
274 ret = CR_SUCCESS;
275 }
276 }
277
278 return ret;
279 }
280
281
282 /***********************************************************************
283 * CM_Add_IDA [SETUPAPI.@]
284 */
285 CONFIGRET WINAPI CM_Add_IDA(
286 DEVINST dnDevInst, PSTR pszID, ULONG ulFlags)
287 {
288 TRACE("%p %s %lx\n", dnDevInst, pszID, ulFlags);
289 return CM_Add_ID_ExA(dnDevInst, pszID, ulFlags, NULL);
290 }
291
292
293 /***********************************************************************
294 * CM_Add_IDW [SETUPAPI.@]
295 */
296 CONFIGRET WINAPI CM_Add_IDW(
297 DEVINST dnDevInst, PWSTR pszID, ULONG ulFlags)
298 {
299 TRACE("%p %s %lx\n", dnDevInst, debugstr_w(pszID), ulFlags);
300 return CM_Add_ID_ExW(dnDevInst, pszID, ulFlags, NULL);
301 }
302
303
304 /***********************************************************************
305 * CM_Add_ID_ExA [SETUPAPI.@]
306 */
307 CONFIGRET WINAPI CM_Add_ID_ExA(
308 DEVINST dnDevInst, PSTR pszID, ULONG ulFlags, HMACHINE hMachine)
309 {
310 PWSTR pszIDW;
311 CONFIGRET ret;
312
313 TRACE("%p %s %lx %p\n", dnDevInst, pszID, ulFlags, hMachine);
314
315 if (CaptureAndConvertAnsiArg(pszID, &pszIDW))
316 return CR_INVALID_DATA;
317
318 ret = CM_Add_ID_ExW(dnDevInst, pszIDW, ulFlags, hMachine);
319
320 MyFree(pszIDW);
321
322 return ret;
323 }
324
325
326 /***********************************************************************
327 * CM_Add_ID_ExW [SETUPAPI.@]
328 */
329 CONFIGRET WINAPI CM_Add_ID_ExW(
330 DEVINST dnDevInst, PWSTR pszID, ULONG ulFlags, HMACHINE hMachine)
331 {
332 RPC_BINDING_HANDLE BindingHandle = NULL;
333 HSTRING_TABLE StringTable = NULL;
334 LPWSTR lpDevInst;
335 CONFIGRET ret;
336
337 TRACE("%p %s %lx %p\n", dnDevInst, debugstr_w(pszID), ulFlags, hMachine);
338
339 if (!IsUserAdmin())
340 return CR_ACCESS_DENIED;
341
342 if (dnDevInst == 0)
343 return CR_INVALID_DEVINST;
344
345 if (pszID == NULL)
346 return CR_INVALID_POINTER;
347
348 if (ulFlags & ~CM_ADD_ID_BITS)
349 return CR_INVALID_FLAG;
350
351 if (hMachine != NULL)
352 {
353 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
354 if (BindingHandle == NULL)
355 return CR_FAILURE;
356
357 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
358 if (StringTable == 0)
359 return CR_FAILURE;
360 }
361 else
362 {
363 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
364 return CR_FAILURE;
365 }
366
367 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
368 if (lpDevInst == NULL)
369 return CR_INVALID_DEVNODE;
370
371 RpcTryExcept
372 {
373 ret = PNP_AddID(BindingHandle,
374 lpDevInst,
375 pszID,
376 ulFlags);
377 }
378 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
379 {
380 ret = RpcStatusToCmStatus(RpcExceptionCode());
381 }
382 RpcEndExcept;
383
384 return ret;
385 }
386
387
388 /***********************************************************************
389 * CM_Connect_MachineA [SETUPAPI.@]
390 */
391 CONFIGRET WINAPI CM_Connect_MachineA(
392 PCSTR UNCServerName, PHMACHINE phMachine)
393 {
394 PWSTR pServerNameW;
395 CONFIGRET ret;
396
397 TRACE("%s %p\n", UNCServerName, phMachine);
398
399 if (UNCServerName == NULL || *UNCServerName == 0)
400 return CM_Connect_MachineW(NULL, phMachine);
401
402 if (CaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
403 return CR_INVALID_DATA;
404
405 ret = CM_Connect_MachineW(pServerNameW, phMachine);
406
407 MyFree(pServerNameW);
408
409 return ret;
410 }
411
412
413 /***********************************************************************
414 * CM_Connect_MachineW [SETUPAPI.@]
415 */
416 CONFIGRET WINAPI CM_Connect_MachineW(
417 PCWSTR UNCServerName, PHMACHINE phMachine)
418 {
419 PMACHINE_INFO pMachine;
420
421 TRACE("%s %p\n", debugstr_w(UNCServerName), phMachine);
422
423 if (phMachine == NULL)
424 return CR_INVALID_POINTER;
425
426 *phMachine = NULL;
427
428 pMachine = HeapAlloc(GetProcessHeap(), 0, sizeof(MACHINE_INFO));
429 if (pMachine == NULL)
430 return CR_OUT_OF_MEMORY;
431
432 if (UNCServerName == NULL || *UNCServerName == 0)
433 {
434 pMachine->bLocal = TRUE;
435
436 /* FIXME: store the computers name in pMachine->szMachineName */
437
438 if (!PnpGetLocalHandles(&pMachine->BindingHandle,
439 &pMachine->StringTable))
440 {
441 HeapFree(GetProcessHeap(), 0, pMachine);
442 return CR_FAILURE;
443 }
444 }
445 else
446 {
447 pMachine->bLocal = FALSE;
448 if (wcslen(UNCServerName) >= SP_MAX_MACHINENAME_LENGTH - 1)
449 {
450 HeapFree(GetProcessHeap(), 0, pMachine);
451 return CR_INVALID_MACHINENAME;
452 }
453 lstrcpyW(pMachine->szMachineName, UNCServerName);
454
455 pMachine->StringTable = StringTableInitialize();
456 if (pMachine->StringTable == NULL)
457 {
458 HeapFree(GetProcessHeap(), 0, pMachine);
459 return CR_FAILURE;
460 }
461
462 StringTableAddString(pMachine->StringTable, L"PLT", 1);
463
464 if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
465 {
466 StringTableDestroy(pMachine->StringTable);
467 HeapFree(GetProcessHeap(), 0, pMachine);
468 return CR_INVALID_MACHINENAME;
469 }
470 }
471
472 phMachine = (PHMACHINE)pMachine;
473
474 return CR_SUCCESS;
475 }
476
477
478 /***********************************************************************
479 * CM_Create_DevNodeA [SETUPAPI.@]
480 */
481 CONFIGRET WINAPI CM_Create_DevNodeA(
482 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
483 ULONG ulFlags)
484 {
485 TRACE("%p %s %p %lx\n",
486 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
487 return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
488 ulFlags, NULL);
489 }
490
491
492 /***********************************************************************
493 * CM_Create_DevNodeW [SETUPAPI.@]
494 */
495 CONFIGRET WINAPI CM_Create_DevNodeW(
496 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
497 ULONG ulFlags)
498 {
499 TRACE("%p %s %p %lx\n",
500 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
501 return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
502 ulFlags, NULL);
503 }
504
505
506 /***********************************************************************
507 * CM_Create_DevNode_ExA [SETUPAPI.@]
508 */
509 CONFIGRET WINAPI CM_Create_DevNode_ExA(
510 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
511 ULONG ulFlags, HANDLE hMachine)
512 {
513 DEVINSTID_W pDeviceIDW;
514 CONFIGRET ret;
515
516 TRACE("%p %s %p %lx %p\n",
517 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
518
519 if (CaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
520 return CR_INVALID_DATA;
521
522 ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
523 hMachine);
524
525 MyFree(pDeviceIDW);
526
527 return ret;
528 }
529
530
531 /***********************************************************************
532 * CM_Create_DevNode_ExW [SETUPAPI.@]
533 */
534 CONFIGRET WINAPI CM_Create_DevNode_ExW(
535 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
536 ULONG ulFlags, HANDLE hMachine)
537 {
538 RPC_BINDING_HANDLE BindingHandle = NULL;
539 HSTRING_TABLE StringTable = NULL;
540 LPWSTR lpParentDevInst;
541 CONFIGRET ret = CR_SUCCESS;
542
543 FIXME("%p %s %p %lx %p\n",
544 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
545
546 if (!IsUserAdmin())
547 return CR_ACCESS_DENIED;
548
549 if (pdnDevInst == NULL)
550 return CR_INVALID_POINTER;
551
552 if (pDeviceID == NULL || wcslen(pDeviceID) == 0)
553 return CR_INVALID_DEVICE_ID;
554
555 if (dnParent == 0)
556 return CR_INVALID_DEVNODE;
557
558 if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
559 return CR_INVALID_FLAG;
560
561 if (hMachine != NULL)
562 {
563 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
564 if (BindingHandle == NULL)
565 return CR_FAILURE;
566
567 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
568 if (StringTable == 0)
569 return CR_FAILURE;
570 }
571 else
572 {
573 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
574 return CR_FAILURE;
575 }
576
577 lpParentDevInst = StringTableStringFromId(StringTable, dnParent);
578 if (lpParentDevInst == NULL)
579 return CR_INVALID_DEVNODE;
580
581 RpcTryExcept
582 {
583 ret = PNP_CreateDevInst(BindingHandle,
584 pDeviceID,
585 lpParentDevInst,
586 MAX_DEVICE_ID_LEN,
587 ulFlags);
588 }
589 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
590 {
591 ret = RpcStatusToCmStatus(RpcExceptionCode());
592 }
593 RpcEndExcept;
594
595 if (ret == CR_SUCCESS)
596 {
597 *pdnDevInst = StringTableAddString(StringTable, pDeviceID, 1);
598 if (*pdnDevInst == 0)
599 ret = CR_NO_SUCH_DEVNODE;
600 }
601
602 return ret;
603 }
604
605
606 /***********************************************************************
607 * CM_Delete_Class_Key [SETUPAPI.@]
608 */
609 CONFIGRET WINAPI CM_Delete_Class_Key(
610 LPGUID ClassGuid, ULONG ulFlags)
611 {
612 TRACE("%p %lx\n", ClassGuid, ulFlags);
613 return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
614 }
615
616
617 /***********************************************************************
618 * CM_Delete_Class_Key_Ex [SETUPAPI.@]
619 */
620 CONFIGRET WINAPI CM_Delete_Class_Key_Ex(
621 LPGUID ClassGuid, ULONG ulFlags, HANDLE hMachine)
622 {
623 WCHAR szGuidString[MAX_GUID_STRING_LEN];
624 RPC_BINDING_HANDLE BindingHandle = NULL;
625 CONFIGRET ret;
626
627 TRACE("%p %lx %lx\n", ClassGuid, ulFlags, hMachine);
628
629 if (ClassGuid == NULL)
630 return CR_INVALID_POINTER;
631
632 if (ulFlags & ~CM_DELETE_CLASS_BITS)
633 return CR_INVALID_FLAG;
634
635 if (!GuidToString(ClassGuid, szGuidString))
636 return CR_INVALID_DATA;
637
638 if (hMachine != NULL)
639 {
640 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
641 if (BindingHandle == NULL)
642 return CR_FAILURE;
643 }
644 else
645 {
646 if (!PnpGetLocalHandles(&BindingHandle, NULL))
647 return CR_FAILURE;
648 }
649
650 RpcTryExcept
651 {
652 ret = PNP_DeleteClassKey(BindingHandle,
653 szGuidString,
654 ulFlags);
655 }
656 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
657 {
658 ret = RpcStatusToCmStatus(RpcExceptionCode());
659 }
660 RpcEndExcept;
661
662 return ret;
663 }
664
665
666 /***********************************************************************
667 * CM_Delete_DevNode_Key [SETUPAPI.@]
668 */
669 CONFIGRET WINAPI CM_Delete_DevNode_Key(
670 DEVNODE dnDevNode, ULONG ulHardwareProfile, ULONG ulFlags)
671 {
672 TRACE("%p %lu %lx\n", dnDevNode, ulHardwareProfile, ulFlags);
673 return CM_Delete_DevNode_Key_Ex(dnDevNode, ulHardwareProfile, ulFlags,
674 NULL);
675 }
676
677
678 /***********************************************************************
679 * CM_Delete_DevNode_Key_Ex [SETUPAPI.@]
680 */
681 CONFIGRET WINAPI CM_Delete_DevNode_Key_Ex(
682 DEVNODE dnDevNode, ULONG ulHardwareProfile, ULONG ulFlags,
683 HANDLE hMachine)
684 {
685 FIXME("%p %lu %lx %p\n",
686 dnDevNode, ulHardwareProfile, ulFlags, hMachine);
687
688 return CR_CALL_NOT_IMPLEMENTED;
689 }
690
691
692 /***********************************************************************
693 * CM_Disable_DevNode [SETUPAPI.@]
694 */
695 CONFIGRET WINAPI CM_Disable_DevNode(
696 DEVINST dnDevInst, ULONG ulFlags)
697 {
698 TRACE("%p %lx\n", dnDevInst, ulFlags);
699 return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
700 }
701
702
703 /***********************************************************************
704 * CM_Disable_DevNode_Ex [SETUPAPI.@]
705 */
706 CONFIGRET WINAPI CM_Disable_DevNode_Ex(
707 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
708 {
709 RPC_BINDING_HANDLE BindingHandle = NULL;
710 HSTRING_TABLE StringTable = NULL;
711 LPWSTR lpDevInst;
712 CONFIGRET ret;
713
714 FIXME("%p %lx %p\n", dnDevInst, ulFlags, hMachine);
715
716 if (!IsUserAdmin())
717 return CR_ACCESS_DENIED;
718
719 if (dnDevInst == 0)
720 return CR_INVALID_DEVINST;
721
722 if (ulFlags != 0)
723 return CR_INVALID_FLAG;
724
725 if (hMachine != NULL)
726 {
727 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
728 if (BindingHandle == NULL)
729 return CR_FAILURE;
730
731 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
732 if (StringTable == 0)
733 return CR_FAILURE;
734 }
735 else
736 {
737 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
738 return CR_FAILURE;
739 }
740
741 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
742 if (lpDevInst == NULL)
743 return CR_INVALID_DEVNODE;
744
745 RpcTryExcept
746 {
747 ret = PNP_DeviceInstanceAction(BindingHandle,
748 PNP_DEVINST_DISABLE,
749 ulFlags,
750 lpDevInst,
751 NULL);
752 }
753 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
754 {
755 ret = RpcStatusToCmStatus(RpcExceptionCode());
756 }
757 RpcEndExcept;
758
759 return ret;
760 }
761
762
763 /***********************************************************************
764 * CM_Disconnect_Machine [SETUPAPI.@]
765 */
766 CONFIGRET WINAPI CM_Disconnect_Machine(HMACHINE hMachine)
767 {
768 PMACHINE_INFO pMachine;
769
770 TRACE("%lx\n", hMachine);
771
772 pMachine = (PMACHINE_INFO)hMachine;
773 if (pMachine == NULL)
774 return CR_SUCCESS;
775
776 if (pMachine->bLocal == FALSE)
777 {
778 if (pMachine->StringTable != NULL)
779 StringTableDestroy(pMachine->StringTable);
780
781 if (!PnpUnbindRpc(pMachine->BindingHandle))
782 return CR_ACCESS_DENIED;
783 }
784
785 HeapFree(GetProcessHeap(), 0, pMachine);
786
787 return CR_SUCCESS;
788 }
789
790
791 /***********************************************************************
792 * CM_Enable_DevNode [SETUPAPI.@]
793 */
794 CONFIGRET WINAPI CM_Enable_DevNode(
795 DEVINST dnDevInst, ULONG ulFlags)
796 {
797 TRACE("%p %lx\n", dnDevInst, ulFlags);
798 return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
799 }
800
801
802 /***********************************************************************
803 * CM_Enable_DevNode_Ex [SETUPAPI.@]
804 */
805 CONFIGRET WINAPI CM_Enable_DevNode_Ex(
806 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
807 {
808 RPC_BINDING_HANDLE BindingHandle = NULL;
809 HSTRING_TABLE StringTable = NULL;
810 LPWSTR lpDevInst;
811 CONFIGRET ret;
812
813 TRACE("%p %lx %p\n", dnDevInst, ulFlags, hMachine);
814
815 if (!IsUserAdmin())
816 return CR_ACCESS_DENIED;
817
818 if (dnDevInst == 0)
819 return CR_INVALID_DEVINST;
820
821 if (ulFlags != 0)
822 return CR_INVALID_FLAG;
823
824 if (hMachine != NULL)
825 {
826 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
827 if (BindingHandle == NULL)
828 return CR_FAILURE;
829
830 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
831 if (StringTable == 0)
832 return CR_FAILURE;
833 }
834 else
835 {
836 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
837 return CR_FAILURE;
838 }
839
840 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
841 if (lpDevInst == NULL)
842 return CR_INVALID_DEVNODE;
843
844 RpcTryExcept
845 {
846 ret = PNP_DeviceInstanceAction(BindingHandle,
847 PNP_DEVINST_ENABLE,
848 ulFlags,
849 lpDevInst,
850 NULL);
851 }
852 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
853 {
854 ret = RpcStatusToCmStatus(RpcExceptionCode());
855 }
856 RpcEndExcept;
857
858 return ret;
859 }
860
861
862 /***********************************************************************
863 * CM_Enumerate_Classes [SETUPAPI.@]
864 */
865 CONFIGRET WINAPI CM_Enumerate_Classes(
866 ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags)
867 {
868 TRACE("%lx %p %lx\n", ulClassIndex, ClassGuid, ulFlags);
869 return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
870 }
871
872
873 /***********************************************************************
874 * CM_Enumerate_Classes_Ex [SETUPAPI.@]
875 */
876 CONFIGRET WINAPI CM_Enumerate_Classes_Ex(
877 ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags, HMACHINE hMachine)
878 {
879 WCHAR szBuffer[MAX_GUID_STRING_LEN];
880 RPC_BINDING_HANDLE BindingHandle = NULL;
881 CONFIGRET ret = CR_SUCCESS;
882 ULONG ulLength = MAX_GUID_STRING_LEN;
883
884 TRACE("%lx %p %lx %p\n", ulClassIndex, ClassGuid, ulFlags, hMachine);
885
886 if (ClassGuid == NULL)
887 return CR_INVALID_POINTER;
888
889 if (ulFlags != 0)
890 return CR_INVALID_FLAG;
891
892 if (hMachine != NULL)
893 {
894 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
895 if (BindingHandle == NULL)
896 return CR_FAILURE;
897 }
898 else
899 {
900 if (!PnpGetLocalHandles(&BindingHandle, NULL))
901 return CR_FAILURE;
902 }
903
904 RpcTryExcept
905 {
906 ret = PNP_EnumerateSubKeys(BindingHandle,
907 PNP_CLASS_SUBKEYS,
908 ulClassIndex,
909 szBuffer,
910 MAX_GUID_STRING_LEN,
911 &ulLength,
912 ulFlags);
913 }
914 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
915 {
916 ret = RpcStatusToCmStatus(RpcExceptionCode());
917 }
918 RpcEndExcept;
919
920 if (ret == CR_SUCCESS)
921 {
922 /* Remove the {} */
923 szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
924
925 /* Convert the buffer to a GUID */
926 if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
927 return CR_FAILURE;
928 }
929
930 return ret;
931 }
932
933
934 /***********************************************************************
935 * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
936 */
937 CONFIGRET WINAPI CM_Enumerate_EnumeratorsA(
938 ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
939 {
940 TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
941 return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
942 ulFlags, NULL);
943 }
944
945
946 /***********************************************************************
947 * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
948 */
949 CONFIGRET WINAPI CM_Enumerate_EnumeratorsW(
950 ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
951 {
952 TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
953 return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
954 ulFlags, NULL);
955 }
956
957
958 /***********************************************************************
959 * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
960 */
961 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExA(
962 ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
963 HMACHINE hMachine)
964 {
965 WCHAR szBuffer[MAX_DEVICE_ID_LEN];
966 ULONG ulOrigLength;
967 ULONG ulLength;
968 CONFIGRET ret = CR_SUCCESS;
969
970 TRACE("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
971 hMachine);
972
973 if (Buffer == NULL || pulLength == NULL)
974 return CR_INVALID_POINTER;
975
976 if (ulFlags != 0)
977 return CR_INVALID_FLAG;
978
979 ulOrigLength = *pulLength;
980 *pulLength = 0;
981
982 ulLength = MAX_DEVICE_ID_LEN;
983 ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
984 ulFlags, hMachine);
985 if (ret == CR_SUCCESS)
986 {
987 if (WideCharToMultiByte(CP_ACP,
988 0,
989 szBuffer,
990 ulLength,
991 Buffer,
992 ulOrigLength,
993 NULL,
994 NULL) == 0)
995 ret = CR_FAILURE;
996 else
997 *pulLength = lstrlenA(Buffer) + 1;
998 }
999
1000 return ret;
1001 }
1002
1003
1004 /***********************************************************************
1005 * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
1006 */
1007 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExW(
1008 ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
1009 HMACHINE hMachine)
1010 {
1011 RPC_BINDING_HANDLE BindingHandle = NULL;
1012 CONFIGRET ret;
1013
1014 TRACE("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
1015 hMachine);
1016
1017 if (Buffer == NULL || pulLength == NULL)
1018 return CR_INVALID_POINTER;
1019
1020 if (ulFlags != 0)
1021 return CR_INVALID_FLAG;
1022
1023 *Buffer = UNICODE_NULL;
1024
1025 if (hMachine != NULL)
1026 {
1027 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1028 if (BindingHandle == NULL)
1029 return CR_FAILURE;
1030 }
1031 else
1032 {
1033 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1034 return CR_FAILURE;
1035 }
1036
1037 RpcTryExcept
1038 {
1039 ret = PNP_EnumerateSubKeys(BindingHandle,
1040 PNP_ENUMERATOR_SUBKEYS,
1041 ulEnumIndex,
1042 Buffer,
1043 *pulLength,
1044 pulLength,
1045 ulFlags);
1046 }
1047 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1048 {
1049 ret = RpcStatusToCmStatus(RpcExceptionCode());
1050 }
1051 RpcEndExcept;
1052
1053 return ret;
1054 }
1055
1056
1057 /***********************************************************************
1058 * CM_Free_Log_Conf [SETUPAPI.@]
1059 */
1060 CONFIGRET WINAPI CM_Free_Log_Conf(
1061 LOG_CONF lcLogConfToBeFreed, ULONG ulFlags)
1062 {
1063 TRACE("%lx %lx\n", lcLogConfToBeFreed, ulFlags);
1064 return CM_Free_Log_Conf_Ex(lcLogConfToBeFreed, ulFlags, NULL);
1065 }
1066
1067
1068 /***********************************************************************
1069 * CM_Free_Log_Conf_Ex [SETUPAPI.@]
1070 */
1071 CONFIGRET WINAPI CM_Free_Log_Conf_Ex(
1072 LOG_CONF lcLogConfToBeFreed, ULONG ulFlags, HMACHINE hMachine)
1073 {
1074 RPC_BINDING_HANDLE BindingHandle = NULL;
1075 HSTRING_TABLE StringTable = NULL;
1076 LPWSTR lpDevInst;
1077 PLOG_CONF_INFO pLogConfInfo;
1078 CONFIGRET ret;
1079
1080 TRACE("%lx %lx %lx\n", lcLogConfToBeFreed, ulFlags, hMachine);
1081
1082 if (!IsUserAdmin())
1083 return CR_ACCESS_DENIED;
1084
1085 pLogConfInfo = (PLOG_CONF_INFO)lcLogConfToBeFreed;
1086 if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
1087 return CR_INVALID_LOG_CONF;
1088
1089 if (ulFlags != 0)
1090 return CR_INVALID_FLAG;
1091
1092 if (hMachine != NULL)
1093 {
1094 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1095 if (BindingHandle == NULL)
1096 return CR_FAILURE;
1097
1098 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1099 if (StringTable == 0)
1100 return CR_FAILURE;
1101 }
1102 else
1103 {
1104 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1105 return CR_FAILURE;
1106 }
1107
1108 lpDevInst = StringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
1109 if (lpDevInst == NULL)
1110 return CR_INVALID_DEVNODE;
1111
1112 RpcTryExcept
1113 {
1114 ret = PNP_FreeLogConf(BindingHandle, lpDevInst, pLogConfInfo->ulFlags,
1115 pLogConfInfo->ulTag, 0);
1116 }
1117 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1118 {
1119 ret = RpcStatusToCmStatus(RpcExceptionCode());
1120 }
1121 RpcEndExcept;
1122
1123 return ret;
1124 }
1125
1126
1127 /***********************************************************************
1128 * CM_Free_Log_Conf_Handle [SETUPAPI.@]
1129 */
1130 CONFIGRET WINAPI CM_Free_Log_Conf_Handle(
1131 LOG_CONF lcLogConf)
1132 {
1133 PLOG_CONF_INFO pLogConfInfo;
1134
1135 TRACE("%lx\n", lcLogConf);
1136
1137 pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
1138 if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
1139 return CR_INVALID_LOG_CONF;
1140
1141 HeapFree(GetProcessHeap(), 0, pLogConfInfo);
1142
1143 return CR_SUCCESS;
1144 }
1145
1146
1147 /***********************************************************************
1148 * CM_Get_Child [SETUPAPI.@]
1149 */
1150 CONFIGRET WINAPI CM_Get_Child(
1151 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
1152 {
1153 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
1154 return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
1155 }
1156
1157
1158 /***********************************************************************
1159 * CM_Get_Child_Ex [SETUPAPI.@]
1160 */
1161 CONFIGRET WINAPI CM_Get_Child_Ex(
1162 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1163 {
1164 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
1165 RPC_BINDING_HANDLE BindingHandle = NULL;
1166 HSTRING_TABLE StringTable = NULL;
1167 LPWSTR lpDevInst;
1168 DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
1169 CONFIGRET ret;
1170
1171 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
1172
1173 if (pdnDevInst == NULL)
1174 return CR_INVALID_POINTER;
1175
1176 if (dnDevInst == 0)
1177 return CR_INVALID_DEVINST;
1178
1179 if (ulFlags != 0)
1180 return CR_INVALID_FLAG;
1181
1182 *pdnDevInst = -1;
1183
1184 if (hMachine != NULL)
1185 {
1186 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1187 if (BindingHandle == NULL)
1188 return CR_FAILURE;
1189
1190 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1191 if (StringTable == 0)
1192 return CR_FAILURE;
1193 }
1194 else
1195 {
1196 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1197 return CR_FAILURE;
1198 }
1199
1200 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1201 if (lpDevInst == NULL)
1202 return CR_INVALID_DEVNODE;
1203
1204 RpcTryExcept
1205 {
1206 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
1207 PNP_GET_CHILD_DEVICE_INSTANCE,
1208 lpDevInst,
1209 szRelatedDevInst,
1210 &dwLength,
1211 0);
1212 }
1213 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1214 {
1215 ret = RpcStatusToCmStatus(RpcExceptionCode());
1216 }
1217 RpcEndExcept;
1218
1219 if (ret != CR_SUCCESS)
1220 return ret;
1221
1222 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
1223
1224 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
1225 if (dwIndex == -1)
1226 return CR_FAILURE;
1227
1228 *pdnDevInst = dwIndex;
1229
1230 return CR_SUCCESS;
1231 }
1232
1233
1234 /***********************************************************************
1235 * CM_Get_Class_Key_NameA [SETUPAPI.@]
1236 */
1237 CONFIGRET WINAPI CM_Get_Class_Key_NameA(
1238 LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
1239 {
1240 TRACE("%p %p %p %lx\n",
1241 ClassGuid, pszKeyName, pulLength, ulFlags);
1242 return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
1243 ulFlags, NULL);
1244 }
1245
1246
1247 /***********************************************************************
1248 * CM_Get_Class_Key_NameW [SETUPAPI.@]
1249 */
1250 CONFIGRET WINAPI CM_Get_Class_Key_NameW(
1251 LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
1252 {
1253 TRACE("%p %p %p %lx\n",
1254 ClassGuid, pszKeyName, pulLength, ulFlags);
1255 return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
1256 ulFlags, NULL);
1257 }
1258
1259
1260 /***********************************************************************
1261 * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
1262 */
1263 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExA(
1264 LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
1265 HMACHINE hMachine)
1266 {
1267 WCHAR szBuffer[MAX_GUID_STRING_LEN];
1268 CONFIGRET ret = CR_SUCCESS;
1269 ULONG ulLength;
1270 ULONG ulOrigLength;
1271
1272 TRACE("%p %p %p %lx %lx\n",
1273 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
1274
1275 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
1276 return CR_INVALID_POINTER;
1277
1278 ulOrigLength = *pulLength;
1279 *pulLength = 0;
1280
1281 ulLength = MAX_GUID_STRING_LEN;
1282 ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
1283 ulFlags, hMachine);
1284 if (ret == CR_SUCCESS)
1285 {
1286 if (WideCharToMultiByte(CP_ACP,
1287 0,
1288 szBuffer,
1289 ulLength,
1290 pszKeyName,
1291 ulOrigLength,
1292 NULL,
1293 NULL) == 0)
1294 ret = CR_FAILURE;
1295 else
1296 *pulLength = lstrlenA(pszKeyName) + 1;
1297 }
1298
1299 return CR_SUCCESS;
1300 }
1301
1302
1303 /***********************************************************************
1304 * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
1305 */
1306 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExW(
1307 LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
1308 HMACHINE hMachine)
1309 {
1310 TRACE("%p %p %p %lx %lx\n",
1311 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
1312
1313 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
1314 return CR_INVALID_POINTER;
1315
1316 if (ulFlags != 0)
1317 return CR_INVALID_FLAG;
1318
1319 if (*pulLength < MAX_GUID_STRING_LEN)
1320 {
1321 *pulLength = 0;
1322 return CR_BUFFER_SMALL;
1323 }
1324
1325 if (!GuidToString(ClassGuid, pszKeyName))
1326 return CR_INVALID_DATA;
1327
1328 *pulLength = MAX_GUID_STRING_LEN;
1329
1330 return CR_SUCCESS;
1331 }
1332
1333
1334 /***********************************************************************
1335 * CM_Get_Class_NameA [SETUPAPI.@]
1336 */
1337 CONFIGRET WINAPI CM_Get_Class_NameA(
1338 LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
1339 {
1340 TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
1341 return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
1342 NULL);
1343 }
1344
1345
1346 /***********************************************************************
1347 * CM_Get_Class_NameW [SETUPAPI.@]
1348 */
1349 CONFIGRET WINAPI CM_Get_Class_NameW(
1350 LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
1351 {
1352 TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
1353 return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
1354 NULL);
1355 }
1356
1357
1358 /***********************************************************************
1359 * CM_Get_Class_Name_ExA [SETUPAPI.@]
1360 */
1361 CONFIGRET WINAPI CM_Get_Class_Name_ExA(
1362 LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
1363 HMACHINE hMachine)
1364 {
1365 WCHAR szBuffer[MAX_CLASS_NAME_LEN];
1366 CONFIGRET ret = CR_SUCCESS;
1367 ULONG ulLength;
1368 ULONG ulOrigLength;
1369
1370 TRACE("%p %p %p %lx %lx\n",
1371 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
1372
1373 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
1374 return CR_INVALID_POINTER;
1375
1376 ulOrigLength = *pulLength;
1377 *pulLength = 0;
1378
1379 ulLength = MAX_CLASS_NAME_LEN;
1380 ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
1381 ulFlags, hMachine);
1382 if (ret == CR_SUCCESS)
1383 {
1384 if (WideCharToMultiByte(CP_ACP,
1385 0,
1386 szBuffer,
1387 ulLength,
1388 Buffer,
1389 ulOrigLength,
1390 NULL,
1391 NULL) == 0)
1392 ret = CR_FAILURE;
1393 else
1394 *pulLength = lstrlenA(Buffer) + 1;
1395 }
1396
1397 return ret;
1398 }
1399
1400
1401 /***********************************************************************
1402 * CM_Get_Class_Name_ExW [SETUPAPI.@]
1403 */
1404 CONFIGRET WINAPI
1405 CM_Get_Class_Name_ExW(
1406 LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
1407 HMACHINE hMachine)
1408 {
1409 WCHAR szGuidString[MAX_GUID_STRING_LEN];
1410 RPC_BINDING_HANDLE BindingHandle = NULL;
1411 CONFIGRET ret;
1412
1413 TRACE("%p %p %p %lx %lx\n",
1414 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
1415
1416 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
1417 return CR_INVALID_POINTER;
1418
1419 if (ulFlags != 0)
1420 return CR_INVALID_FLAG;
1421
1422 if (!GuidToString(ClassGuid, szGuidString))
1423 return CR_INVALID_DATA;
1424
1425 TRACE("Guid %s\n", debugstr_w(szGuidString));
1426
1427 if (hMachine != NULL)
1428 {
1429 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1430 if (BindingHandle == NULL)
1431 return CR_FAILURE;
1432 }
1433 else
1434 {
1435 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1436 return CR_FAILURE;
1437 }
1438
1439 RpcTryExcept
1440 {
1441 ret = PNP_GetClassName(BindingHandle,
1442 szGuidString,
1443 Buffer,
1444 pulLength,
1445 ulFlags);
1446 }
1447 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1448 {
1449 ret = RpcStatusToCmStatus(RpcExceptionCode());
1450 }
1451 RpcEndExcept;
1452
1453 return ret;
1454 }
1455
1456
1457 /***********************************************************************
1458 * CM_Get_Depth [SETUPAPI.@]
1459 */
1460 CONFIGRET WINAPI CM_Get_Depth(
1461 PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags)
1462 {
1463 TRACE("%p %lx %lx\n", pulDepth, dnDevInst, ulFlags);
1464 return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
1465 }
1466
1467
1468 /***********************************************************************
1469 * CM_Get_Depth_Ex [SETUPAPI.@]
1470 */
1471 CONFIGRET WINAPI CM_Get_Depth_Ex(
1472 PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1473 {
1474 RPC_BINDING_HANDLE BindingHandle = NULL;
1475 HSTRING_TABLE StringTable = NULL;
1476 LPWSTR lpDevInst;
1477 CONFIGRET ret;
1478
1479 TRACE("%p %lx %lx %lx\n",
1480 pulDepth, dnDevInst, ulFlags, hMachine);
1481
1482 if (pulDepth == NULL)
1483 return CR_INVALID_POINTER;
1484
1485 if (dnDevInst == 0)
1486 return CR_INVALID_DEVINST;
1487
1488 if (ulFlags != 0)
1489 return CR_INVALID_FLAG;
1490
1491 if (hMachine != NULL)
1492 {
1493 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1494 if (BindingHandle == NULL)
1495 return CR_FAILURE;
1496
1497 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1498 if (StringTable == 0)
1499 return CR_FAILURE;
1500 }
1501 else
1502 {
1503 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1504 return CR_FAILURE;
1505 }
1506
1507 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1508 if (lpDevInst == NULL)
1509 return CR_INVALID_DEVNODE;
1510
1511 RpcTryExcept
1512 {
1513 ret = PNP_GetDepth(BindingHandle,
1514 lpDevInst,
1515 pulDepth,
1516 ulFlags);
1517 }
1518 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1519 {
1520 ret = RpcStatusToCmStatus(RpcExceptionCode());
1521 }
1522 RpcEndExcept;
1523
1524 return ret;
1525 }
1526
1527
1528 /***********************************************************************
1529 * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
1530 */
1531 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA(
1532 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1533 PVOID Buffer, PULONG pulLength, ULONG ulFlags)
1534 {
1535 TRACE("%lx %lu %p %p %p %lx\n",
1536 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
1537
1538 return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
1539 pulRegDataType, Buffer,
1540 pulLength, ulFlags, NULL);
1541 }
1542
1543
1544 /***********************************************************************
1545 * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
1546 */
1547 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(
1548 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1549 PVOID Buffer, PULONG pulLength, ULONG ulFlags)
1550 {
1551 TRACE("%lx %lu %p %p %p %lx\n",
1552 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
1553
1554 return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
1555 pulRegDataType, Buffer,
1556 pulLength, ulFlags, NULL);
1557 }
1558
1559
1560 /***********************************************************************
1561 * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
1562 */
1563 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExA(
1564 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1565 PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
1566 {
1567 PVOID BufferW;
1568 ULONG LengthW;
1569 ULONG RegDataType = REG_NONE;
1570 CONFIGRET ret;
1571
1572 TRACE("%lx %lu %p %p %p %lx %lx\n",
1573 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
1574 ulFlags, hMachine);
1575
1576 if (!pulLength)
1577 return CR_INVALID_POINTER;
1578
1579 LengthW = *pulLength * sizeof(WCHAR);
1580 BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
1581
1582 if (!BufferW)
1583 return CR_OUT_OF_MEMORY;
1584
1585 ret = CM_Get_DevNode_Registry_Property_ExW(dnDevInst,
1586 ulProperty,
1587 &RegDataType,
1588 BufferW,
1589 &LengthW,
1590 ulFlags,
1591 hMachine);
1592
1593 if (ret == CR_SUCCESS)
1594 {
1595 if (RegDataType == REG_SZ || RegDataType == REG_EXPAND_SZ)
1596 {
1597 /* Do W->A conversion */
1598 *pulLength = WideCharToMultiByte(CP_ACP,
1599 0,
1600 BufferW,
1601 lstrlenW(BufferW) + 1,
1602 Buffer,
1603 *pulLength,
1604 NULL,
1605 NULL);
1606 if (*pulLength == 0)
1607 ret = CR_FAILURE;
1608 }
1609 else
1610 {
1611 /* Directly copy the value */
1612 if (LengthW <= *pulLength)
1613 memcpy(Buffer, BufferW, LengthW);
1614 else
1615 {
1616 *pulLength = LengthW;
1617 ret = CR_BUFFER_SMALL;
1618 }
1619 }
1620 }
1621
1622 if (pulRegDataType)
1623 *pulRegDataType = RegDataType;
1624
1625 HeapFree(GetProcessHeap(), 0, BufferW);
1626
1627 return ret;
1628 }
1629
1630
1631 /***********************************************************************
1632 * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
1633 */
1634 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW(
1635 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1636 PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
1637 {
1638 RPC_BINDING_HANDLE BindingHandle = NULL;
1639 HSTRING_TABLE StringTable = NULL;
1640 CONFIGRET ret = CR_SUCCESS;
1641 LPWSTR lpDevInst;
1642 ULONG ulDataType = 0;
1643 ULONG ulTransferLength = 0;
1644
1645 TRACE("%lx %lu %p %p %p %lx %lx\n",
1646 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
1647 ulFlags, hMachine);
1648
1649 if (dnDevInst == 0)
1650 return CR_INVALID_DEVNODE;
1651
1652 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
1653 return CR_INVALID_PROPERTY;
1654
1655 /* pulRegDataType is optional */
1656
1657 /* Buffer is optional */
1658
1659 if (pulLength == NULL)
1660 return CR_INVALID_POINTER;
1661
1662 if (*pulLength == 0)
1663 return CR_INVALID_POINTER;
1664
1665 if (ulFlags != 0)
1666 return CR_INVALID_FLAG;
1667
1668 if (hMachine != NULL)
1669 {
1670 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1671 if (BindingHandle == NULL)
1672 return CR_FAILURE;
1673
1674 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1675 if (StringTable == 0)
1676 return CR_FAILURE;
1677 }
1678 else
1679 {
1680 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1681 return CR_FAILURE;
1682 }
1683
1684 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1685 if (lpDevInst == NULL)
1686 return CR_INVALID_DEVNODE;
1687
1688 ulTransferLength = *pulLength;
1689
1690 RpcTryExcept
1691 {
1692 ret = PNP_GetDeviceRegProp(BindingHandle,
1693 lpDevInst,
1694 ulProperty,
1695 &ulDataType,
1696 Buffer,
1697 &ulTransferLength,
1698 pulLength,
1699 ulFlags);
1700 }
1701 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1702 {
1703 ret = RpcStatusToCmStatus(RpcExceptionCode());
1704 }
1705 RpcEndExcept;
1706
1707 if (ret == CR_SUCCESS)
1708 {
1709 if (pulRegDataType != NULL)
1710 *pulRegDataType = ulDataType;
1711 }
1712
1713 return ret;
1714 }
1715
1716
1717 /***********************************************************************
1718 * CM_Get_DevNode_Status [SETUPAPI.@]
1719 */
1720 CONFIGRET WINAPI CM_Get_DevNode_Status(
1721 PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
1722 ULONG ulFlags)
1723 {
1724 TRACE("%p %p %lx %lx\n",
1725 pulStatus, pulProblemNumber, dnDevInst, ulFlags);
1726 return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
1727 ulFlags, NULL);
1728 }
1729
1730
1731 /***********************************************************************
1732 * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
1733 */
1734 CONFIGRET WINAPI
1735 CM_Get_DevNode_Status_Ex(
1736 PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
1737 ULONG ulFlags, HMACHINE hMachine)
1738 {
1739 RPC_BINDING_HANDLE BindingHandle = NULL;
1740 HSTRING_TABLE StringTable = NULL;
1741 LPWSTR lpDevInst;
1742 CONFIGRET ret;
1743
1744 TRACE("%p %p %lx %lx %lx\n",
1745 pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
1746
1747 if (pulStatus == NULL || pulProblemNumber == NULL)
1748 return CR_INVALID_POINTER;
1749
1750 if (dnDevInst == 0)
1751 return CR_INVALID_DEVINST;
1752
1753 if (ulFlags != 0)
1754 return CR_INVALID_FLAG;
1755
1756 if (hMachine != NULL)
1757 {
1758 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1759 if (BindingHandle == NULL)
1760 return CR_FAILURE;
1761
1762 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1763 if (StringTable == 0)
1764 return CR_FAILURE;
1765 }
1766 else
1767 {
1768 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1769 return CR_FAILURE;
1770 }
1771
1772 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1773 if (lpDevInst == NULL)
1774 return CR_INVALID_DEVNODE;
1775
1776 RpcTryExcept
1777 {
1778 ret = PNP_GetDeviceStatus(BindingHandle,
1779 lpDevInst,
1780 pulStatus,
1781 pulProblemNumber,
1782 ulFlags);
1783 }
1784 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
1785 {
1786 ret = RpcStatusToCmStatus(RpcExceptionCode());
1787 }
1788 RpcEndExcept;
1789
1790 return ret;
1791 }
1792
1793
1794 /***********************************************************************
1795 * CM_Get_Device_IDA [SETUPAPI.@]
1796 */
1797 CONFIGRET WINAPI CM_Get_Device_IDA(
1798 DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1799 {
1800 TRACE("%lx %p %ld %ld\n",
1801 dnDevInst, Buffer, BufferLen, ulFlags);
1802 return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
1803 }
1804
1805
1806 /***********************************************************************
1807 * CM_Get_Device_IDW [SETUPAPI.@]
1808 */
1809 CONFIGRET WINAPI CM_Get_Device_IDW(
1810 DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1811 {
1812 TRACE("%lx %p %ld %ld\n",
1813 dnDevInst, Buffer, BufferLen, ulFlags);
1814 return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
1815 }
1816
1817
1818 /***********************************************************************
1819 * CM_Get_Device_ID_ExA [SETUPAPI.@]
1820 */
1821 CONFIGRET WINAPI CM_Get_Device_ID_ExA(
1822 DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1823 HMACHINE hMachine)
1824 {
1825 WCHAR szBufferW[MAX_DEVICE_ID_LEN];
1826 CONFIGRET ret = CR_SUCCESS;
1827
1828 FIXME("%lx %p %ld %ld %lx\n",
1829 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
1830
1831 if (Buffer == NULL)
1832 return CR_INVALID_POINTER;
1833
1834 ret = CM_Get_Device_ID_ExW(dnDevInst,
1835 szBufferW,
1836 MAX_DEVICE_ID_LEN,
1837 ulFlags,
1838 hMachine);
1839 if (ret == CR_SUCCESS)
1840 {
1841 if (WideCharToMultiByte(CP_ACP,
1842 0,
1843 szBufferW,
1844 lstrlenW(szBufferW) + 1,
1845 Buffer,
1846 BufferLen,
1847 NULL,
1848 NULL) == 0)
1849 ret = CR_FAILURE;
1850 }
1851
1852 return ret;
1853 }
1854
1855
1856 /***********************************************************************
1857 * CM_Get_Device_ID_ExW [SETUPAPI.@]
1858 */
1859 CONFIGRET WINAPI CM_Get_Device_ID_ExW(
1860 DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1861 HMACHINE hMachine)
1862 {
1863 HSTRING_TABLE StringTable = NULL;
1864
1865 TRACE("%lx %p %ld %ld %lx\n",
1866 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
1867
1868 if (dnDevInst == 0)
1869 return CR_INVALID_DEVINST;
1870
1871 if (Buffer == NULL)
1872 return CR_INVALID_POINTER;
1873
1874 if (ulFlags != 0)
1875 return CR_INVALID_FLAG;
1876
1877 if (hMachine != NULL)
1878 {
1879 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1880 if (StringTable == NULL)
1881 return CR_FAILURE;
1882 }
1883 else
1884 {
1885 if (!PnpGetLocalHandles(NULL, &StringTable))
1886 return CR_FAILURE;
1887 }
1888
1889 if (!StringTableStringFromIdEx(StringTable,
1890 dnDevInst,
1891 Buffer,
1892 &BufferLen))
1893 return CR_FAILURE;
1894
1895 return CR_SUCCESS;
1896 }
1897
1898
1899 /***********************************************************************
1900 * CM_Get_Device_ID_ListA [SETUPAPI.@]
1901 */
1902 CONFIGRET WINAPI CM_Get_Device_ID_ListA(
1903 PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1904 {
1905 TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
1906 return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
1907 ulFlags, NULL);
1908 }
1909
1910
1911 /***********************************************************************
1912 * CM_Get_Device_ID_ListW [SETUPAPI.@]
1913 */
1914 CONFIGRET WINAPI CM_Get_Device_ID_ListW(
1915 PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1916 {
1917 TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
1918 return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
1919 ulFlags, NULL);
1920 }
1921
1922
1923 /***********************************************************************
1924 * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
1925 */
1926 CONFIGRET WINAPI CM_Get_Device_ID_List_ExA(
1927 PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1928 HMACHINE hMachine)
1929 {
1930 LPWSTR BufferW = NULL;
1931 LPWSTR pszFilterW = NULL;
1932 CONFIGRET ret = CR_SUCCESS;
1933
1934 FIXME("%p %p %ld %ld %lx\n",
1935 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
1936
1937 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
1938 if (BufferW == NULL)
1939 return CR_OUT_OF_MEMORY;
1940
1941 if (pszFilter == NULL)
1942 {
1943 ret = CM_Get_Device_ID_List_ExW(NULL,
1944 BufferW,
1945 BufferLen,
1946 ulFlags,
1947 hMachine);
1948 }
1949 else
1950 {
1951 if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
1952 {
1953 ret = CR_INVALID_DEVICE_ID;
1954 goto Done;
1955 }
1956
1957 ret = CM_Get_Device_ID_List_ExW(pszFilterW,
1958 BufferW,
1959 BufferLen,
1960 ulFlags,
1961 hMachine);
1962
1963 MyFree(pszFilterW);
1964 }
1965
1966 if (WideCharToMultiByte(CP_ACP,
1967 0,
1968 BufferW,
1969 lstrlenW(BufferW) + 1,
1970 Buffer,
1971 BufferLen,
1972 NULL,
1973 NULL) == 0)
1974 ret = CR_FAILURE;
1975
1976 Done:
1977 MyFree(BufferW);
1978
1979 return ret;
1980 }
1981
1982
1983 /***********************************************************************
1984 * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
1985 */
1986 CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(
1987 PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1988 HMACHINE hMachine)
1989 {
1990 FIXME("%p %p %ld %ld %lx\n",
1991 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
1992 memset(Buffer,0,2);
1993 return CR_SUCCESS;
1994 }
1995
1996
1997 /***********************************************************************
1998 * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
1999 */
2000 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(
2001 PULONG pulLen, PCSTR pszFilter, ULONG ulFlags)
2002 {
2003 TRACE("%p %s %ld\n", pulLen, pszFilter, ulFlags);
2004 return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
2005 }
2006
2007
2008 /***********************************************************************
2009 * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
2010 */
2011 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(
2012 PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags)
2013 {
2014 TRACE("%p %s %ld\n", pulLen, debugstr_w(pszFilter), ulFlags);
2015 return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
2016 }
2017
2018
2019 /***********************************************************************
2020 * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
2021 */
2022 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA(
2023 PULONG pulLen, PCSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
2024 {
2025 LPWSTR pszFilterW = NULL;
2026 CONFIGRET ret = CR_SUCCESS;
2027
2028 FIXME("%p %s %lx %lx\n", pulLen, pszFilter, ulFlags, hMachine);
2029
2030 if (pszFilter == NULL)
2031 {
2032 ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
2033 NULL,
2034 ulFlags,
2035 hMachine);
2036 }
2037 else
2038 {
2039 if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
2040 return CR_INVALID_DEVICE_ID;
2041
2042 ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
2043 pszFilterW,
2044 ulFlags,
2045 hMachine);
2046
2047 MyFree(pszFilterW);
2048 }
2049
2050 return ret;
2051 }
2052
2053
2054 /***********************************************************************
2055 * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
2056 */
2057 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(
2058 PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
2059 {
2060 RPC_BINDING_HANDLE BindingHandle = NULL;
2061 CONFIGRET ret;
2062
2063 FIXME("%p %s %ld %lx\n", pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
2064
2065 if (pulLen == NULL)
2066 return CR_INVALID_POINTER;
2067
2068 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
2069 return CR_INVALID_FLAG;
2070
2071 if (hMachine != NULL)
2072 {
2073 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2074 if (BindingHandle == NULL)
2075 return CR_FAILURE;
2076 }
2077 else
2078 {
2079 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2080 return CR_FAILURE;
2081 }
2082
2083 *pulLen = 0;
2084
2085 RpcTryExcept
2086 {
2087 ret = PNP_GetDeviceListSize(BindingHandle,
2088 (LPWSTR)pszFilter,
2089 pulLen,
2090 ulFlags);
2091 }
2092 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2093 {
2094 ret = RpcStatusToCmStatus(RpcExceptionCode());
2095 }
2096 RpcEndExcept;
2097
2098 return ret;
2099 }
2100
2101
2102 /***********************************************************************
2103 * CM_Get_Device_ID_Size [SETUPAPI.@]
2104 */
2105 CONFIGRET WINAPI CM_Get_Device_ID_Size(
2106 PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags)
2107 {
2108 TRACE("%p %lx %lx\n", pulLen, dnDevInst, ulFlags);
2109 return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
2110 }
2111
2112
2113 /***********************************************************************
2114 * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
2115 */
2116 CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex(
2117 PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
2118 {
2119 HSTRING_TABLE StringTable = NULL;
2120 LPWSTR DeviceId;
2121
2122 TRACE("%p %lx %lx %lx\n", pulLen, dnDevInst, ulFlags, hMachine);
2123
2124 if (pulLen == NULL)
2125 return CR_INVALID_POINTER;
2126
2127 if (dnDevInst == 0)
2128 return CR_INVALID_DEVINST;
2129
2130 if (ulFlags != 0)
2131 return CR_INVALID_FLAG;
2132
2133 if (hMachine != NULL)
2134 {
2135 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2136 if (StringTable == NULL)
2137 return CR_FAILURE;
2138 }
2139 else
2140 {
2141 if (!PnpGetLocalHandles(NULL, &StringTable))
2142 return CR_FAILURE;
2143 }
2144
2145 DeviceId = StringTableStringFromId(StringTable, dnDevInst);
2146 if (DeviceId == NULL)
2147 {
2148 *pulLen = 0;
2149 return CR_SUCCESS;
2150 }
2151
2152 *pulLen = lstrlenW(DeviceId);
2153
2154 return CR_SUCCESS;
2155 }
2156
2157
2158 /***********************************************************************
2159 * CM_Get_First_Log_Conf [SETUPAPI.@]
2160 */
2161 CONFIGRET WINAPI CM_Get_First_Log_Conf(
2162 PLOG_CONF plcLogConf, DEVINST dnDevInst, ULONG ulFlags)
2163 {
2164 TRACE("%p %lx %lx\n", plcLogConf, dnDevInst, ulFlags);
2165 return CM_Get_First_Log_Conf_Ex(plcLogConf, dnDevInst, ulFlags, NULL);
2166 }
2167
2168
2169 /***********************************************************************
2170 * CM_Get_First_Log_Conf_Ex [SETUPAPI.@]
2171 */
2172 CONFIGRET WINAPI CM_Get_First_Log_Conf_Ex(
2173 PLOG_CONF plcLogConf, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
2174 {
2175 RPC_BINDING_HANDLE BindingHandle = NULL;
2176 HSTRING_TABLE StringTable = NULL;
2177 LPWSTR lpDevInst = NULL;
2178 CONFIGRET ret = CR_SUCCESS;
2179 ULONG ulTag;
2180 PLOG_CONF_INFO pLogConfInfo;
2181
2182 FIXME("%p %lx %lx %lx\n", plcLogConf, dnDevInst, ulFlags, hMachine);
2183
2184 if (dnDevInst == 0)
2185 return CR_INVALID_DEVINST;
2186
2187 if (ulFlags & ~LOG_CONF_BITS)
2188 return CR_INVALID_FLAG;
2189
2190 if (plcLogConf)
2191 *plcLogConf = 0;
2192
2193 if (hMachine != NULL)
2194 {
2195 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2196 if (BindingHandle == NULL)
2197 return CR_FAILURE;
2198
2199 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2200 if (StringTable == 0)
2201 return CR_FAILURE;
2202 }
2203 else
2204 {
2205 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2206 return CR_FAILURE;
2207 }
2208
2209 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2210 if (lpDevInst == NULL)
2211 return CR_INVALID_DEVNODE;
2212
2213 RpcTryExcept
2214 {
2215 ret = PNP_GetFirstLogConf(BindingHandle,
2216 lpDevInst,
2217 ulFlags,
2218 &ulTag,
2219 ulFlags);
2220 }
2221 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2222 {
2223 ret = RpcStatusToCmStatus(RpcExceptionCode());
2224 }
2225 RpcEndExcept;
2226
2227 if (ret != CR_SUCCESS)
2228 return ret;
2229
2230 pLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
2231 if (pLogConfInfo == NULL)
2232 return CR_OUT_OF_MEMORY;
2233
2234 pLogConfInfo->ulMagic = LOG_CONF_MAGIC;
2235 pLogConfInfo->dnDevInst = dnDevInst;
2236 pLogConfInfo->ulFlags = ulFlags;
2237 pLogConfInfo->ulTag = ulTag;
2238
2239 *plcLogConf = (LOG_CONF)pLogConfInfo;
2240
2241 return CR_SUCCESS;
2242 }
2243
2244
2245 /***********************************************************************
2246 * CM_Get_Global_State [SETUPAPI.@]
2247 */
2248 CONFIGRET WINAPI CM_Get_Global_State(
2249 PULONG pulState, ULONG ulFlags)
2250 {
2251 TRACE("%p %lx\n", pulState, ulFlags);
2252 return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
2253 }
2254
2255
2256 /***********************************************************************
2257 * CM_Get_Global_State_Ex [SETUPAPI.@]
2258 */
2259 CONFIGRET WINAPI CM_Get_Global_State_Ex(
2260 PULONG pulState, ULONG ulFlags, HMACHINE hMachine)
2261 {
2262 RPC_BINDING_HANDLE BindingHandle = NULL;
2263 CONFIGRET ret;
2264
2265 TRACE("%p %lx %lx\n", pulState, ulFlags, hMachine);
2266
2267 if (pulState == NULL)
2268 return CR_INVALID_POINTER;
2269
2270 if (ulFlags != 0)
2271 return CR_INVALID_FLAG;
2272
2273 if (hMachine != NULL)
2274 {
2275 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2276 if (BindingHandle == NULL)
2277 return CR_FAILURE;
2278 }
2279 else
2280 {
2281 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2282 return CR_FAILURE;
2283 }
2284
2285 RpcTryExcept
2286 {
2287 ret = PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
2288 }
2289 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2290 {
2291 ret = RpcStatusToCmStatus(RpcExceptionCode());
2292 }
2293 RpcEndExcept;
2294
2295 return ret;
2296 }
2297
2298
2299 /***********************************************************************
2300 * CM_Get_HW_Prof_FlagsA [SETUPAPI.@]
2301 */
2302 CONFIGRET WINAPI CM_Get_HW_Prof_FlagsA(
2303 DEVINSTID_A szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
2304 ULONG ulFlags)
2305 {
2306 TRACE("%s %lu %p %lx\n", szDevInstName,
2307 ulHardwareProfile, pulValue, ulFlags);
2308
2309 return CM_Get_HW_Prof_Flags_ExA(szDevInstName, ulHardwareProfile,
2310 pulValue, ulFlags, NULL);
2311 }
2312
2313
2314 /***********************************************************************
2315 * CM_Get_HW_Prof_FlagsW [SETUPAPI.@]
2316 */
2317 CONFIGRET WINAPI CM_Get_HW_Prof_FlagsW(
2318 DEVINSTID_W szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
2319 ULONG ulFlags)
2320 {
2321 TRACE("%s %lu %p %lx\n", debugstr_w(szDevInstName),
2322 ulHardwareProfile, pulValue, ulFlags);
2323
2324 return CM_Get_HW_Prof_Flags_ExW(szDevInstName, ulHardwareProfile,
2325 pulValue, ulFlags, NULL);
2326 }
2327
2328
2329 /***********************************************************************
2330 * CM_Get_HW_Prof_Flags_ExA [SETUPAPI.@]
2331 */
2332 CONFIGRET WINAPI CM_Get_HW_Prof_Flags_ExA(
2333 DEVINSTID_A szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
2334 ULONG ulFlags, HMACHINE hMachine)
2335 {
2336 DEVINSTID_W pszDevIdW = NULL;
2337 CONFIGRET ret = CR_SUCCESS;
2338
2339 TRACE("%s %lu %p %lx %lx\n", szDevInstName,
2340 ulHardwareProfile, pulValue, ulFlags, hMachine);
2341
2342 if (szDevInstName != NULL)
2343 {
2344 if (CaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
2345 return CR_INVALID_DEVICE_ID;
2346 }
2347
2348 ret = CM_Get_HW_Prof_Flags_ExW(pszDevIdW, ulHardwareProfile,
2349 pulValue, ulFlags, hMachine);
2350
2351 if (pszDevIdW != NULL)
2352 MyFree(pszDevIdW);
2353
2354 return ret;
2355 }
2356
2357
2358 /***********************************************************************
2359 * CM_Get_HW_Prof_Flags_ExW [SETUPAPI.@]
2360 */
2361 CONFIGRET WINAPI CM_Get_HW_Prof_Flags_ExW(
2362 DEVINSTID_W szDevInstName, ULONG ulHardwareProfile, PULONG pulValue,
2363 ULONG ulFlags, HMACHINE hMachine)
2364 {
2365 RPC_BINDING_HANDLE BindingHandle = NULL;
2366 CONFIGRET ret;
2367
2368 FIXME("%s %lu %p %lx %lx\n", debugstr_w(szDevInstName),
2369 ulHardwareProfile, pulValue, ulFlags, hMachine);
2370
2371 if ((szDevInstName == NULL) || (pulValue == NULL))
2372 return CR_INVALID_POINTER;
2373
2374 if (ulFlags != 0)
2375 return CR_INVALID_FLAG;
2376
2377 /* FIXME: Check whether szDevInstName is valid */
2378
2379 if (hMachine != NULL)
2380 {
2381 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2382 if (BindingHandle == NULL)
2383 return CR_FAILURE;
2384 }
2385 else
2386 {
2387 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2388 return CR_FAILURE;
2389 }
2390
2391 RpcTryExcept
2392 {
2393 ret = PNP_HwProfFlags(BindingHandle, PNP_GET_HWPROFFLAGS, szDevInstName,
2394 ulHardwareProfile, pulValue, NULL, NULL, 0, 0);
2395 }
2396 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2397 {
2398 ret = RpcStatusToCmStatus(RpcExceptionCode());
2399 }
2400 RpcEndExcept;
2401
2402 return ret;
2403 }
2404
2405
2406 /***********************************************************************
2407 * CM_Get_Log_Conf_Priority [SETUPAPI.@]
2408 */
2409 CONFIGRET WINAPI CM_Get_Log_Conf_Priority(
2410 LOG_CONF lcLogConf, PPRIORITY pPriority, ULONG ulFlags)
2411 {
2412 TRACE("%p %p %lx\n", lcLogConf, pPriority, ulFlags);
2413 return CM_Get_Log_Conf_Priority_Ex(lcLogConf, pPriority, ulFlags, NULL);
2414 }
2415
2416
2417 /***********************************************************************
2418 * CM_Get_Log_Conf_Priority_Ex [SETUPAPI.@]
2419 */
2420 CONFIGRET WINAPI CM_Get_Log_Conf_Priority_Ex(
2421 LOG_CONF lcLogConf, PPRIORITY pPriority, ULONG ulFlags,
2422 HMACHINE hMachine)
2423 {
2424 RPC_BINDING_HANDLE BindingHandle = NULL;
2425 HSTRING_TABLE StringTable = NULL;
2426 PLOG_CONF_INFO pLogConfInfo;
2427 LPWSTR lpDevInst;
2428 CONFIGRET ret;
2429
2430 FIXME("%p %p %lx %lx\n", lcLogConf, pPriority, ulFlags, hMachine);
2431
2432 pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
2433 if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
2434 return CR_INVALID_LOG_CONF;
2435
2436 if (pPriority == NULL)
2437 return CR_INVALID_POINTER;
2438
2439 if (ulFlags != 0)
2440 return CR_INVALID_FLAG;
2441
2442 if (hMachine != NULL)
2443 {
2444 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2445 if (BindingHandle == NULL)
2446 return CR_FAILURE;
2447
2448 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2449 if (StringTable == 0)
2450 return CR_FAILURE;
2451 }
2452 else
2453 {
2454 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2455 return CR_FAILURE;
2456 }
2457
2458 lpDevInst = StringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
2459 if (lpDevInst == NULL)
2460 return CR_INVALID_DEVNODE;
2461
2462 RpcTryExcept
2463 {
2464 ret = PNP_GetLogConfPriority(BindingHandle,
2465 lpDevInst,
2466 pLogConfInfo->ulFlags,
2467 pLogConfInfo->ulTag,
2468 pPriority,
2469 0);
2470 }
2471 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2472 {
2473 ret = RpcStatusToCmStatus(RpcExceptionCode());
2474 }
2475 RpcEndExcept;
2476
2477 return ret;
2478 }
2479
2480
2481 /***********************************************************************
2482 * CM_Get_Next_Log_Conf [SETUPAPI.@]
2483 */
2484 CONFIGRET WINAPI CM_Get_Next_Log_Conf(
2485 PLOG_CONF plcLogConf, LOG_CONF lcLogConf, ULONG ulFlags)
2486 {
2487 TRACE("%p %p %lx\n", plcLogConf, lcLogConf, ulFlags);
2488 return CM_Get_Next_Log_Conf_Ex(plcLogConf, lcLogConf, ulFlags, NULL);
2489 }
2490
2491
2492 /***********************************************************************
2493 * CM_Get_Next_Log_Conf_Ex [SETUPAPI.@]
2494 */
2495 CONFIGRET WINAPI CM_Get_Next_Log_Conf_Ex(
2496 PLOG_CONF plcLogConf, LOG_CONF lcLogConf, ULONG ulFlags,
2497 HMACHINE hMachine)
2498 {
2499 RPC_BINDING_HANDLE BindingHandle = NULL;
2500 HSTRING_TABLE StringTable = NULL;
2501 PLOG_CONF_INFO pLogConfInfo;
2502 PLOG_CONF_INFO pNewLogConfInfo;
2503 ULONG ulNewTag;
2504 LPWSTR lpDevInst;
2505 CONFIGRET ret;
2506
2507 FIXME("%p %p %lx %lx\n", plcLogConf, lcLogConf, ulFlags, hMachine);
2508
2509 if (plcLogConf)
2510 *plcLogConf = 0;
2511
2512 pLogConfInfo = (PLOG_CONF_INFO)lcLogConf;
2513 if (pLogConfInfo == NULL || pLogConfInfo->ulMagic != LOG_CONF_MAGIC)
2514 return CR_INVALID_LOG_CONF;
2515
2516 if (ulFlags != 0)
2517 return CR_INVALID_FLAG;
2518
2519 if (hMachine != NULL)
2520 {
2521 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2522 if (BindingHandle == NULL)
2523 return CR_FAILURE;
2524
2525 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2526 if (StringTable == 0)
2527 return CR_FAILURE;
2528 }
2529 else
2530 {
2531 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2532 return CR_FAILURE;
2533 }
2534
2535 lpDevInst = StringTableStringFromId(StringTable, pLogConfInfo->dnDevInst);
2536 if (lpDevInst == NULL)
2537 return CR_INVALID_DEVNODE;
2538
2539 RpcTryExcept
2540 {
2541 ret = PNP_GetNextLogConf(BindingHandle,
2542 lpDevInst,
2543 pLogConfInfo->ulFlags,
2544 pLogConfInfo->ulTag,
2545 &ulNewTag,
2546 0);
2547 }
2548 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2549 {
2550 ret = RpcStatusToCmStatus(RpcExceptionCode());
2551 }
2552 RpcEndExcept;
2553
2554 if (ret != CR_SUCCESS)
2555 return ret;
2556
2557 if (plcLogConf)
2558 {
2559 pNewLogConfInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(LOG_CONF_INFO));
2560 if (pNewLogConfInfo == NULL)
2561 return CR_OUT_OF_MEMORY;
2562
2563 pNewLogConfInfo->ulMagic = LOG_CONF_MAGIC;
2564 pNewLogConfInfo->dnDevInst = pLogConfInfo->dnDevInst;
2565 pNewLogConfInfo->ulFlags = pLogConfInfo->ulFlags;
2566 pNewLogConfInfo->ulTag = ulNewTag;
2567
2568 *plcLogConf = (LOG_CONF)pNewLogConfInfo;
2569 }
2570
2571 return CR_SUCCESS;
2572 }
2573
2574
2575 /***********************************************************************
2576 * CM_Get_Parent [SETUPAPI.@]
2577 */
2578 CONFIGRET WINAPI CM_Get_Parent(
2579 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
2580 {
2581 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
2582 return CM_Get_Parent_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
2583 }
2584
2585
2586 /***********************************************************************
2587 * CM_Get_Parent_Ex [SETUPAPI.@]
2588 */
2589 CONFIGRET WINAPI CM_Get_Parent_Ex(
2590 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
2591 {
2592 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
2593 RPC_BINDING_HANDLE BindingHandle = NULL;
2594 HSTRING_TABLE StringTable = NULL;
2595 LPWSTR lpDevInst;
2596 DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
2597 CONFIGRET ret;
2598
2599 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
2600
2601 if (pdnDevInst == NULL)
2602 return CR_INVALID_POINTER;
2603
2604 if (dnDevInst == 0)
2605 return CR_INVALID_DEVINST;
2606
2607 if (ulFlags != 0)
2608 return CR_INVALID_FLAG;
2609
2610 *pdnDevInst = -1;
2611
2612 if (hMachine != NULL)
2613 {
2614 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2615 if (BindingHandle == NULL)
2616 return CR_FAILURE;
2617
2618 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2619 if (StringTable == 0)
2620 return CR_FAILURE;
2621 }
2622 else
2623 {
2624 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2625 return CR_FAILURE;
2626 }
2627
2628 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2629 if (lpDevInst == NULL)
2630 return CR_INVALID_DEVNODE;
2631
2632 RpcTryExcept
2633 {
2634 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
2635 PNP_GET_PARENT_DEVICE_INSTANCE,
2636 lpDevInst,
2637 szRelatedDevInst,
2638 &dwLength,
2639 0);
2640 }
2641 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2642 {
2643 ret = RpcStatusToCmStatus(RpcExceptionCode());
2644 }
2645 RpcEndExcept;
2646
2647 if (ret != CR_SUCCESS)
2648 return ret;
2649
2650 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
2651
2652 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
2653 if (dwIndex == -1)
2654 return CR_FAILURE;
2655
2656 *pdnDevInst = dwIndex;
2657
2658 return CR_SUCCESS;
2659 }
2660
2661
2662 /***********************************************************************
2663 * CM_Get_Sibling [SETUPAPI.@]
2664 */
2665 CONFIGRET WINAPI CM_Get_Sibling(
2666 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
2667 {
2668 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
2669 return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
2670 }
2671
2672
2673 /***********************************************************************
2674 * CM_Get_Sibling_Ex [SETUPAPI.@]
2675 */
2676 CONFIGRET WINAPI CM_Get_Sibling_Ex(
2677 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
2678 {
2679 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
2680 RPC_BINDING_HANDLE BindingHandle = NULL;
2681 HSTRING_TABLE StringTable = NULL;
2682 LPWSTR lpDevInst;
2683 DWORD dwIndex, dwLength = MAX_DEVICE_ID_LEN;
2684 CONFIGRET ret;
2685
2686 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
2687
2688 if (pdnDevInst == NULL)
2689 return CR_INVALID_POINTER;
2690
2691 if (dnDevInst == 0)
2692 return CR_INVALID_DEVINST;
2693
2694 if (ulFlags != 0)
2695 return CR_INVALID_FLAG;
2696
2697 *pdnDevInst = -1;
2698
2699 if (hMachine != NULL)
2700 {
2701 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2702 if (BindingHandle == NULL)
2703 return CR_FAILURE;
2704
2705 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2706 if (StringTable == 0)
2707 return CR_FAILURE;
2708 }
2709 else
2710 {
2711 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2712 return CR_FAILURE;
2713 }
2714
2715 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2716 if (lpDevInst == NULL)
2717 return CR_INVALID_DEVNODE;
2718
2719 RpcTryExcept
2720 {
2721 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
2722 PNP_GET_SIBLING_DEVICE_INSTANCE,
2723 lpDevInst,
2724 szRelatedDevInst,
2725 &dwLength,
2726 0);
2727 }
2728 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2729 {
2730 ret = RpcStatusToCmStatus(RpcExceptionCode());
2731 }
2732 RpcEndExcept;
2733
2734 if (ret != CR_SUCCESS)
2735 return ret;
2736
2737 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
2738
2739 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
2740 if (dwIndex == -1)
2741 return CR_FAILURE;
2742
2743 *pdnDevInst = dwIndex;
2744
2745 return CR_SUCCESS;
2746 }
2747
2748
2749 /***********************************************************************
2750 * CM_Get_Version [SETUPAPI.@]
2751 */
2752 WORD WINAPI CM_Get_Version(VOID)
2753 {
2754 TRACE("\n");
2755 return CM_Get_Version_Ex(NULL);
2756 }
2757
2758
2759 /***********************************************************************
2760 * CM_Get_Version_Ex [SETUPAPI.@]
2761 */
2762 WORD WINAPI CM_Get_Version_Ex(HMACHINE hMachine)
2763 {
2764 RPC_BINDING_HANDLE BindingHandle = NULL;
2765 WORD Version = 0;
2766 CONFIGRET ret;
2767
2768 TRACE("%lx\n", hMachine);
2769
2770 if (hMachine != NULL)
2771 {
2772 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2773 if (BindingHandle == NULL)
2774 return 0;
2775 }
2776 else
2777 {
2778 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2779 return CR_FAILURE;
2780 }
2781
2782 RpcTryExcept
2783 {
2784 ret = PNP_GetVersion(BindingHandle, &Version);
2785 }
2786 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2787 {
2788 ret = RpcStatusToCmStatus(RpcExceptionCode());
2789 }
2790 RpcEndExcept;
2791
2792 if (ret != CR_SUCCESS)
2793 return 0;
2794
2795 return Version;
2796 }
2797
2798
2799 /***********************************************************************
2800 * CM_Is_Dock_Station_Present [SETUPAPI.@]
2801 */
2802 CONFIGRET WINAPI CM_Is_Dock_Station_Present(
2803 PBOOL pbPresent)
2804 {
2805 TRACE("%p\n", pbPresent);
2806 return CM_Is_Dock_Station_Present_Ex(pbPresent, NULL);
2807 }
2808
2809
2810 /***********************************************************************
2811 * CM_Is_Dock_Station_Present_Ex [SETUPAPI.@]
2812 */
2813 CONFIGRET WINAPI CM_Is_Dock_Station_Present_Ex(
2814 PBOOL pbPresent, HMACHINE hMachine)
2815 {
2816 RPC_BINDING_HANDLE BindingHandle = NULL;
2817 CONFIGRET ret;
2818
2819 TRACE("%p %lx\n", pbPresent, hMachine);
2820
2821 if (pbPresent == NULL)
2822 return CR_INVALID_POINTER;
2823
2824 *pbPresent = FALSE;
2825
2826 if (hMachine != NULL)
2827 {
2828 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2829 if (BindingHandle == NULL)
2830 return CR_FAILURE;
2831 }
2832 else
2833 {
2834 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2835 return CR_FAILURE;
2836 }
2837
2838 RpcTryExcept
2839 {
2840 ret = PNP_IsDockStationPresent(BindingHandle,
2841 pbPresent);
2842 }
2843 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2844 {
2845 ret = RpcStatusToCmStatus(RpcExceptionCode());
2846 }
2847 RpcEndExcept;
2848
2849 return ret;
2850 }
2851
2852
2853 /***********************************************************************
2854 * CM_Locate_DevNodeA [SETUPAPI.@]
2855 */
2856 CONFIGRET WINAPI CM_Locate_DevNodeA(
2857 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
2858 {
2859 TRACE("%p %s %lu\n", pdnDevInst, pDeviceID, ulFlags);
2860 return CM_Locate_DevNode_ExA(pdnDevInst, pDeviceID, ulFlags, NULL);
2861 }
2862
2863
2864 /***********************************************************************
2865 * CM_Locate_DevNodeW [SETUPAPI.@]
2866 */
2867 CONFIGRET WINAPI CM_Locate_DevNodeW(
2868 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags)
2869 {
2870 TRACE("%p %s %lu\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags);
2871 return CM_Locate_DevNode_ExW(pdnDevInst, pDeviceID, ulFlags, NULL);
2872 }
2873
2874
2875 /***********************************************************************
2876 * CM_Locate_DevNode_ExA [SETUPAPI.@]
2877 */
2878 CONFIGRET WINAPI CM_Locate_DevNode_ExA(
2879 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine)
2880 {
2881 DEVINSTID_W pDevIdW = NULL;
2882 CONFIGRET ret = CR_SUCCESS;
2883
2884 TRACE("%p %s %lu %lx\n", pdnDevInst, pDeviceID, ulFlags, hMachine);
2885
2886 if (pDeviceID != NULL)
2887 {
2888 if (CaptureAndConvertAnsiArg(pDeviceID, &pDevIdW))
2889 return CR_INVALID_DEVICE_ID;
2890 }
2891
2892 ret = CM_Locate_DevNode_ExW(pdnDevInst, pDevIdW, ulFlags, hMachine);
2893
2894 if (pDevIdW != NULL)
2895 MyFree(pDevIdW);
2896
2897 return ret;
2898 }
2899
2900
2901 /***********************************************************************
2902 * CM_Locate_DevNode_ExW [SETUPAPI.@]
2903 */
2904 CONFIGRET WINAPI CM_Locate_DevNode_ExW(
2905 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine)
2906 {
2907 WCHAR DeviceIdBuffer[MAX_DEVICE_ID_LEN];
2908 RPC_BINDING_HANDLE BindingHandle = NULL;
2909 HSTRING_TABLE StringTable = NULL;
2910 CONFIGRET ret = CR_SUCCESS;
2911
2912 TRACE("%p %s %lu %lx\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine);
2913
2914 if (pdnDevInst == NULL)
2915 return CR_INVALID_POINTER;
2916
2917 if (ulFlags & ~CM_LOCATE_DEVNODE_BITS)
2918 return CR_INVALID_FLAG;
2919
2920 if (hMachine != NULL)
2921 {
2922 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2923 if (BindingHandle == NULL)
2924 return CR_FAILURE;
2925
2926 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2927 if (StringTable == 0)
2928 return CR_FAILURE;
2929 }
2930 else
2931 {
2932 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2933 return CR_FAILURE;
2934 }
2935
2936 if (pDeviceID != NULL && lstrlenW(pDeviceID) != 0)
2937 {
2938 lstrcpyW(DeviceIdBuffer, pDeviceID);
2939 }
2940 else
2941 {
2942 RpcTryExcept
2943 {
2944 /* Get the root device ID */
2945 ret = PNP_GetRootDeviceInstance(BindingHandle,
2946 DeviceIdBuffer,
2947 MAX_DEVICE_ID_LEN);
2948 }
2949 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2950 {
2951 ret = RpcStatusToCmStatus(RpcExceptionCode());
2952 }
2953 RpcEndExcept;
2954
2955 if (ret != CR_SUCCESS)
2956 return CR_FAILURE;
2957 }
2958 TRACE("DeviceIdBuffer: %s\n", debugstr_w(DeviceIdBuffer));
2959
2960 RpcTryExcept
2961 {
2962 /* Validate the device ID */
2963 ret = PNP_ValidateDeviceInstance(BindingHandle,
2964 DeviceIdBuffer,
2965 ulFlags);
2966 }
2967 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
2968 {
2969 ret = RpcStatusToCmStatus(RpcExceptionCode());
2970 }
2971 RpcEndExcept;
2972
2973 if (ret == CR_SUCCESS)
2974 {
2975 *pdnDevInst = StringTableAddString(StringTable, DeviceIdBuffer, 1);
2976 if (*pdnDevInst == -1)
2977 ret = CR_FAILURE;
2978 }
2979
2980 return ret;
2981 }
2982
2983
2984 /***********************************************************************
2985 * CM_Move_DevNode [SETUPAPI.@]
2986 */
2987 CONFIGRET WINAPI CM_Move_DevNode(
2988 DEVINST dnFromDevInst, DEVINST dnToDevInst, ULONG ulFlags)
2989 {
2990 TRACE("%lx %lx %lx\n", dnFromDevInst, dnToDevInst, ulFlags);
2991 return CM_Move_DevNode_Ex(dnFromDevInst, dnToDevInst, ulFlags, NULL);
2992 }
2993
2994
2995 /***********************************************************************
2996 * CM_Move_DevNode_Ex [SETUPAPI.@]
2997 */
2998 CONFIGRET WINAPI CM_Move_DevNode_Ex(
2999 DEVINST dnFromDevInst, DEVINST dnToDevInst, ULONG ulFlags,
3000 HMACHINE hMachine)
3001 {
3002 RPC_BINDING_HANDLE BindingHandle = NULL;
3003 HSTRING_TABLE StringTable = NULL;
3004 LPWSTR lpFromDevInst;
3005 LPWSTR lpToDevInst;
3006 CONFIGRET ret;
3007
3008 FIXME("%lx %lx %lx %lx\n",
3009 dnFromDevInst, dnToDevInst, ulFlags, hMachine);
3010
3011 if (!IsUserAdmin())
3012 return CR_ACCESS_DENIED;
3013
3014 if (dnFromDevInst == 0 || dnToDevInst == 0)
3015 return CR_INVALID_DEVNODE;
3016
3017 if (ulFlags != 0)
3018 return CR_INVALID_FLAG;
3019
3020 if (hMachine != NULL)
3021 {
3022 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3023 if (BindingHandle == NULL)
3024 return CR_FAILURE;
3025
3026 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3027 if (StringTable == 0)
3028 return CR_FAILURE;
3029 }
3030 else
3031 {
3032 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3033 return CR_FAILURE;
3034 }
3035
3036 lpFromDevInst = StringTableStringFromId(StringTable, dnFromDevInst);
3037 if (lpFromDevInst == NULL)
3038 return CR_INVALID_DEVNODE;
3039
3040 lpToDevInst = StringTableStringFromId(StringTable, dnToDevInst);
3041 if (lpToDevInst == NULL)
3042 return CR_INVALID_DEVNODE;
3043
3044 RpcTryExcept
3045 {
3046 ret = PNP_DeviceInstanceAction(BindingHandle,
3047 PNP_DEVINST_MOVE,
3048 ulFlags,
3049 lpFromDevInst,
3050 lpToDevInst);
3051 }
3052 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3053 {
3054 ret = RpcStatusToCmStatus(RpcExceptionCode());
3055 }
3056 RpcEndExcept;
3057
3058 return ret;
3059 }
3060
3061
3062 /***********************************************************************
3063 * CM_Open_Class_KeyA [SETUPAPI.@]
3064 */
3065 CONFIGRET WINAPI CM_Open_Class_KeyA(
3066 LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
3067 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
3068 {
3069 TRACE("%p %s %lx %lx %p %lx\n",
3070 debugstr_guid(pClassGuid), pszClassName,
3071 samDesired, Disposition, phkClass, ulFlags);
3072
3073 return CM_Open_Class_Key_ExA(pClassGuid, pszClassName, samDesired,
3074 Disposition, phkClass, ulFlags, NULL);
3075 }
3076
3077
3078 /***********************************************************************
3079 * CM_Open_Class_KeyW [SETUPAPI.@]
3080 */
3081 CONFIGRET WINAPI CM_Open_Class_KeyW(
3082 LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
3083 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
3084 {
3085 TRACE("%p %s %lx %lx %p %lx\n",
3086 debugstr_guid(pClassGuid), debugstr_w(pszClassName),
3087 samDesired, Disposition, phkClass, ulFlags);
3088
3089 return CM_Open_Class_Key_ExW(pClassGuid, pszClassName, samDesired,
3090 Disposition, phkClass, ulFlags, NULL);
3091 }
3092
3093
3094 /***********************************************************************
3095 * CM_Open_Class_Key_ExA [SETUPAPI.@]
3096 */
3097 CONFIGRET WINAPI CM_Open_Class_Key_ExA(
3098 LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
3099 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
3100 HMACHINE hMachine)
3101 {
3102 CONFIGRET rc = CR_SUCCESS;
3103 LPWSTR pszClassNameW = NULL;
3104
3105 TRACE("%p %s %lx %lx %p %lx %lx\n",
3106 debugstr_guid(pClassGuid), pszClassName,
3107 samDesired, Disposition, phkClass, ulFlags, hMachine);
3108
3109 if (pszClassName != NULL)
3110 {
3111 if (CaptureAndConvertAnsiArg(pszClassName, &pszClassNameW))
3112 return CR_INVALID_DATA;
3113 }
3114
3115 rc = CM_Open_Class_Key_ExW(pClassGuid, pszClassNameW, samDesired,
3116 Disposition, phkClass, ulFlags, hMachine);
3117
3118 if (pszClassNameW != NULL)
3119 MyFree(pszClassNameW);
3120
3121 return CR_SUCCESS;
3122 }
3123
3124
3125 /***********************************************************************
3126 * CM_Open_Class_Key_ExW [SETUPAPI.@]
3127 */
3128 CONFIGRET WINAPI CM_Open_Class_Key_ExW(
3129 LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
3130 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
3131 HMACHINE hMachine)
3132 {
3133 WCHAR szKeyName[MAX_PATH];
3134 LPWSTR lpGuidString;
3135 DWORD dwDisposition;
3136 DWORD dwError;
3137 HKEY hKey;
3138
3139 TRACE("%p %s %lx %lx %p %lx %lx\n",
3140 debugstr_guid(pClassGuid), debugstr_w(pszClassName),
3141 samDesired, Disposition, phkClass, ulFlags, hMachine);
3142
3143 /* Check Disposition and ulFlags */
3144 if ((Disposition & ~RegDisposition_Bits) ||
3145 (ulFlags & ~CM_OPEN_CLASS_KEY_BITS))
3146 return CR_INVALID_FLAG;
3147
3148 /* Check phkClass */
3149 if (phkClass == NULL)
3150 return CR_INVALID_POINTER;
3151
3152 *phkClass = NULL;
3153
3154 if (ulFlags == CM_OPEN_CLASS_KEY_INTERFACE &&
3155 pszClassName != NULL)
3156 return CR_INVALID_DATA;
3157
3158 if (hMachine == NULL)
3159 {
3160 hKey = HKEY_LOCAL_MACHINE;
3161 }
3162 else
3163 {
3164 if (RegConnectRegistryW(((PMACHINE_INFO)hMachine)->szMachineName,
3165 HKEY_LOCAL_MACHINE, &hKey))
3166 return CR_REGISTRY_ERROR;
3167 }
3168
3169 if (ulFlags & CM_OPEN_CLASS_KEY_INTERFACE)
3170 {
3171 lstrcpyW(szKeyName, DeviceClasses);
3172 }
3173 else
3174 {
3175 lstrcpyW(szKeyName, ControlClass);
3176 }
3177
3178 if (pClassGuid != NULL)
3179 {
3180 if (UuidToStringW((UUID*)pClassGuid, &lpGuidString) != RPC_S_OK)
3181 {
3182 RegCloseKey(hKey);
3183 return CR_INVALID_DATA;
3184 }
3185
3186 lstrcatW(szKeyName, Backslash);
3187 lstrcatW(szKeyName, lpGuidString);
3188 }
3189
3190 if (Disposition == RegDisposition_OpenAlways)
3191 {
3192 dwError = RegCreateKeyExW(hKey, szKeyName, 0, NULL, 0, samDesired,
3193 NULL, phkClass, &dwDisposition);
3194 }
3195 else
3196 {
3197 dwError = RegOpenKeyExW(hKey, szKeyName, 0, samDesired, phkClass);
3198 }
3199
3200 RegCloseKey(hKey);
3201
3202 if (pClassGuid != NULL)
3203 RpcStringFreeW(&lpGuidString);
3204
3205 if (dwError != ERROR_SUCCESS)
3206 {
3207 *phkClass = NULL;
3208 return CR_NO_SUCH_REGISTRY_KEY;
3209 }
3210
3211 if (pszClassName != NULL)
3212 {
3213 RegSetValueExW(*phkClass, Class, 0, REG_SZ, (LPBYTE)pszClassName,
3214 (lstrlenW(pszClassName) + 1) * sizeof(WCHAR));
3215 }
3216
3217 return CR_SUCCESS;
3218 }
3219
3220
3221 /***********************************************************************
3222 * CM_Open_DevNode_Key [SETUPAPI.@]
3223 */
3224 CONFIGRET WINAPI CM_Open_DevNode_Key(
3225 DEVINST dnDevNode, REGSAM samDesired, ULONG ulHardwareProfile,
3226 REGDISPOSITION Disposition, PHKEY phkDevice, ULONG ulFlags)
3227 {
3228 TRACE("%lx %lx %lu %lx %p %lx\n", dnDevNode, samDesired,
3229 ulHardwareProfile, Disposition, phkDevice, ulFlags);
3230 return CM_Open_DevNode_Key_Ex(dnDevNode, samDesired, ulHardwareProfile,
3231 Disposition, phkDevice, ulFlags, NULL);
3232 }
3233
3234
3235 /***********************************************************************
3236 * CM_Open_DevNode_Key_Ex [SETUPAPI.@]
3237 */
3238 CONFIGRET WINAPI CM_Open_DevNode_Key_Ex(
3239 DEVINST dnDevNode, REGSAM samDesired, ULONG ulHardwareProfile,
3240 REGDISPOSITION Disposition, PHKEY phkDevice, ULONG ulFlags,
3241 HMACHINE hMachine)
3242 {
3243 FIXME("%lx %lx %lu %lx %p %lx %lx\n", dnDevNode, samDesired,
3244 ulHardwareProfile, Disposition, phkDevice, ulFlags, hMachine);
3245
3246 return CR_CALL_NOT_IMPLEMENTED;
3247 }
3248
3249
3250 /***********************************************************************
3251 * CM_Reenumerate_DevNode [SETUPAPI.@]
3252 */
3253 CONFIGRET WINAPI CM_Reenumerate_DevNode(
3254 DEVINST dnDevInst, ULONG ulFlags)
3255 {
3256 TRACE("%lx %lx\n", dnDevInst, ulFlags);
3257 return CM_Reenumerate_DevNode_Ex(dnDevInst, ulFlags, NULL);
3258 }
3259
3260
3261 /***********************************************************************
3262 * CM_Reenumerate_DevNode_Ex [SETUPAPI.@]
3263 */
3264 CONFIGRET WINAPI
3265 CM_Reenumerate_DevNode_Ex(
3266 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
3267 {
3268 RPC_BINDING_HANDLE BindingHandle = NULL;
3269 HSTRING_TABLE StringTable = NULL;
3270 LPWSTR lpDevInst;
3271 CONFIGRET ret;
3272
3273 FIXME("%lx %lx %lx\n", dnDevInst, ulFlags, hMachine);
3274
3275 if (dnDevInst == 0)
3276 return CR_INVALID_DEVNODE;
3277
3278 if (ulFlags & ~CM_REENUMERATE_BITS)
3279 return CR_INVALID_FLAG;
3280
3281 if (hMachine != NULL)
3282 {
3283 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3284 if (BindingHandle == NULL)
3285 return CR_FAILURE;
3286
3287 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3288 if (StringTable == 0)
3289 return CR_FAILURE;
3290 }
3291 else
3292 {
3293 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3294 return CR_FAILURE;
3295 }
3296
3297 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
3298 if (lpDevInst == NULL)
3299 return CR_INVALID_DEVNODE;
3300
3301 RpcTryExcept
3302 {
3303 ret = PNP_DeviceInstanceAction(BindingHandle,
3304 PNP_DEVINST_REENUMERATE,
3305 ulFlags,
3306 lpDevInst,
3307 NULL);
3308 }
3309 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3310 {
3311 ret = RpcStatusToCmStatus(RpcExceptionCode());
3312 }
3313 RpcEndExcept;
3314
3315 return ret;
3316 }
3317
3318
3319 /***********************************************************************
3320 * CM_Request_Eject_PC [SETUPAPI.@]
3321 */
3322 CONFIGRET WINAPI CM_Request_Eject_PC(VOID)
3323 {
3324 TRACE("\n");
3325 return CM_Request_Eject_PC_Ex(NULL);
3326 }
3327
3328
3329 /***********************************************************************
3330 * CM_Request_Eject_PC_Ex [SETUPAPI.@]
3331 */
3332 CONFIGRET WINAPI CM_Request_Eject_PC_Ex(
3333 HMACHINE hMachine)
3334 {
3335 RPC_BINDING_HANDLE BindingHandle = NULL;
3336 CONFIGRET ret;
3337
3338 TRACE("%lx\n", hMachine);
3339
3340 if (hMachine != NULL)
3341 {
3342 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3343 if (BindingHandle == NULL)
3344 return CR_FAILURE;
3345 }
3346 else
3347 {
3348 if (!PnpGetLocalHandles(&BindingHandle, NULL))
3349 return CR_FAILURE;
3350 }
3351
3352 RpcTryExcept
3353 {
3354 ret = PNP_RequestEjectPC(BindingHandle);
3355 }
3356 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3357 {
3358 ret = RpcStatusToCmStatus(RpcExceptionCode());
3359 }
3360 RpcEndExcept;
3361
3362 return ret;
3363 }
3364
3365
3366 /***********************************************************************
3367 * CM_Run_Detection [SETUPAPI.@]
3368 */
3369 CONFIGRET WINAPI CM_Run_Detection(
3370 ULONG ulFlags)
3371 {
3372 TRACE("%lx\n", ulFlags);
3373 return CM_Run_Detection_Ex(ulFlags, NULL);
3374 }
3375
3376
3377 /***********************************************************************
3378 * CM_Run_Detection_Ex [SETUPAPI.@]
3379 */
3380 CONFIGRET WINAPI CM_Run_Detection_Ex(
3381 ULONG ulFlags, HMACHINE hMachine)
3382 {
3383 RPC_BINDING_HANDLE BindingHandle = NULL;
3384 CONFIGRET ret;
3385
3386 TRACE("%lx %lx\n", ulFlags, hMachine);
3387
3388 if (!IsUserAdmin())
3389 return CR_ACCESS_DENIED;
3390
3391 if (ulFlags & ~CM_DETECT_BITS)
3392 return CR_INVALID_FLAG;
3393
3394 if (hMachine != NULL)
3395 {
3396 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3397 if (BindingHandle == NULL)
3398 return CR_FAILURE;
3399 }
3400 else
3401 {
3402 if (!PnpGetLocalHandles(&BindingHandle, NULL))
3403 return CR_FAILURE;
3404 }
3405
3406 RpcTryExcept
3407 {
3408 ret = PNP_RunDetection(BindingHandle,
3409 ulFlags);
3410 }
3411 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3412 {
3413 ret = RpcStatusToCmStatus(RpcExceptionCode());
3414 }
3415 RpcEndExcept;
3416
3417 return ret;
3418 }
3419
3420
3421 /***********************************************************************
3422 * CM_Set_DevNode_Problem [SETUPAPI.@]
3423 */
3424 CONFIGRET WINAPI CM_Set_DevNode_Problem(
3425 DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags)
3426 {
3427 TRACE("%lx %lx %lx\n", dnDevInst, ulProblem, ulFlags);
3428 return CM_Set_DevNode_Problem_Ex(dnDevInst, ulProblem, ulFlags, NULL);
3429 }
3430
3431
3432 /***********************************************************************
3433 * CM_Set_DevNode_Problem_Ex [SETUPAPI.@]
3434 */
3435 CONFIGRET WINAPI CM_Set_DevNode_Problem_Ex(
3436 DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags, HMACHINE hMachine)
3437 {
3438 RPC_BINDING_HANDLE BindingHandle = NULL;
3439 HSTRING_TABLE StringTable = NULL;
3440 LPWSTR lpDevInst;
3441 CONFIGRET ret;
3442
3443 TRACE("%lx %lx %lx %lx\n", dnDevInst, ulProblem, ulFlags, hMachine);
3444
3445 if (dnDevInst == 0)
3446 return CR_INVALID_DEVNODE;
3447
3448 if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
3449 return CR_INVALID_FLAG;
3450
3451 if (hMachine != NULL)
3452 {
3453 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3454 if (BindingHandle == NULL)
3455 return CR_FAILURE;
3456
3457 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3458 if (StringTable == 0)
3459 return CR_FAILURE;
3460 }
3461 else
3462 {
3463 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3464 return CR_FAILURE;
3465 }
3466
3467 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
3468 if (lpDevInst == NULL)
3469 return CR_INVALID_DEVNODE;
3470
3471 RpcTryExcept
3472 {
3473 ret = PNP_SetDeviceProblem(BindingHandle,
3474 lpDevInst,
3475 ulProblem,
3476 ulFlags);
3477 }
3478 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3479 {
3480 ret = RpcStatusToCmStatus(RpcExceptionCode());
3481 }
3482 RpcEndExcept;
3483
3484 return ret;
3485 }
3486
3487
3488 /***********************************************************************
3489 * CM_Set_DevNode_Registry_PropertyA [SETUPAPI.@]
3490 */
3491 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyA(
3492 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
3493 ULONG ulFlags)
3494 {
3495 TRACE("%lx %lu %p %lx %lx\n",
3496 dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
3497 return CM_Set_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
3498 Buffer, ulLength,
3499 ulFlags, NULL);
3500 }
3501
3502
3503 /***********************************************************************
3504 * CM_Set_DevNode_Registry_PropertyW [SETUPAPI.@]
3505 */
3506 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyW(
3507 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
3508 ULONG ulFlags)
3509 {
3510 TRACE("%lx %lu %p %lx %lx\n",
3511 dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
3512 return CM_Set_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
3513 Buffer, ulLength,
3514 ulFlags, NULL);
3515 }
3516
3517
3518 /***********************************************************************
3519 * CM_Set_DevNode_Registry_Property_ExA [SETUPAPI.@]
3520 */
3521 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExA(
3522 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
3523 ULONG ulFlags, HMACHINE hMachine)
3524 {
3525 CONFIGRET ret = CR_SUCCESS;
3526 LPWSTR lpBuffer;
3527 ULONG ulType;
3528
3529 FIXME("%lx %lu %p %lx %lx %lx\n",
3530 dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
3531
3532 if (Buffer == NULL && ulLength != 0)
3533 return CR_INVALID_POINTER;
3534
3535 if (Buffer == NULL)
3536 {
3537 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
3538 ulProperty,
3539 NULL,
3540 0,
3541 ulFlags,
3542 hMachine);
3543 }
3544 else
3545 {
3546 /* Get property type */
3547 switch (ulProperty)
3548 {
3549 case CM_DRP_DEVICEDESC:
3550 ulType = REG_SZ;
3551 break;
3552
3553 case CM_DRP_HARDWAREID:
3554 ulType = REG_MULTI_SZ;
3555 break;
3556
3557 case CM_DRP_COMPATIBLEIDS:
3558 ulType = REG_MULTI_SZ;
3559 break;
3560
3561 case CM_DRP_SERVICE:
3562 ulType = REG_SZ;
3563 break;
3564
3565 case CM_DRP_CLASS:
3566 ulType = REG_SZ;
3567 break;
3568
3569 case CM_DRP_CLASSGUID:
3570 ulType = REG_SZ;
3571 break;
3572
3573 case CM_DRP_DRIVER:
3574 ulType = REG_SZ;
3575 break;
3576
3577 case CM_DRP_CONFIGFLAGS:
3578 ulType = REG_DWORD;
3579 break;
3580
3581 case CM_DRP_MFG:
3582 ulType = REG_SZ;
3583 break;
3584
3585 case CM_DRP_FRIENDLYNAME:
3586 ulType = REG_SZ;
3587 break;
3588
3589 case CM_DRP_LOCATION_INFORMATION:
3590 ulType = REG_SZ;
3591 break;
3592
3593 case CM_DRP_UPPERFILTERS:
3594 ulType = REG_MULTI_SZ;
3595 break;
3596
3597 case CM_DRP_LOWERFILTERS:
3598 ulType = REG_MULTI_SZ;
3599 break;
3600
3601 default:
3602 return CR_INVALID_PROPERTY;
3603 }
3604
3605 /* Allocate buffer if needed */
3606 if (ulType == REG_SZ ||
3607 ulType == REG_MULTI_SZ)
3608 {
3609 lpBuffer = MyMalloc(ulLength * sizeof(WCHAR));
3610 if (lpBuffer == NULL)
3611 {
3612 ret = CR_OUT_OF_MEMORY;
3613 }
3614 else
3615 {
3616 if (!MultiByteToWideChar(CP_ACP, 0, Buffer,
3617 ulLength, lpBuffer, ulLength))
3618 {
3619 MyFree(lpBuffer);
3620 ret = CR_FAILURE;
3621 }
3622 else
3623 {
3624 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
3625 ulProperty,
3626 lpBuffer,
3627 ulLength * sizeof(WCHAR),
3628 ulFlags,
3629 hMachine);
3630 MyFree(lpBuffer);
3631 }
3632 }
3633 }
3634 else
3635 {
3636 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
3637 ulProperty,
3638 Buffer,
3639 ulLength,
3640 ulFlags,
3641 hMachine);
3642 }
3643
3644 ret = CR_CALL_NOT_IMPLEMENTED;
3645 }
3646
3647 return ret;
3648 }
3649
3650
3651 /***********************************************************************
3652 * CM_Set_DevNode_Registry_Property_ExW [SETUPAPI.@]
3653 */
3654 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExW(
3655 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
3656 ULONG ulFlags, HMACHINE hMachine)
3657 {
3658 RPC_BINDING_HANDLE BindingHandle = NULL;
3659 HSTRING_TABLE StringTable = NULL;
3660 LPWSTR lpDevInst;
3661 ULONG ulType;
3662 CONFIGRET ret;
3663
3664 TRACE("%lx %lu %p %lx %lx %lx\n",
3665 dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
3666
3667 if (dnDevInst == 0)
3668 return CR_INVALID_DEVNODE;
3669
3670 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
3671 return CR_INVALID_PROPERTY;
3672
3673 if (Buffer != NULL && ulLength == 0)
3674 return CR_INVALID_POINTER;
3675
3676 if (ulFlags != 0)
3677 return CR_INVALID_FLAG;
3678
3679 if (hMachine != NULL)
3680 {
3681 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3682 if (BindingHandle == NULL)
3683 return CR_FAILURE;
3684
3685 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3686 if (StringTable == 0)
3687 return CR_FAILURE;
3688 }
3689 else
3690 {
3691 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3692 return CR_FAILURE;
3693 }
3694
3695 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
3696 if (lpDevInst == NULL)
3697 return CR_INVALID_DEVNODE;
3698
3699 switch (ulProperty)
3700 {
3701 case CM_DRP_DEVICEDESC:
3702 ulType = REG_SZ;
3703 break;
3704
3705 case CM_DRP_HARDWAREID:
3706 ulType = REG_MULTI_SZ;
3707 break;
3708
3709 case CM_DRP_COMPATIBLEIDS:
3710 ulType = REG_MULTI_SZ;
3711 break;
3712
3713 case CM_DRP_SERVICE:
3714 ulType = REG_SZ;
3715 break;
3716
3717 case CM_DRP_CLASS:
3718 ulType = REG_SZ;
3719 break;
3720
3721 case CM_DRP_CLASSGUID:
3722 ulType = REG_SZ;
3723 break;
3724
3725 case CM_DRP_DRIVER:
3726 ulType = REG_SZ;
3727 break;
3728
3729 case CM_DRP_CONFIGFLAGS:
3730 ulType = REG_DWORD;
3731 break;
3732
3733 case CM_DRP_MFG:
3734 ulType = REG_SZ;
3735 break;
3736
3737 case CM_DRP_FRIENDLYNAME:
3738 ulType = REG_SZ;
3739 break;
3740
3741 case CM_DRP_LOCATION_INFORMATION:
3742 ulType = REG_SZ;
3743 break;
3744
3745 case CM_DRP_UPPERFILTERS:
3746 ulType = REG_MULTI_SZ;
3747 break;
3748
3749 case CM_DRP_LOWERFILTERS:
3750 ulType = REG_MULTI_SZ;
3751 break;
3752
3753 default:
3754 return CR_INVALID_PROPERTY;
3755 }
3756
3757 RpcTryExcept
3758 {
3759 ret = PNP_SetDeviceRegProp(BindingHandle,
3760 lpDevInst,
3761 ulProperty,
3762 ulType,
3763 (BYTE *)Buffer,
3764 ulLength,
3765 ulFlags);
3766 }
3767 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3768 {
3769 ret = RpcStatusToCmStatus(RpcExceptionCode());
3770 }
3771 RpcEndExcept;
3772
3773 return ret;
3774 }
3775
3776
3777 /***********************************************************************
3778 * CM_Set_HW_Prof [SETUPAPI.@]
3779 */
3780 CONFIGRET WINAPI CM_Set_HW_Prof(
3781 ULONG ulHardwareProfile, ULONG ulFlags)
3782 {
3783 TRACE("%lu %lu\n", ulHardwareProfile, ulFlags);
3784 return CM_Set_HW_Prof_Ex(ulHardwareProfile, ulFlags, NULL);
3785 }
3786
3787
3788 /***********************************************************************
3789 * CM_Set_HW_Prof_Ex [SETUPAPI.@]
3790 */
3791 CONFIGRET WINAPI CM_Set_HW_Prof_Ex(
3792 ULONG ulHardwareProfile, ULONG ulFlags, HMACHINE hMachine)
3793 {
3794 RPC_BINDING_HANDLE BindingHandle = NULL;
3795 CONFIGRET ret;
3796
3797 TRACE("%lu %lu %lx\n", ulHardwareProfile, ulFlags, hMachine);
3798
3799 if (!IsUserAdmin())
3800 return CR_ACCESS_DENIED;
3801
3802 if (ulFlags != 0)
3803 return CR_INVALID_FLAG;
3804
3805 if (hMachine != NULL)
3806 {
3807 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3808 if (BindingHandle == NULL)
3809 return CR_FAILURE;
3810 }
3811 else
3812 {
3813 if (!PnpGetLocalHandles(&BindingHandle, NULL))
3814 return CR_FAILURE;
3815 }
3816
3817 RpcTryExcept
3818 {
3819 ret = PNP_SetHwProf(BindingHandle, ulHardwareProfile, ulFlags);
3820 }
3821 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3822 {
3823 ret = RpcStatusToCmStatus(RpcExceptionCode());
3824 }
3825 RpcEndExcept;
3826
3827 return ret;
3828 }
3829
3830
3831 /***********************************************************************
3832 * CM_Set_HW_Prof_FlagsA [SETUPAPI.@]
3833 */
3834 CONFIGRET WINAPI CM_Set_HW_Prof_FlagsA(
3835 DEVINSTID_A szDevInstName, ULONG ulConfig, ULONG ulValue,
3836 ULONG ulFlags)
3837 {
3838 TRACE("%s %lu %lu %lx\n", szDevInstName,
3839 ulConfig, ulValue, ulFlags);
3840 return CM_Set_HW_Prof_Flags_ExA(szDevInstName, ulConfig, ulValue,
3841 ulFlags, NULL);
3842 }
3843
3844
3845 /***********************************************************************
3846 * CM_Set_HW_Prof_FlagsW [SETUPAPI.@]
3847 */
3848 CONFIGRET WINAPI CM_Set_HW_Prof_FlagsW(
3849 DEVINSTID_W szDevInstName, ULONG ulConfig, ULONG ulValue,
3850 ULONG ulFlags)
3851 {
3852 TRACE("%s %lu %lu %lx\n", debugstr_w(szDevInstName),
3853 ulConfig, ulValue, ulFlags);
3854 return CM_Set_HW_Prof_Flags_ExW(szDevInstName, ulConfig, ulValue,
3855 ulFlags, NULL);
3856 }
3857
3858
3859 /***********************************************************************
3860 * CM_Set_HW_Prof_Flags_ExA [SETUPAPI.@]
3861 */
3862 CONFIGRET WINAPI CM_Set_HW_Prof_Flags_ExA(
3863 DEVINSTID_A szDevInstName, ULONG ulConfig, ULONG ulValue,
3864 ULONG ulFlags, HMACHINE hMachine)
3865 {
3866 DEVINSTID_W pszDevIdW = NULL;
3867 CONFIGRET ret = CR_SUCCESS;
3868
3869 TRACE("%s %lu %lu %lx %lx\n", szDevInstName,
3870 ulConfig, ulValue, ulFlags, hMachine);
3871
3872 if (szDevInstName != NULL)
3873 {
3874 if (CaptureAndConvertAnsiArg(szDevInstName, &pszDevIdW))
3875 return CR_INVALID_DEVICE_ID;
3876 }
3877
3878 ret = CM_Set_HW_Prof_Flags_ExW(pszDevIdW, ulConfig, ulValue,
3879 ulFlags, hMachine);
3880
3881 if (pszDevIdW != NULL)
3882 MyFree(pszDevIdW);
3883
3884 return ret;
3885 }
3886
3887
3888 /***********************************************************************
3889 * CM_Set_HW_Prof_Flags_ExW [SETUPAPI.@]
3890 */
3891 CONFIGRET WINAPI CM_Set_HW_Prof_Flags_ExW(
3892 DEVINSTID_W szDevInstName, ULONG ulConfig, ULONG ulValue,
3893 ULONG ulFlags, HMACHINE hMachine)
3894 {
3895 RPC_BINDING_HANDLE BindingHandle = NULL;
3896 CONFIGRET ret;
3897
3898 FIXME("%s %lu %lu %lx %lx\n", debugstr_w(szDevInstName),
3899 ulConfig, ulValue, ulFlags, hMachine);
3900
3901 if (szDevInstName == NULL)
3902 return CR_INVALID_POINTER;
3903
3904 if (ulFlags & ~ CM_SET_HW_PROF_FLAGS_BITS)
3905 return CR_INVALID_FLAG;
3906
3907 /* FIXME: Check whether szDevInstName is valid */
3908
3909 if (hMachine != NULL)
3910 {
3911 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3912 if (BindingHandle == NULL)
3913 return CR_FAILURE;
3914 }
3915 else
3916 {
3917 if (!PnpGetLocalHandles(&BindingHandle, NULL))
3918 return CR_FAILURE;
3919 }
3920
3921 RpcTryExcept
3922 {
3923 ret = PNP_HwProfFlags(BindingHandle, PNP_SET_HWPROFFLAGS, szDevInstName,
3924 ulConfig, &ulValue, NULL, NULL, 0, 0);
3925 }
3926 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3927 {
3928 ret = RpcStatusToCmStatus(RpcExceptionCode());
3929 }
3930 RpcEndExcept;
3931
3932 return ret;
3933 }
3934
3935
3936 /***********************************************************************
3937 * CM_Setup_DevNode [SETUPAPI.@]
3938 */
3939 CONFIGRET WINAPI CM_Setup_DevNode(
3940 DEVINST dnDevInst, ULONG ulFlags)
3941 {
3942 TRACE("%lx %lx\n", dnDevInst, ulFlags);
3943 return CM_Setup_DevNode_Ex(dnDevInst, ulFlags, NULL);
3944 }
3945
3946
3947 /***********************************************************************
3948 * CM_Setup_DevNode_Ex [SETUPAPI.@]
3949 */
3950 CONFIGRET WINAPI CM_Setup_DevNode_Ex(
3951 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
3952 {
3953 RPC_BINDING_HANDLE BindingHandle = NULL;
3954 HSTRING_TABLE StringTable = NULL;
3955 LPWSTR lpDevInst;
3956 CONFIGRET ret;
3957
3958 FIXME("%lx %lx %lx\n", dnDevInst, ulFlags, hMachine);
3959
3960 if (!IsUserAdmin())
3961 return CR_ACCESS_DENIED;
3962
3963 if (dnDevInst == 0)
3964 return CR_INVALID_DEVNODE;
3965
3966 if (ulFlags & ~CM_SETUP_BITS)
3967 return CR_INVALID_FLAG;
3968
3969 if (hMachine != NULL)
3970 {
3971 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
3972 if (BindingHandle == NULL)
3973 return CR_FAILURE;
3974
3975 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
3976 if (StringTable == 0)
3977 return CR_FAILURE;
3978 }
3979 else
3980 {
3981 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
3982 return CR_FAILURE;
3983 }
3984
3985 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
3986 if (lpDevInst == NULL)
3987 return CR_INVALID_DEVNODE;
3988
3989 RpcTryExcept
3990 {
3991 ret = PNP_DeviceInstanceAction(BindingHandle,
3992 PNP_DEVINST_SETUP,
3993 ulFlags,
3994 lpDevInst,
3995 NULL);
3996 }
3997 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
3998 {
3999 ret = RpcStatusToCmStatus(RpcExceptionCode());
4000 }
4001 RpcEndExcept;
4002
4003 return ret;
4004 }
4005
4006
4007 /***********************************************************************
4008 * CM_Uninstall_DevNode [SETUPAPI.@]
4009 */
4010 CONFIGRET WINAPI CM_Uninstall_DevNode(
4011 DEVINST dnPhantom, ULONG ulFlags)
4012 {
4013 TRACE("%lx %lx\n", dnPhantom, ulFlags);
4014 return CM_Uninstall_DevNode_Ex(dnPhantom, ulFlags, NULL);
4015 }
4016
4017
4018 /***********************************************************************
4019 * CM_Uninstall_DevNode_Ex [SETUPAPI.@]
4020 */
4021 CONFIGRET WINAPI CM_Uninstall_DevNode_Ex(
4022 DEVINST dnPhantom, ULONG ulFlags, HMACHINE hMachine)
4023 {
4024 RPC_BINDING_HANDLE BindingHandle = NULL;
4025 HSTRING_TABLE StringTable = NULL;
4026 LPWSTR lpDevInst;
4027 CONFIGRET ret;
4028
4029 TRACE("%lx %lx %lx\n", dnPhantom, ulFlags, hMachine);
4030
4031 if (dnPhantom == 0)
4032 return CR_INVALID_DEVNODE;
4033
4034 if (ulFlags != 0)
4035 return CR_INVALID_FLAG;
4036
4037 if (hMachine != NULL)
4038 {
4039 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
4040 if (BindingHandle == NULL)
4041 return CR_FAILURE;
4042
4043 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
4044 if (StringTable == 0)
4045 return CR_FAILURE;
4046 }
4047 else
4048 {
4049 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
4050 return CR_FAILURE;
4051 }
4052
4053 lpDevInst = StringTableStringFromId(StringTable, dnPhantom);
4054 if (lpDevInst == NULL)
4055 return CR_INVALID_DEVNODE;
4056
4057 RpcTryExcept
4058 {
4059 ret = PNP_UninstallDevInst(BindingHandle,
4060 lpDevInst,
4061 ulFlags);
4062 }
4063 RpcExcept(EXCEPTION_EXECUTE_HANDLER)
4064 {
4065 ret = RpcStatusToCmStatus(RpcExceptionCode());
4066 }
4067 RpcEndExcept;
4068
4069 return ret;
4070 }