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