reshuffling of dlls
[reactos.git] / reactos / dll / 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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[MAX_PATH];
43 RPC_BINDING_HANDLE BindingHandle;
44 HSTRING_TABLE StringTable;
45 } MACHINE_INFO, *PMACHINE_INFO;
46
47
48 static BOOL GuidToString(LPGUID Guid, LPWSTR String)
49 {
50 LPWSTR lpString;
51
52 if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
53 return FALSE;
54
55 lstrcpyW(&String[1], lpString);
56
57 String[0] = L'{';
58 String[MAX_GUID_STRING_LEN - 2] = L'}';
59 String[MAX_GUID_STRING_LEN - 1] = 0;
60
61 RpcStringFree(&lpString);
62
63 return TRUE;
64 }
65
66
67 /***********************************************************************
68 * CMP_Init_Detection [SETUPAPI.@]
69 */
70 CONFIGRET WINAPI CMP_Init_Detection(
71 DWORD dwMagic)
72 {
73 RPC_BINDING_HANDLE BindingHandle = NULL;
74
75 TRACE("%lu\n", dwMagic);
76
77 if (dwMagic != CMP_MAGIC)
78 return CR_INVALID_DATA;
79
80 if (!PnpGetLocalHandles(&BindingHandle, NULL))
81 return CR_FAILURE;
82
83 return PNP_InitDetection(BindingHandle);
84 }
85
86
87 /***********************************************************************
88 * CMP_Report_LogOn [SETUPAPI.@]
89 */
90 CONFIGRET WINAPI CMP_Report_LogOn(
91 DWORD dwMagic,
92 DWORD dwProcessId)
93 {
94 RPC_BINDING_HANDLE BindingHandle = NULL;
95 CONFIGRET ret = CR_SUCCESS;
96 BOOL bAdmin;
97 DWORD i;
98
99 TRACE("%lu\n", dwMagic);
100
101 if (dwMagic != CMP_MAGIC)
102 return CR_INVALID_DATA;
103
104 if (!PnpGetLocalHandles(&BindingHandle, NULL))
105 return CR_FAILURE;
106
107 bAdmin = IsUserAdmin();
108
109 for (i = 0; i < 30; i++)
110 {
111 ret = PNP_ReportLogOn(BindingHandle,
112 bAdmin,
113 dwProcessId);
114 if (ret == CR_SUCCESS)
115 break;
116
117 Sleep(5000);
118 }
119
120 return ret;
121 }
122
123
124 /***********************************************************************
125 * CM_Connect_MachineA [SETUPAPI.@]
126 */
127 CONFIGRET WINAPI CM_Connect_MachineA(
128 PCSTR UNCServerName, PHMACHINE phMachine)
129 {
130 PWSTR pServerNameW;
131 CONFIGRET ret;
132
133 TRACE("%s %p\n", UNCServerName, phMachine);
134
135 if (UNCServerName == NULL || *UNCServerName == 0)
136 return CM_Connect_MachineW(NULL, phMachine);
137
138 if (CaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
139 return CR_INVALID_DATA;
140
141 ret = CM_Connect_MachineW(pServerNameW, phMachine);
142
143 MyFree(pServerNameW);
144
145 return ret;
146 }
147
148
149 /***********************************************************************
150 * CM_Connect_MachineW [SETUPAPI.@]
151 */
152 CONFIGRET WINAPI CM_Connect_MachineW(
153 PCWSTR UNCServerName, PHMACHINE phMachine)
154 {
155 PMACHINE_INFO pMachine;
156
157 TRACE("%s %p\n", debugstr_w(UNCServerName), phMachine);
158
159 pMachine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MACHINE_INFO));
160 if (pMachine == NULL)
161 return CR_OUT_OF_MEMORY;
162
163 lstrcpyW(pMachine->szMachineName, UNCServerName);
164
165 pMachine->StringTable = StringTableInitialize();
166 if (pMachine->StringTable == NULL)
167 {
168 HeapFree(GetProcessHeap(), 0, pMachine);
169 return CR_FAILURE;
170 }
171
172 StringTableAddString(pMachine->StringTable, L"PLT", 1);
173
174 if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
175 {
176 StringTableDestroy(pMachine->StringTable);
177 HeapFree(GetProcessHeap(), 0, pMachine);
178 return CR_INVALID_MACHINENAME;
179 }
180
181 phMachine = (PHMACHINE)pMachine;
182
183 return CR_SUCCESS;
184 }
185
186
187 /***********************************************************************
188 * CM_Create_DevNodeA [SETUPAPI.@]
189 */
190 CONFIGRET WINAPI CM_Create_DevNodeA(
191 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
192 ULONG ulFlags)
193 {
194 TRACE("%p %s %p %lx\n",
195 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags);
196 return CM_Create_DevNode_ExA(pdnDevInst, pDeviceID, dnParent,
197 ulFlags, NULL);
198 }
199
200
201 /***********************************************************************
202 * CM_Create_DevNodeW [SETUPAPI.@]
203 */
204 CONFIGRET WINAPI CM_Create_DevNodeW(
205 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
206 ULONG ulFlags)
207 {
208 TRACE("%p %s %p %lx\n",
209 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags);
210 return CM_Create_DevNode_ExW(pdnDevInst, pDeviceID, dnParent,
211 ulFlags, NULL);
212 }
213
214
215 /***********************************************************************
216 * CM_Create_DevNode_ExA [SETUPAPI.@]
217 */
218 CONFIGRET WINAPI CM_Create_DevNode_ExA(
219 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, DEVINST dnParent,
220 ULONG ulFlags, HANDLE hMachine)
221 {
222 DEVINSTID_W pDeviceIDW;
223 CONFIGRET ret;
224
225 TRACE("%p %s %p %lx %p\n",
226 pdnDevInst, debugstr_a(pDeviceID), dnParent, ulFlags, hMachine);
227
228 if (CaptureAndConvertAnsiArg(pDeviceID, &pDeviceIDW))
229 return CR_INVALID_DATA;
230
231 ret = CM_Create_DevNode_ExW(pdnDevInst, pDeviceIDW, dnParent, ulFlags,
232 hMachine);
233
234 MyFree(pDeviceIDW);
235
236 return ret;
237 }
238
239
240 /***********************************************************************
241 * CM_Create_DevNode_ExW [SETUPAPI.@]
242 */
243 CONFIGRET WINAPI CM_Create_DevNode_ExW(
244 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, DEVINST dnParent,
245 ULONG ulFlags, HANDLE hMachine)
246 {
247 RPC_BINDING_HANDLE BindingHandle = NULL;
248 HSTRING_TABLE StringTable = NULL;
249 LPWSTR lpParentDevInst;
250 CONFIGRET ret = CR_SUCCESS;
251
252 FIXME("%p %s %p %lx %p\n",
253 pdnDevInst, debugstr_w(pDeviceID), dnParent, ulFlags, hMachine);
254
255 if (!IsUserAdmin())
256 return CR_ACCESS_DENIED;
257
258 if (pdnDevInst == NULL)
259 return CR_INVALID_POINTER;
260
261 if (pDeviceID == NULL || wcslen(pDeviceID) == 0)
262 return CR_INVALID_DEVICE_ID;
263
264 if (dnParent == 0)
265 return CR_INVALID_DEVNODE;
266
267 if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
268 return CR_INVALID_FLAG;
269
270 if (hMachine != NULL)
271 {
272 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
273 if (BindingHandle == NULL)
274 return CR_FAILURE;
275
276 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
277 if (StringTable == 0)
278 return CR_FAILURE;
279 }
280 else
281 {
282 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
283 return CR_FAILURE;
284 }
285
286 lpParentDevInst = StringTableStringFromId(StringTable, dnParent);
287 if (lpParentDevInst == NULL)
288 return CR_INVALID_DEVNODE;
289
290 ret = PNP_CreateDevInst(BindingHandle,
291 pDeviceID,
292 lpParentDevInst,
293 MAX_DEVICE_ID_LEN,
294 ulFlags);
295 if (ret == CR_SUCCESS)
296 {
297 *pdnDevInst = StringTableAddString(StringTable, pDeviceID, 1);
298 if (*pdnDevInst == 0)
299 ret = CR_NO_SUCH_DEVNODE;
300 }
301
302 return ret;
303 }
304
305
306 /***********************************************************************
307 * CM_Delete_Class_Key [SETUPAPI.@]
308 */
309 CONFIGRET WINAPI CM_Delete_Class_Key(
310 LPGUID ClassGuid, ULONG ulFlags)
311 {
312 TRACE("%p %lx\n", ClassGuid, ulFlags);
313 return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
314 }
315
316
317 /***********************************************************************
318 * CM_Delete_Class_Key_Ex [SETUPAPI.@]
319 */
320 CONFIGRET WINAPI CM_Delete_Class_Key_Ex(
321 LPGUID ClassGuid, ULONG ulFlags, HANDLE hMachine)
322 {
323 WCHAR szGuidString[MAX_GUID_STRING_LEN];
324 RPC_BINDING_HANDLE BindingHandle = NULL;
325
326 TRACE("%p %lx %lx\n", ClassGuid, ulFlags, hMachine);
327
328 if (ClassGuid == NULL)
329 return CR_INVALID_POINTER;
330
331 if (ulFlags & ~CM_DELETE_CLASS_BITS)
332 return CR_INVALID_FLAG;
333
334 if (!GuidToString(ClassGuid, szGuidString))
335 return CR_INVALID_DATA;
336
337 if (hMachine != NULL)
338 {
339 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
340 if (BindingHandle == NULL)
341 return CR_FAILURE;
342 }
343 else
344 {
345 if (!PnpGetLocalHandles(&BindingHandle, NULL))
346 return CR_FAILURE;
347 }
348
349 return PNP_DeleteClassKey(BindingHandle,
350 szGuidString,
351 ulFlags);
352 }
353
354
355 /***********************************************************************
356 * CM_Disable_DevNode [SETUPAPI.@]
357 */
358 CONFIGRET WINAPI CM_Disable_DevNode(
359 DEVINST dnDevInst, ULONG ulFlags)
360 {
361 TRACE("%p %lx\n", dnDevInst, ulFlags);
362 return CM_Disable_DevNode_Ex(dnDevInst, ulFlags, NULL);
363 }
364
365
366 /***********************************************************************
367 * CM_Disable_DevNode_Ex [SETUPAPI.@]
368 */
369 CONFIGRET WINAPI CM_Disable_DevNode_Ex(
370 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
371 {
372 RPC_BINDING_HANDLE BindingHandle = NULL;
373 HSTRING_TABLE StringTable = NULL;
374 LPWSTR lpDevInst;
375
376 FIXME("%p %lx %p\n", dnDevInst, ulFlags, hMachine);
377
378 if (!IsUserAdmin())
379 return CR_ACCESS_DENIED;
380
381 if (dnDevInst == 0)
382 return CR_INVALID_DEVINST;
383
384 if (ulFlags != 0)
385 return CR_INVALID_FLAG;
386
387 if (hMachine != NULL)
388 {
389 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
390 if (BindingHandle == NULL)
391 return CR_FAILURE;
392
393 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
394 if (StringTable == 0)
395 return CR_FAILURE;
396 }
397 else
398 {
399 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
400 return CR_FAILURE;
401 }
402
403 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
404 if (lpDevInst == NULL)
405 return CR_INVALID_DEVNODE;
406
407 return PNP_DeviceInstanceAction(BindingHandle,
408 5,
409 ulFlags,
410 lpDevInst,
411 NULL);
412 }
413
414
415 /***********************************************************************
416 * CM_Disconnect_Machine [SETUPAPI.@]
417 */
418 CONFIGRET WINAPI CM_Disconnect_Machine(HMACHINE hMachine)
419 {
420 PMACHINE_INFO pMachine;
421
422 TRACE("%lx\n", hMachine);
423
424 pMachine = (PMACHINE_INFO)hMachine;
425 if (pMachine == NULL)
426 return CR_SUCCESS;
427
428 if (pMachine->StringTable != NULL)
429 StringTableDestroy(pMachine->StringTable);
430
431 if (!PnpUnbindRpc(pMachine->BindingHandle))
432 return CR_ACCESS_DENIED;
433
434 HeapFree(GetProcessHeap(), 0, pMachine);
435
436 return CR_SUCCESS;
437 }
438
439
440 /***********************************************************************
441 * CM_Enable_DevNode [SETUPAPI.@]
442 */
443 CONFIGRET WINAPI CM_Enable_DevNode(
444 DEVINST dnDevInst, ULONG ulFlags)
445 {
446 TRACE("%p %lx\n", dnDevInst, ulFlags);
447 return CM_Enable_DevNode_Ex(dnDevInst, ulFlags, NULL);
448 }
449
450
451 /***********************************************************************
452 * CM_Enable_DevNode_Ex [SETUPAPI.@]
453 */
454 CONFIGRET WINAPI CM_Enable_DevNode_Ex(
455 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
456 {
457 RPC_BINDING_HANDLE BindingHandle = NULL;
458 HSTRING_TABLE StringTable = NULL;
459 LPWSTR lpDevInst;
460
461 FIXME("%p %lx %p\n", dnDevInst, ulFlags, hMachine);
462
463 if (!IsUserAdmin())
464 return CR_ACCESS_DENIED;
465
466 if (dnDevInst == 0)
467 return CR_INVALID_DEVINST;
468
469 if (ulFlags != 0)
470 return CR_INVALID_FLAG;
471
472 if (hMachine != NULL)
473 {
474 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
475 if (BindingHandle == NULL)
476 return CR_FAILURE;
477
478 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
479 if (StringTable == 0)
480 return CR_FAILURE;
481 }
482 else
483 {
484 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
485 return CR_FAILURE;
486 }
487
488 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
489 if (lpDevInst == NULL)
490 return CR_INVALID_DEVNODE;
491
492 return PNP_DeviceInstanceAction(BindingHandle,
493 4,
494 ulFlags,
495 lpDevInst,
496 NULL);
497 }
498
499
500 /***********************************************************************
501 * CM_Enumerate_Classes [SETUPAPI.@]
502 */
503 CONFIGRET WINAPI CM_Enumerate_Classes(
504 ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags)
505 {
506 TRACE("%lx %p %lx\n", ulClassIndex, ClassGuid, ulFlags);
507 return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
508 }
509
510
511 /***********************************************************************
512 * CM_Enumerate_Classes_Ex [SETUPAPI.@]
513 */
514 CONFIGRET WINAPI CM_Enumerate_Classes_Ex(
515 ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags, HMACHINE hMachine)
516 {
517 WCHAR szBuffer[MAX_GUID_STRING_LEN];
518 RPC_BINDING_HANDLE BindingHandle = NULL;
519 CONFIGRET ret = CR_SUCCESS;
520 ULONG ulLength = MAX_GUID_STRING_LEN;
521
522 TRACE("%lx %p %lx %p\n", ulClassIndex, ClassGuid, ulFlags, hMachine);
523
524 if (ClassGuid == NULL)
525 return CR_INVALID_POINTER;
526
527 if (ulFlags != 0)
528 return CR_INVALID_FLAG;
529
530 if (hMachine != NULL)
531 {
532 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
533 if (BindingHandle == NULL)
534 return CR_FAILURE;
535 }
536 else
537 {
538 if (!PnpGetLocalHandles(&BindingHandle, NULL))
539 return CR_FAILURE;
540 }
541
542 ret = PNP_EnumerateSubKeys(BindingHandle,
543 PNP_BRANCH_CLASS,
544 ulClassIndex,
545 szBuffer,
546 MAX_GUID_STRING_LEN,
547 &ulLength,
548 ulFlags);
549 if (ret == CR_SUCCESS)
550 {
551 /* Remove the {} */
552 szBuffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
553
554 /* Convert the buffer to a GUID */
555 if (UuidFromStringW(&szBuffer[1], ClassGuid) != RPC_S_OK)
556 return CR_FAILURE;
557 }
558
559 return ret;
560 }
561
562
563 /***********************************************************************
564 * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
565 */
566 CONFIGRET WINAPI CM_Enumerate_EnumeratorsA(
567 ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
568 {
569 TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
570 return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
571 ulFlags, NULL);
572 }
573
574
575 /***********************************************************************
576 * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
577 */
578 CONFIGRET WINAPI CM_Enumerate_EnumeratorsW(
579 ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
580 {
581 TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
582 return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
583 ulFlags, NULL);
584 }
585
586
587 /***********************************************************************
588 * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
589 */
590 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExA(
591 ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
592 HMACHINE hMachine)
593 {
594 WCHAR szBuffer[MAX_DEVICE_ID_LEN];
595 ULONG ulOrigLength;
596 ULONG ulLength;
597 CONFIGRET ret = CR_SUCCESS;
598
599 TRACE("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
600 hMachine);
601
602 if (Buffer == NULL || pulLength == NULL)
603 return CR_INVALID_POINTER;
604
605 if (ulFlags != 0)
606 return CR_INVALID_FLAG;
607
608 ulOrigLength = *pulLength;
609 *pulLength = 0;
610
611 ulLength = MAX_DEVICE_ID_LEN;
612 ret = CM_Enumerate_Enumerators_ExW(ulEnumIndex, szBuffer, &ulLength,
613 ulFlags, hMachine);
614 if (ret == CR_SUCCESS)
615 {
616 if (WideCharToMultiByte(CP_ACP,
617 0,
618 szBuffer,
619 ulLength,
620 Buffer,
621 ulOrigLength,
622 NULL,
623 NULL) == 0)
624 ret = CR_FAILURE;
625 else
626 *pulLength = lstrlenA(Buffer) + 1;
627 }
628
629 return ret;
630 }
631
632
633 /***********************************************************************
634 * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
635 */
636 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExW(
637 ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
638 HMACHINE hMachine)
639 {
640 RPC_BINDING_HANDLE BindingHandle = NULL;
641
642 TRACE("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
643 hMachine);
644
645 if (Buffer == NULL || pulLength == NULL)
646 return CR_INVALID_POINTER;
647
648 if (ulFlags != 0)
649 return CR_INVALID_FLAG;
650
651 *Buffer = UNICODE_NULL;
652
653 if (hMachine != NULL)
654 {
655 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
656 if (BindingHandle == NULL)
657 return CR_FAILURE;
658 }
659 else
660 {
661 if (!PnpGetLocalHandles(&BindingHandle, NULL))
662 return CR_FAILURE;
663 }
664
665 return PNP_EnumerateSubKeys(BindingHandle,
666 PNP_BRANCH_ENUM,
667 ulEnumIndex,
668 Buffer,
669 *pulLength,
670 pulLength,
671 ulFlags);
672 }
673
674
675 /***********************************************************************
676 * CM_Get_Child [SETUPAPI.@]
677 */
678 CONFIGRET WINAPI CM_Get_Child(
679 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
680 {
681 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
682 return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
683 }
684
685
686 /***********************************************************************
687 * CM_Get_Child_Ex [SETUPAPI.@]
688 */
689 CONFIGRET WINAPI CM_Get_Child_Ex(
690 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
691 {
692 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
693 RPC_BINDING_HANDLE BindingHandle = NULL;
694 HSTRING_TABLE StringTable = NULL;
695 LPWSTR lpDevInst;
696 DWORD dwIndex;
697 CONFIGRET ret;
698
699 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
700
701 if (pdnDevInst == NULL)
702 return CR_INVALID_POINTER;
703
704 if (dnDevInst == 0)
705 return CR_INVALID_DEVINST;
706
707 if (ulFlags != 0)
708 return CR_INVALID_FLAG;
709
710 *pdnDevInst = -1;
711
712 if (hMachine != NULL)
713 {
714 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
715 if (BindingHandle == NULL)
716 return CR_FAILURE;
717
718 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
719 if (StringTable == 0)
720 return CR_FAILURE;
721 }
722 else
723 {
724 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
725 return CR_FAILURE;
726 }
727
728 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
729 if (lpDevInst == NULL)
730 return CR_INVALID_DEVNODE;
731
732 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
733 PNP_DEVICE_CHILD,
734 lpDevInst,
735 szRelatedDevInst,
736 MAX_DEVICE_ID_LEN,
737 0);
738 if (ret != CR_SUCCESS)
739 return ret;
740
741 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
742
743 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
744 if (dwIndex == -1)
745 return CR_FAILURE;
746
747 *pdnDevInst = dwIndex;
748
749 return CR_SUCCESS;
750 }
751
752
753 /***********************************************************************
754 * CM_Get_Class_Key_NameA [SETUPAPI.@]
755 */
756 CONFIGRET WINAPI CM_Get_Class_Key_NameA(
757 LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
758 {
759 TRACE("%p %p %p %lx\n",
760 ClassGuid, pszKeyName, pulLength, ulFlags);
761 return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
762 ulFlags, NULL);
763 }
764
765
766 /***********************************************************************
767 * CM_Get_Class_Key_NameW [SETUPAPI.@]
768 */
769 CONFIGRET WINAPI CM_Get_Class_Key_NameW(
770 LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
771 {
772 TRACE("%p %p %p %lx\n",
773 ClassGuid, pszKeyName, pulLength, ulFlags);
774 return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
775 ulFlags, NULL);
776 }
777
778
779 /***********************************************************************
780 * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
781 */
782 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExA(
783 LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
784 HMACHINE hMachine)
785 {
786 WCHAR szBuffer[MAX_GUID_STRING_LEN];
787 CONFIGRET ret = CR_SUCCESS;
788 ULONG ulLength;
789 ULONG ulOrigLength;
790
791 TRACE("%p %p %p %lx %lx\n",
792 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
793
794 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
795 return CR_INVALID_POINTER;
796
797 ulOrigLength = *pulLength;
798 *pulLength = 0;
799
800 ulLength = MAX_GUID_STRING_LEN;
801 ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
802 ulFlags, hMachine);
803 if (ret == CR_SUCCESS)
804 {
805 if (WideCharToMultiByte(CP_ACP,
806 0,
807 szBuffer,
808 ulLength,
809 pszKeyName,
810 ulOrigLength,
811 NULL,
812 NULL) == 0)
813 ret = CR_FAILURE;
814 else
815 *pulLength = lstrlenA(pszKeyName) + 1;
816 }
817
818 return CR_SUCCESS;
819 }
820
821
822 /***********************************************************************
823 * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
824 */
825 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExW(
826 LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
827 HMACHINE hMachine)
828 {
829 TRACE("%p %p %p %lx %lx\n",
830 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
831
832 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
833 return CR_INVALID_POINTER;
834
835 if (ulFlags != 0)
836 return CR_INVALID_FLAG;
837
838 if (*pulLength < MAX_GUID_STRING_LEN)
839 {
840 *pulLength = 0;
841 return CR_BUFFER_SMALL;
842 }
843
844 if (!GuidToString(ClassGuid, pszKeyName))
845 return CR_INVALID_DATA;
846
847 *pulLength = MAX_GUID_STRING_LEN;
848
849 return CR_SUCCESS;
850 }
851
852
853 /***********************************************************************
854 * CM_Get_Class_NameA [SETUPAPI.@]
855 */
856 CONFIGRET WINAPI CM_Get_Class_NameA(
857 LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
858 {
859 TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
860 return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
861 NULL);
862 }
863
864
865 /***********************************************************************
866 * CM_Get_Class_NameW [SETUPAPI.@]
867 */
868 CONFIGRET WINAPI CM_Get_Class_NameW(
869 LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
870 {
871 TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
872 return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
873 NULL);
874 }
875
876
877 /***********************************************************************
878 * CM_Get_Class_Name_ExA [SETUPAPI.@]
879 */
880 CONFIGRET WINAPI CM_Get_Class_Name_ExA(
881 LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
882 HMACHINE hMachine)
883 {
884 WCHAR szBuffer[MAX_CLASS_NAME_LEN];
885 CONFIGRET ret = CR_SUCCESS;
886 ULONG ulLength;
887 ULONG ulOrigLength;
888
889 TRACE("%p %p %p %lx %lx\n",
890 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
891
892 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
893 return CR_INVALID_POINTER;
894
895 ulOrigLength = *pulLength;
896 *pulLength = 0;
897
898 ulLength = MAX_CLASS_NAME_LEN;
899 ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
900 ulFlags, hMachine);
901 if (ret == CR_SUCCESS)
902 {
903 if (WideCharToMultiByte(CP_ACP,
904 0,
905 szBuffer,
906 ulLength,
907 Buffer,
908 ulOrigLength,
909 NULL,
910 NULL) == 0)
911 ret = CR_FAILURE;
912 else
913 *pulLength = lstrlenA(Buffer) + 1;
914 }
915
916 return ret;
917 }
918
919
920 /***********************************************************************
921 * CM_Get_Class_Name_ExW [SETUPAPI.@]
922 */
923 CONFIGRET WINAPI
924 CM_Get_Class_Name_ExW(
925 LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
926 HMACHINE hMachine)
927 {
928 WCHAR szGuidString[MAX_GUID_STRING_LEN];
929 RPC_BINDING_HANDLE BindingHandle = NULL;
930
931 TRACE("%p %p %p %lx %lx\n",
932 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
933
934 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
935 return CR_INVALID_POINTER;
936
937 if (ulFlags != 0)
938 return CR_INVALID_FLAG;
939
940 if (!GuidToString(ClassGuid, szGuidString))
941 return CR_INVALID_DATA;
942
943 TRACE("Guid %s\n", debugstr_w(szGuidString));
944
945 if (hMachine != NULL)
946 {
947 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
948 if (BindingHandle == NULL)
949 return CR_FAILURE;
950 }
951 else
952 {
953 if (!PnpGetLocalHandles(&BindingHandle, NULL))
954 return CR_FAILURE;
955 }
956
957 return PNP_GetClassName(BindingHandle,
958 szGuidString,
959 Buffer,
960 pulLength,
961 ulFlags);
962 }
963
964
965 /***********************************************************************
966 * CM_Get_Depth [SETUPAPI.@]
967 */
968 CONFIGRET WINAPI CM_Get_Depth(
969 PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags)
970 {
971 TRACE("%p %lx %lx\n", pulDepth, dnDevInst, ulFlags);
972 return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
973 }
974
975
976 /***********************************************************************
977 * CM_Get_Depth_Ex [SETUPAPI.@]
978 */
979 CONFIGRET WINAPI CM_Get_Depth_Ex(
980 PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
981 {
982 RPC_BINDING_HANDLE BindingHandle = NULL;
983 HSTRING_TABLE StringTable = NULL;
984 LPWSTR lpDevInst;
985
986 TRACE("%p %lx %lx %lx\n",
987 pulDepth, dnDevInst, ulFlags, hMachine);
988
989 if (pulDepth == NULL)
990 return CR_INVALID_POINTER;
991
992 if (dnDevInst == 0)
993 return CR_INVALID_DEVINST;
994
995 if (ulFlags != 0)
996 return CR_INVALID_FLAG;
997
998 if (hMachine != NULL)
999 {
1000 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1001 if (BindingHandle == NULL)
1002 return CR_FAILURE;
1003
1004 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1005 if (StringTable == 0)
1006 return CR_FAILURE;
1007 }
1008 else
1009 {
1010 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1011 return CR_FAILURE;
1012 }
1013
1014 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1015 if (lpDevInst == NULL)
1016 return CR_INVALID_DEVNODE;
1017
1018 return PNP_GetDepth(BindingHandle,
1019 lpDevInst,
1020 pulDepth,
1021 ulFlags);
1022 }
1023
1024
1025 /***********************************************************************
1026 * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
1027 */
1028 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA(
1029 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1030 PVOID Buffer, PULONG pulLength, ULONG ulFlags)
1031 {
1032 TRACE("%lx %lu %p %p %p %lx\n",
1033 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
1034
1035 return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
1036 pulRegDataType, Buffer,
1037 pulLength, ulFlags, NULL);
1038 }
1039
1040
1041 /***********************************************************************
1042 * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
1043 */
1044 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(
1045 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1046 PVOID Buffer, PULONG pulLength, ULONG ulFlags)
1047 {
1048 TRACE("%lx %lu %p %p %p %lx\n",
1049 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
1050
1051 return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
1052 pulRegDataType, Buffer,
1053 pulLength, ulFlags, NULL);
1054 }
1055
1056
1057 /***********************************************************************
1058 * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
1059 */
1060 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExA(
1061 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1062 PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
1063 {
1064 PVOID BufferW;
1065 ULONG LengthW;
1066 ULONG RegDataType;
1067 CONFIGRET ret;
1068
1069 TRACE("%lx %lu %p %p %p %lx %lx\n",
1070 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
1071 ulFlags, hMachine);
1072
1073 if (!pulLength)
1074 return CR_INVALID_POINTER;
1075
1076 LengthW = *pulLength * sizeof(WCHAR);
1077 BufferW = HeapAlloc(GetProcessHeap(), 0, LengthW);
1078
1079 if (!BufferW)
1080 return CR_OUT_OF_MEMORY;
1081
1082 ret = CM_Get_DevNode_Registry_Property_ExW(dnDevInst,
1083 ulProperty,
1084 &RegDataType,
1085 BufferW,
1086 &LengthW,
1087 ulFlags,
1088 hMachine);
1089
1090 if (ret == CR_SUCCESS)
1091 {
1092 if (RegDataType == REG_SZ || RegDataType == REG_EXPAND_SZ)
1093 {
1094 /* Do W->A conversion */
1095 *pulLength = WideCharToMultiByte(CP_ACP,
1096 0,
1097 BufferW,
1098 lstrlenW(BufferW) + 1,
1099 Buffer,
1100 *pulLength,
1101 NULL,
1102 NULL);
1103 if (*pulLength == 0)
1104 ret = CR_FAILURE;
1105 }
1106 else
1107 {
1108 /* Directly copy the value */
1109 if (LengthW <= *pulLength)
1110 memcpy(Buffer, BufferW, LengthW);
1111 else
1112 {
1113 *pulLength = LengthW;
1114 ret = CR_BUFFER_SMALL;
1115 }
1116 }
1117 }
1118
1119 if (pulRegDataType)
1120 *pulRegDataType = RegDataType;
1121
1122 HeapFree(GetProcessHeap(), 0, BufferW);
1123
1124 return ret;
1125 }
1126
1127
1128 /***********************************************************************
1129 * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
1130 */
1131 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW(
1132 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
1133 PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
1134 {
1135 RPC_BINDING_HANDLE BindingHandle = NULL;
1136 HSTRING_TABLE StringTable = NULL;
1137 CONFIGRET ret = CR_SUCCESS;
1138 LPWSTR lpDevInst;
1139 ULONG ulDataType = 0;
1140 ULONG ulTransferLength = 0;
1141
1142 TRACE("%lx %lu %p %p %p %lx %lx\n",
1143 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
1144 ulFlags, hMachine);
1145
1146 if (dnDevInst == 0)
1147 return CR_INVALID_DEVNODE;
1148
1149 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
1150 return CR_INVALID_PROPERTY;
1151
1152 /* pulRegDataType is optional */
1153
1154 /* Buffer is optional */
1155
1156 if (pulLength == NULL)
1157 return CR_INVALID_POINTER;
1158
1159 if (*pulLength == 0)
1160 return CR_INVALID_POINTER;
1161
1162 if (ulFlags != 0)
1163 return CR_INVALID_FLAG;
1164
1165 if (hMachine != NULL)
1166 {
1167 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1168 if (BindingHandle == NULL)
1169 return CR_FAILURE;
1170
1171 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1172 if (StringTable == 0)
1173 return CR_FAILURE;
1174 }
1175 else
1176 {
1177 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1178 return CR_FAILURE;
1179 }
1180
1181 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1182 if (lpDevInst == NULL)
1183 return CR_INVALID_DEVNODE;
1184
1185 ulTransferLength = *pulLength;
1186 ret = PNP_GetDeviceRegProp(BindingHandle,
1187 lpDevInst,
1188 ulProperty,
1189 &ulDataType,
1190 Buffer,
1191 &ulTransferLength,
1192 pulLength,
1193 ulFlags);
1194 if (ret == CR_SUCCESS)
1195 {
1196 if (pulRegDataType != NULL)
1197 *pulRegDataType = ulDataType;
1198 }
1199
1200 return ret;
1201 }
1202
1203
1204 /***********************************************************************
1205 * CM_Get_DevNode_Status [SETUPAPI.@]
1206 */
1207 CONFIGRET WINAPI CM_Get_DevNode_Status(
1208 PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
1209 ULONG ulFlags)
1210 {
1211 TRACE("%p %p %lx %lx\n",
1212 pulStatus, pulProblemNumber, dnDevInst, ulFlags);
1213 return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
1214 ulFlags, NULL);
1215 }
1216
1217
1218 /***********************************************************************
1219 * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
1220 */
1221 CONFIGRET WINAPI
1222 CM_Get_DevNode_Status_Ex(
1223 PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
1224 ULONG ulFlags, HMACHINE hMachine)
1225 {
1226 RPC_BINDING_HANDLE BindingHandle = NULL;
1227 HSTRING_TABLE StringTable = NULL;
1228 LPWSTR lpDevInst;
1229
1230 TRACE("%p %p %lx %lx %lx\n",
1231 pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
1232
1233 if (pulStatus == NULL || pulProblemNumber == NULL)
1234 return CR_INVALID_POINTER;
1235
1236 if (dnDevInst == 0)
1237 return CR_INVALID_DEVINST;
1238
1239 if (ulFlags != 0)
1240 return CR_INVALID_FLAG;
1241
1242 if (hMachine != NULL)
1243 {
1244 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1245 if (BindingHandle == NULL)
1246 return CR_FAILURE;
1247
1248 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1249 if (StringTable == 0)
1250 return CR_FAILURE;
1251 }
1252 else
1253 {
1254 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1255 return CR_FAILURE;
1256 }
1257
1258 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1259 if (lpDevInst == NULL)
1260 return CR_INVALID_DEVNODE;
1261
1262 return PNP_GetDeviceStatus(BindingHandle,
1263 lpDevInst,
1264 pulStatus,
1265 pulProblemNumber,
1266 ulFlags);
1267 }
1268
1269
1270 /***********************************************************************
1271 * CM_Get_Device_IDA [SETUPAPI.@]
1272 */
1273 CONFIGRET WINAPI CM_Get_Device_IDA(
1274 DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1275 {
1276 TRACE("%lx %p %ld %ld\n",
1277 dnDevInst, Buffer, BufferLen, ulFlags);
1278 return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
1279 }
1280
1281
1282 /***********************************************************************
1283 * CM_Get_Device_IDW [SETUPAPI.@]
1284 */
1285 CONFIGRET WINAPI CM_Get_Device_IDW(
1286 DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1287 {
1288 TRACE("%lx %p %ld %ld\n",
1289 dnDevInst, Buffer, BufferLen, ulFlags);
1290 return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
1291 }
1292
1293
1294 /***********************************************************************
1295 * CM_Get_Device_ID_ExA [SETUPAPI.@]
1296 */
1297 CONFIGRET WINAPI CM_Get_Device_ID_ExA(
1298 DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1299 HMACHINE hMachine)
1300 {
1301 WCHAR szBufferW[MAX_DEVICE_ID_LEN];
1302 CONFIGRET ret = CR_SUCCESS;
1303
1304 FIXME("%lx %p %ld %ld %lx\n",
1305 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
1306
1307 if (Buffer == NULL)
1308 return CR_INVALID_POINTER;
1309
1310 ret = CM_Get_Device_ID_ExW(dnDevInst,
1311 szBufferW,
1312 MAX_DEVICE_ID_LEN,
1313 ulFlags,
1314 hMachine);
1315 if (ret == CR_SUCCESS)
1316 {
1317 if (WideCharToMultiByte(CP_ACP,
1318 0,
1319 szBufferW,
1320 lstrlenW(szBufferW) + 1,
1321 Buffer,
1322 BufferLen,
1323 NULL,
1324 NULL) == 0)
1325 ret = CR_FAILURE;
1326 }
1327
1328 return ret;
1329 }
1330
1331
1332 /***********************************************************************
1333 * CM_Get_Device_ID_ExW [SETUPAPI.@]
1334 */
1335 CONFIGRET WINAPI CM_Get_Device_ID_ExW(
1336 DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1337 HMACHINE hMachine)
1338 {
1339 HSTRING_TABLE StringTable = NULL;
1340
1341 TRACE("%lx %p %ld %ld %lx\n",
1342 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
1343
1344 if (dnDevInst == 0)
1345 return CR_INVALID_DEVINST;
1346
1347 if (Buffer == NULL)
1348 return CR_INVALID_POINTER;
1349
1350 if (ulFlags != 0)
1351 return CR_INVALID_FLAG;
1352
1353 if (hMachine != NULL)
1354 {
1355 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1356 if (StringTable == NULL)
1357 return CR_FAILURE;
1358 }
1359 else
1360 {
1361 if (!PnpGetLocalHandles(NULL, &StringTable))
1362 return CR_FAILURE;
1363 }
1364
1365 if (!StringTableStringFromIdEx(StringTable,
1366 dnDevInst,
1367 Buffer,
1368 &BufferLen))
1369 return CR_FAILURE;
1370
1371 return CR_SUCCESS;
1372 }
1373
1374
1375 /***********************************************************************
1376 * CM_Get_Device_ID_ListA [SETUPAPI.@]
1377 */
1378 CONFIGRET WINAPI CM_Get_Device_ID_ListA(
1379 PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1380 {
1381 TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
1382 return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
1383 ulFlags, NULL);
1384 }
1385
1386
1387 /***********************************************************************
1388 * CM_Get_Device_ID_ListW [SETUPAPI.@]
1389 */
1390 CONFIGRET WINAPI CM_Get_Device_ID_ListW(
1391 PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1392 {
1393 TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
1394 return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
1395 ulFlags, NULL);
1396 }
1397
1398
1399 /***********************************************************************
1400 * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
1401 */
1402 CONFIGRET WINAPI CM_Get_Device_ID_List_ExA(
1403 PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1404 HMACHINE hMachine)
1405 {
1406 LPWSTR BufferW = NULL;
1407 LPWSTR pszFilterW = NULL;
1408 CONFIGRET ret = CR_SUCCESS;
1409
1410 FIXME("%p %p %ld %ld %lx\n",
1411 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
1412
1413 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
1414 if (BufferW == NULL)
1415 return CR_OUT_OF_MEMORY;
1416
1417 if (pszFilter == NULL)
1418 {
1419 ret = CM_Get_Device_ID_List_ExW(NULL,
1420 BufferW,
1421 BufferLen,
1422 ulFlags,
1423 hMachine);
1424 }
1425 else
1426 {
1427 if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
1428 {
1429 ret = CR_INVALID_DEVICE_ID;
1430 goto Done;
1431 }
1432
1433 ret = CM_Get_Device_ID_List_ExW(pszFilterW,
1434 BufferW,
1435 BufferLen,
1436 ulFlags,
1437 hMachine);
1438
1439 MyFree(pszFilterW);
1440 }
1441
1442 if (WideCharToMultiByte(CP_ACP,
1443 0,
1444 BufferW,
1445 lstrlenW(BufferW) + 1,
1446 Buffer,
1447 BufferLen,
1448 NULL,
1449 NULL) == 0)
1450 ret = CR_FAILURE;
1451
1452 Done:
1453 MyFree(BufferW);
1454
1455 return ret;
1456 }
1457
1458
1459 /***********************************************************************
1460 * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
1461 */
1462 CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(
1463 PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1464 HMACHINE hMachine)
1465 {
1466 FIXME("%p %p %ld %ld %lx\n",
1467 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
1468 memset(Buffer,0,2);
1469 return CR_SUCCESS;
1470 }
1471
1472
1473 /***********************************************************************
1474 * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
1475 */
1476 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(
1477 PULONG pulLen, PCSTR pszFilter, ULONG ulFlags)
1478 {
1479 TRACE("%p %s %ld\n", pulLen, pszFilter, ulFlags);
1480 return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
1481 }
1482
1483
1484 /***********************************************************************
1485 * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
1486 */
1487 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(
1488 PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags)
1489 {
1490 TRACE("%p %s %ld\n", pulLen, debugstr_w(pszFilter), ulFlags);
1491 return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
1492 }
1493
1494
1495 /***********************************************************************
1496 * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
1497 */
1498 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA(
1499 PULONG pulLen, PCSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
1500 {
1501 LPWSTR pszFilterW = NULL;
1502 CONFIGRET ret = CR_SUCCESS;
1503
1504 FIXME("%p %s %lx %lx\n", pulLen, pszFilter, ulFlags, hMachine);
1505
1506 if (pszFilter == NULL)
1507 {
1508 ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
1509 NULL,
1510 ulFlags,
1511 hMachine);
1512 }
1513 else
1514 {
1515 if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
1516 return CR_INVALID_DEVICE_ID;
1517
1518 ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
1519 pszFilterW,
1520 ulFlags,
1521 hMachine);
1522
1523 MyFree(pszFilterW);
1524 }
1525
1526 return ret;
1527 }
1528
1529
1530 /***********************************************************************
1531 * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
1532 */
1533 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(
1534 PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
1535 {
1536 RPC_BINDING_HANDLE BindingHandle = NULL;
1537
1538 FIXME("%p %s %ld %lx\n", pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
1539
1540 if (pulLen == NULL)
1541 return CR_INVALID_POINTER;
1542
1543 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
1544 return CR_INVALID_FLAG;
1545
1546 if (hMachine != NULL)
1547 {
1548 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1549 if (BindingHandle == NULL)
1550 return CR_FAILURE;
1551 }
1552 else
1553 {
1554 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1555 return CR_FAILURE;
1556 }
1557
1558 *pulLen = 0;
1559
1560 return PNP_GetDeviceListSize(BindingHandle,
1561 (LPWSTR)pszFilter,
1562 pulLen,
1563 ulFlags);
1564 }
1565
1566
1567 /***********************************************************************
1568 * CM_Get_Device_ID_Size [SETUPAPI.@]
1569 */
1570 CONFIGRET WINAPI CM_Get_Device_ID_Size(
1571 PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags)
1572 {
1573 TRACE("%p %lx %lx\n", pulLen, dnDevInst, ulFlags);
1574 return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
1575 }
1576
1577
1578 /***********************************************************************
1579 * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
1580 */
1581 CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex(
1582 PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1583 {
1584 HSTRING_TABLE StringTable = NULL;
1585 LPWSTR DeviceId;
1586
1587 TRACE("%p %lx %lx %lx\n", pulLen, dnDevInst, ulFlags, hMachine);
1588
1589 if (pulLen == NULL)
1590 return CR_INVALID_POINTER;
1591
1592 if (dnDevInst == 0)
1593 return CR_INVALID_DEVINST;
1594
1595 if (ulFlags != 0)
1596 return CR_INVALID_FLAG;
1597
1598 if (hMachine != NULL)
1599 {
1600 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1601 if (StringTable == NULL)
1602 return CR_FAILURE;
1603 }
1604 else
1605 {
1606 if (!PnpGetLocalHandles(NULL, &StringTable))
1607 return CR_FAILURE;
1608 }
1609
1610 DeviceId = StringTableStringFromId(StringTable, dnDevInst);
1611 if (DeviceId == NULL)
1612 {
1613 *pulLen = 0;
1614 return CR_SUCCESS;
1615 }
1616
1617 *pulLen = lstrlenW(DeviceId);
1618
1619 return CR_SUCCESS;
1620 }
1621
1622
1623 /***********************************************************************
1624 * CM_Get_Global_State [SETUPAPI.@]
1625 */
1626 CONFIGRET WINAPI CM_Get_Global_State(
1627 PULONG pulState, ULONG ulFlags)
1628 {
1629 TRACE("%p %lx\n", pulState, ulFlags);
1630 return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
1631 }
1632
1633
1634 /***********************************************************************
1635 * CM_Get_Global_State_Ex [SETUPAPI.@]
1636 */
1637 CONFIGRET WINAPI CM_Get_Global_State_Ex(
1638 PULONG pulState, ULONG ulFlags, HMACHINE hMachine)
1639 {
1640 RPC_BINDING_HANDLE BindingHandle = NULL;
1641
1642 TRACE("%p %lx %lx\n", pulState, ulFlags, hMachine);
1643
1644 if (pulState == NULL)
1645 return CR_INVALID_POINTER;
1646
1647 if (ulFlags != 0)
1648 return CR_INVALID_FLAG;
1649
1650 if (hMachine != NULL)
1651 {
1652 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1653 if (BindingHandle == NULL)
1654 return CR_FAILURE;
1655 }
1656 else
1657 {
1658 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1659 return CR_FAILURE;
1660 }
1661
1662 return PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
1663 }
1664
1665
1666 /***********************************************************************
1667 * CM_Get_Parent [SETUPAPI.@]
1668 */
1669 CONFIGRET WINAPI CM_Get_Parent(
1670 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
1671 {
1672 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
1673 return CM_Get_Parent_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
1674 }
1675
1676
1677 /***********************************************************************
1678 * CM_Get_Parent_Ex [SETUPAPI.@]
1679 */
1680 CONFIGRET WINAPI CM_Get_Parent_Ex(
1681 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1682 {
1683 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
1684 RPC_BINDING_HANDLE BindingHandle = NULL;
1685 HSTRING_TABLE StringTable = NULL;
1686 LPWSTR lpDevInst;
1687 DWORD dwIndex;
1688 CONFIGRET ret;
1689
1690 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
1691
1692 if (pdnDevInst == NULL)
1693 return CR_INVALID_POINTER;
1694
1695 if (dnDevInst == 0)
1696 return CR_INVALID_DEVINST;
1697
1698 if (ulFlags != 0)
1699 return CR_INVALID_FLAG;
1700
1701 *pdnDevInst = -1;
1702
1703 if (hMachine != NULL)
1704 {
1705 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1706 if (BindingHandle == NULL)
1707 return CR_FAILURE;
1708
1709 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1710 if (StringTable == 0)
1711 return CR_FAILURE;
1712 }
1713 else
1714 {
1715 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1716 return CR_FAILURE;
1717 }
1718
1719 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1720 if (lpDevInst == NULL)
1721 return CR_INVALID_DEVNODE;
1722
1723 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
1724 PNP_DEVICE_PARENT,
1725 lpDevInst,
1726 szRelatedDevInst,
1727 MAX_DEVICE_ID_LEN,
1728 0);
1729 if (ret != CR_SUCCESS)
1730 return ret;
1731
1732 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
1733
1734 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
1735 if (dwIndex == -1)
1736 return CR_FAILURE;
1737
1738 *pdnDevInst = dwIndex;
1739
1740 return CR_SUCCESS;
1741 }
1742
1743
1744 /***********************************************************************
1745 * CM_Get_Sibling [SETUPAPI.@]
1746 */
1747 CONFIGRET WINAPI CM_Get_Sibling(
1748 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
1749 {
1750 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
1751 return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
1752 }
1753
1754
1755 /***********************************************************************
1756 * CM_Get_Sibling_Ex [SETUPAPI.@]
1757 */
1758 CONFIGRET WINAPI CM_Get_Sibling_Ex(
1759 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1760 {
1761 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
1762 RPC_BINDING_HANDLE BindingHandle = NULL;
1763 HSTRING_TABLE StringTable = NULL;
1764 LPWSTR lpDevInst;
1765 DWORD dwIndex;
1766 CONFIGRET ret;
1767
1768 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
1769
1770 if (pdnDevInst == NULL)
1771 return CR_INVALID_POINTER;
1772
1773 if (dnDevInst == 0)
1774 return CR_INVALID_DEVINST;
1775
1776 if (ulFlags != 0)
1777 return CR_INVALID_FLAG;
1778
1779 *pdnDevInst = -1;
1780
1781 if (hMachine != NULL)
1782 {
1783 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1784 if (BindingHandle == NULL)
1785 return CR_FAILURE;
1786
1787 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1788 if (StringTable == 0)
1789 return CR_FAILURE;
1790 }
1791 else
1792 {
1793 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1794 return CR_FAILURE;
1795 }
1796
1797 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1798 if (lpDevInst == NULL)
1799 return CR_INVALID_DEVNODE;
1800
1801 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
1802 PNP_DEVICE_SIBLING,
1803 lpDevInst,
1804 szRelatedDevInst,
1805 MAX_DEVICE_ID_LEN,
1806 0);
1807 if (ret != CR_SUCCESS)
1808 return ret;
1809
1810 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
1811
1812 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
1813 if (dwIndex == -1)
1814 return CR_FAILURE;
1815
1816 *pdnDevInst = dwIndex;
1817
1818 return CR_SUCCESS;
1819 }
1820
1821
1822 /***********************************************************************
1823 * CM_Get_Version [SETUPAPI.@]
1824 */
1825 WORD WINAPI CM_Get_Version(VOID)
1826 {
1827 TRACE("\n");
1828 return CM_Get_Version_Ex(NULL);
1829 }
1830
1831
1832 /***********************************************************************
1833 * CM_Get_Version_Ex [SETUPAPI.@]
1834 */
1835 WORD WINAPI CM_Get_Version_Ex(HMACHINE hMachine)
1836 {
1837 RPC_BINDING_HANDLE BindingHandle = NULL;
1838 WORD Version = 0;
1839
1840 TRACE("%lx\n", hMachine);
1841
1842 if (hMachine != NULL)
1843 {
1844 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1845 if (BindingHandle == NULL)
1846 return 0;
1847 }
1848 else
1849 {
1850 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1851 return CR_FAILURE;
1852 }
1853
1854 if (PNP_GetVersion(BindingHandle, &Version) != CR_SUCCESS)
1855 return 0;
1856
1857 return Version;
1858 }
1859
1860
1861 /***********************************************************************
1862 * CM_Is_Dock_Station_Present [SETUPAPI.@]
1863 */
1864 CONFIGRET WINAPI CM_Is_Dock_Station_Present(
1865 PBOOL pbPresent)
1866 {
1867 TRACE("%p\n", pbPresent);
1868 return CM_Is_Dock_Station_Present_Ex(pbPresent, NULL);
1869 }
1870
1871
1872 /***********************************************************************
1873 * CM_Is_Dock_Station_Present_Ex [SETUPAPI.@]
1874 */
1875 CONFIGRET WINAPI CM_Is_Dock_Station_Present_Ex(
1876 PBOOL pbPresent, HMACHINE hMachine)
1877 {
1878 RPC_BINDING_HANDLE BindingHandle = NULL;
1879
1880 TRACE("%p %lx\n", pbPresent, hMachine);
1881
1882 if (pbPresent == NULL)
1883 return CR_INVALID_POINTER;
1884
1885 *pbPresent = FALSE;
1886
1887 if (hMachine != NULL)
1888 {
1889 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1890 if (BindingHandle == NULL)
1891 return CR_FAILURE;
1892 }
1893 else
1894 {
1895 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1896 return CR_FAILURE;
1897 }
1898
1899 return PNP_IsDockStationPresent(BindingHandle,
1900 (unsigned long *)pbPresent);
1901 }
1902
1903
1904 /***********************************************************************
1905 * CM_Locate_DevNodeA [SETUPAPI.@]
1906 */
1907 CONFIGRET WINAPI CM_Locate_DevNodeA(
1908 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
1909 {
1910 TRACE("%p %s %lu\n", pdnDevInst, pDeviceID, ulFlags);
1911 return CM_Locate_DevNode_ExA(pdnDevInst, pDeviceID, ulFlags, NULL);
1912 }
1913
1914
1915 /***********************************************************************
1916 * CM_Locate_DevNodeW [SETUPAPI.@]
1917 */
1918 CONFIGRET WINAPI CM_Locate_DevNodeW(
1919 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags)
1920 {
1921 TRACE("%p %s %lu\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags);
1922 return CM_Locate_DevNode_ExW(pdnDevInst, pDeviceID, ulFlags, NULL);
1923 }
1924
1925
1926 /***********************************************************************
1927 * CM_Locate_DevNode_ExA [SETUPAPI.@]
1928 */
1929 CONFIGRET WINAPI CM_Locate_DevNode_ExA(
1930 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine)
1931 {
1932 DEVINSTID_W pDevIdW = NULL;
1933 CONFIGRET ret = CR_SUCCESS;
1934
1935 TRACE("%p %s %lu %lx\n", pdnDevInst, pDeviceID, ulFlags, hMachine);
1936
1937 if (pDeviceID != NULL)
1938 {
1939 if (CaptureAndConvertAnsiArg(pDeviceID, &pDevIdW))
1940 return CR_INVALID_DEVICE_ID;
1941 }
1942
1943 ret = CM_Locate_DevNode_ExW(pdnDevInst, pDevIdW, ulFlags, hMachine);
1944
1945 if (pDevIdW != NULL)
1946 MyFree(pDevIdW);
1947
1948 return ret;
1949 }
1950
1951
1952 /***********************************************************************
1953 * CM_Locate_DevNode_ExW [SETUPAPI.@]
1954 */
1955 CONFIGRET WINAPI CM_Locate_DevNode_ExW(
1956 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine)
1957 {
1958 WCHAR DeviceIdBuffer[MAX_DEVICE_ID_LEN];
1959 RPC_BINDING_HANDLE BindingHandle = NULL;
1960 HSTRING_TABLE StringTable = NULL;
1961 CONFIGRET ret = CR_SUCCESS;
1962
1963 TRACE("%p %s %lu %lx\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine);
1964
1965 if (pdnDevInst == NULL)
1966 return CR_INVALID_POINTER;
1967
1968 if (ulFlags & ~CM_LOCATE_DEVNODE_BITS)
1969 return CR_INVALID_FLAG;
1970
1971 if (hMachine != NULL)
1972 {
1973 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1974 if (BindingHandle == NULL)
1975 return CR_FAILURE;
1976
1977 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1978 if (StringTable == 0)
1979 return CR_FAILURE;
1980 }
1981 else
1982 {
1983 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1984 return CR_FAILURE;
1985 }
1986
1987 if (pDeviceID != NULL && lstrlenW(pDeviceID) != 0)
1988 {
1989 lstrcpyW(DeviceIdBuffer, pDeviceID);
1990 }
1991 else
1992 {
1993 /* Get the root device ID */
1994 ret = PNP_GetRootDeviceInstance(BindingHandle,
1995 DeviceIdBuffer,
1996 MAX_DEVICE_ID_LEN);
1997 if (ret != CR_SUCCESS)
1998 return CR_FAILURE;
1999 }
2000 TRACE("DeviceIdBuffer: %s\n", debugstr_w(DeviceIdBuffer));
2001
2002 /* Validate the device ID */
2003 ret = PNP_ValidateDeviceInstance(BindingHandle,
2004 DeviceIdBuffer,
2005 ulFlags);
2006 if (ret == CR_SUCCESS)
2007 {
2008 *pdnDevInst = StringTableAddString(StringTable, DeviceIdBuffer, 1);
2009 if (*pdnDevInst == -1)
2010 ret = CR_FAILURE;
2011 }
2012
2013 return ret;
2014 }
2015
2016
2017 /***********************************************************************
2018 * CM_Move_DevNode [SETUPAPI.@]
2019 */
2020 CONFIGRET WINAPI CM_Move_DevNode(
2021 DEVINST dnFromDevInst, DEVINST dnToDevInst, ULONG ulFlags)
2022 {
2023 TRACE("%lx %lx %lx\n", dnFromDevInst, dnToDevInst, ulFlags);
2024 return CM_Move_DevNode_Ex(dnFromDevInst, dnToDevInst, ulFlags, NULL);
2025 }
2026
2027
2028 /***********************************************************************
2029 * CM_Move_DevNode_Ex [SETUPAPI.@]
2030 */
2031 CONFIGRET WINAPI CM_Move_DevNode_Ex(
2032 DEVINST dnFromDevInst, DEVINST dnToDevInst, ULONG ulFlags,
2033 HMACHINE hMachine)
2034 {
2035 RPC_BINDING_HANDLE BindingHandle = NULL;
2036 HSTRING_TABLE StringTable = NULL;
2037 LPWSTR lpFromDevInst;
2038 LPWSTR lpToDevInst;
2039
2040 FIXME("%lx %lx %lx %lx\n",
2041 dnFromDevInst, dnToDevInst, ulFlags, hMachine);
2042
2043 if (!IsUserAdmin())
2044 return CR_ACCESS_DENIED;
2045
2046 if (dnFromDevInst == 0 || dnToDevInst == 0)
2047 return CR_INVALID_DEVNODE;
2048
2049 if (ulFlags != 0)
2050 return CR_INVALID_FLAG;
2051
2052 if (hMachine != NULL)
2053 {
2054 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2055 if (BindingHandle == NULL)
2056 return CR_FAILURE;
2057
2058 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2059 if (StringTable == 0)
2060 return CR_FAILURE;
2061 }
2062 else
2063 {
2064 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2065 return CR_FAILURE;
2066 }
2067
2068 lpFromDevInst = StringTableStringFromId(StringTable, dnFromDevInst);
2069 if (lpFromDevInst == NULL)
2070 return CR_INVALID_DEVNODE;
2071
2072 lpToDevInst = StringTableStringFromId(StringTable, dnToDevInst);
2073 if (lpToDevInst == NULL)
2074 return CR_INVALID_DEVNODE;
2075
2076 return PNP_DeviceInstanceAction(BindingHandle,
2077 2,
2078 ulFlags,
2079 lpFromDevInst,
2080 lpToDevInst);
2081 }
2082
2083
2084 /***********************************************************************
2085 * CM_Open_Class_KeyA [SETUPAPI.@]
2086 */
2087 CONFIGRET WINAPI CM_Open_Class_KeyA(
2088 LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
2089 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
2090 {
2091 TRACE("%p %s %lx %lx %p %lx\n",
2092 debugstr_guid(pClassGuid), pszClassName,
2093 samDesired, Disposition, phkClass, ulFlags);
2094
2095 return CM_Open_Class_Key_ExA(pClassGuid, pszClassName, samDesired,
2096 Disposition, phkClass, ulFlags, NULL);
2097 }
2098
2099
2100 /***********************************************************************
2101 * CM_Open_Class_KeyW [SETUPAPI.@]
2102 */
2103 CONFIGRET WINAPI CM_Open_Class_KeyW(
2104 LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
2105 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
2106 {
2107 TRACE("%p %s %lx %lx %p %lx\n",
2108 debugstr_guid(pClassGuid), debugstr_w(pszClassName),
2109 samDesired, Disposition, phkClass, ulFlags);
2110
2111 return CM_Open_Class_Key_ExW(pClassGuid, pszClassName, samDesired,
2112 Disposition, phkClass, ulFlags, NULL);
2113 }
2114
2115
2116 /***********************************************************************
2117 * CM_Open_Class_Key_ExA [SETUPAPI.@]
2118 */
2119 CONFIGRET WINAPI CM_Open_Class_Key_ExA(
2120 LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
2121 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
2122 HMACHINE hMachine)
2123 {
2124 CONFIGRET rc = CR_SUCCESS;
2125 LPWSTR pszClassNameW = NULL;
2126
2127 TRACE("%p %s %lx %lx %p %lx %lx\n",
2128 debugstr_guid(pClassGuid), pszClassName,
2129 samDesired, Disposition, phkClass, ulFlags, hMachine);
2130
2131 if (pszClassName != NULL)
2132 {
2133 if (CaptureAndConvertAnsiArg(pszClassName, &pszClassNameW))
2134 return CR_INVALID_DATA;
2135 }
2136
2137 rc = CM_Open_Class_Key_ExW(pClassGuid, pszClassNameW, samDesired,
2138 Disposition, phkClass, ulFlags, hMachine);
2139
2140 if (pszClassNameW != NULL)
2141 MyFree(pszClassNameW);
2142
2143 return CR_SUCCESS;
2144 }
2145
2146
2147 /***********************************************************************
2148 * CM_Open_Class_Key_ExW [SETUPAPI.@]
2149 */
2150 CONFIGRET WINAPI CM_Open_Class_Key_ExW(
2151 LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
2152 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
2153 HMACHINE hMachine)
2154 {
2155 WCHAR szKeyName[MAX_PATH];
2156 LPWSTR lpGuidString;
2157 DWORD dwDisposition;
2158 DWORD dwError;
2159 HKEY hKey;
2160
2161 TRACE("%p %s %lx %lx %p %lx %lx\n",
2162 debugstr_guid(pClassGuid), debugstr_w(pszClassName),
2163 samDesired, Disposition, phkClass, ulFlags, hMachine);
2164
2165 /* Check Disposition and ulFlags */
2166 if ((Disposition & ~RegDisposition_Bits) ||
2167 (ulFlags & ~CM_OPEN_CLASS_KEY_BITS))
2168 return CR_INVALID_FLAG;
2169
2170 /* Check phkClass */
2171 if (phkClass == NULL)
2172 return CR_INVALID_POINTER;
2173
2174 *phkClass = NULL;
2175
2176 if (ulFlags == CM_OPEN_CLASS_KEY_INTERFACE &&
2177 pszClassName != NULL)
2178 return CR_INVALID_DATA;
2179
2180 if (hMachine == NULL)
2181 {
2182 hKey = HKEY_LOCAL_MACHINE;
2183 }
2184 else
2185 {
2186 if (RegConnectRegistryW(((PMACHINE_INFO)hMachine)->szMachineName,
2187 HKEY_LOCAL_MACHINE, &hKey))
2188 return CR_REGISTRY_ERROR;
2189 }
2190
2191 if (ulFlags & CM_OPEN_CLASS_KEY_INTERFACE)
2192 {
2193 lstrcpyW(szKeyName, DeviceClasses);
2194 }
2195 else
2196 {
2197 lstrcpyW(szKeyName, ControlClass);
2198 }
2199
2200 if (pClassGuid != NULL)
2201 {
2202 if (UuidToStringW((UUID*)pClassGuid, &lpGuidString) != RPC_S_OK)
2203 {
2204 RegCloseKey(hKey);
2205 return CR_INVALID_DATA;
2206 }
2207
2208 lstrcatW(szKeyName, Backslash);
2209 lstrcatW(szKeyName, lpGuidString);
2210 }
2211
2212 if (Disposition == RegDisposition_OpenAlways)
2213 {
2214 dwError = RegCreateKeyExW(hKey, szKeyName, 0, NULL, 0, samDesired,
2215 NULL, phkClass, &dwDisposition);
2216 }
2217 else
2218 {
2219 dwError = RegOpenKeyExW(hKey, szKeyName, 0, samDesired, phkClass);
2220 }
2221
2222 RegCloseKey(hKey);
2223
2224 if (pClassGuid != NULL)
2225 RpcStringFreeW(&lpGuidString);
2226
2227 if (dwError != ERROR_SUCCESS)
2228 {
2229 *phkClass = NULL;
2230 return CR_NO_SUCH_REGISTRY_KEY;
2231 }
2232
2233 if (pszClassName != NULL)
2234 {
2235 RegSetValueExW(*phkClass, Class, 0, REG_SZ, (LPBYTE)pszClassName,
2236 (lstrlenW(pszClassName) + 1) * sizeof(WCHAR));
2237 }
2238
2239 return CR_SUCCESS;
2240 }
2241
2242
2243 /***********************************************************************
2244 * CM_Reenumerate_DevNode [SETUPAPI.@]
2245 */
2246 CONFIGRET WINAPI CM_Reenumerate_DevNode(
2247 DEVINST dnDevInst, ULONG ulFlags)
2248 {
2249 TRACE("%lx %lx\n", dnDevInst, ulFlags);
2250 return CM_Reenumerate_DevNode_Ex(dnDevInst, ulFlags, NULL);
2251 }
2252
2253
2254 /***********************************************************************
2255 * CM_Reenumerate_DevNode_Ex [SETUPAPI.@]
2256 */
2257 CONFIGRET WINAPI
2258 CM_Reenumerate_DevNode_Ex(
2259 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
2260 {
2261 RPC_BINDING_HANDLE BindingHandle = NULL;
2262 HSTRING_TABLE StringTable = NULL;
2263 LPWSTR lpDevInst;
2264
2265 FIXME("%lx %lx %lx\n", dnDevInst, ulFlags, hMachine);
2266
2267 if (dnDevInst == 0)
2268 return CR_INVALID_DEVNODE;
2269
2270 if (ulFlags & ~CM_REENUMERATE_BITS)
2271 return CR_INVALID_FLAG;
2272
2273 if (hMachine != NULL)
2274 {
2275 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2276 if (BindingHandle == NULL)
2277 return CR_FAILURE;
2278
2279 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2280 if (StringTable == 0)
2281 return CR_FAILURE;
2282 }
2283 else
2284 {
2285 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2286 return CR_FAILURE;
2287 }
2288
2289 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2290 if (lpDevInst == NULL)
2291 return CR_INVALID_DEVNODE;
2292
2293 return PNP_DeviceInstanceAction(BindingHandle,
2294 7,
2295 ulFlags,
2296 lpDevInst,
2297 NULL);
2298 }
2299
2300
2301 /***********************************************************************
2302 * CM_Request_Eject_PC [SETUPAPI.@]
2303 */
2304 CONFIGRET WINAPI CM_Request_Eject_PC(VOID)
2305 {
2306 TRACE("\n");
2307 return CM_Request_Eject_PC_Ex(NULL);
2308 }
2309
2310
2311 /***********************************************************************
2312 * CM_Request_Eject_PC_Ex [SETUPAPI.@]
2313 */
2314 CONFIGRET WINAPI CM_Request_Eject_PC_Ex(
2315 HMACHINE hMachine)
2316 {
2317 RPC_BINDING_HANDLE BindingHandle = NULL;
2318
2319 TRACE("%lx\n", hMachine);
2320
2321 if (hMachine != NULL)
2322 {
2323 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2324 if (BindingHandle == NULL)
2325 return CR_FAILURE;
2326 }
2327 else
2328 {
2329 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2330 return CR_FAILURE;
2331 }
2332
2333 return PNP_RequestEjectPC(BindingHandle);
2334 }
2335
2336
2337 /***********************************************************************
2338 * CM_Run_Detection [SETUPAPI.@]
2339 */
2340 CONFIGRET WINAPI CM_Run_Detection(
2341 ULONG ulFlags)
2342 {
2343 TRACE("%lx\n", ulFlags);
2344 return CM_Run_Detection_Ex(ulFlags, NULL);
2345 }
2346
2347
2348 /***********************************************************************
2349 * CM_Run_Detection_Ex [SETUPAPI.@]
2350 */
2351 CONFIGRET WINAPI CM_Run_Detection_Ex(
2352 ULONG ulFlags, HMACHINE hMachine)
2353 {
2354 RPC_BINDING_HANDLE BindingHandle = NULL;
2355
2356 TRACE("%lx %lx\n", ulFlags, hMachine);
2357
2358 if (!IsUserAdmin())
2359 return CR_ACCESS_DENIED;
2360
2361 if (ulFlags & ~CM_DETECT_BITS)
2362 return CR_INVALID_FLAG;
2363
2364 if (hMachine != NULL)
2365 {
2366 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2367 if (BindingHandle == NULL)
2368 return CR_FAILURE;
2369 }
2370 else
2371 {
2372 if (!PnpGetLocalHandles(&BindingHandle, NULL))
2373 return CR_FAILURE;
2374 }
2375
2376 return PNP_RunDetection(BindingHandle,
2377 ulFlags);
2378 }
2379
2380
2381 /***********************************************************************
2382 * CM_Set_DevNode_Problem [SETUPAPI.@]
2383 */
2384 CONFIGRET WINAPI CM_Set_DevNode_Problem(
2385 DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags)
2386 {
2387 TRACE("%lx %lx %lx\n", dnDevInst, ulProblem, ulFlags);
2388 return CM_Set_DevNode_Problem_Ex(dnDevInst, ulProblem, ulFlags, NULL);
2389 }
2390
2391
2392 /***********************************************************************
2393 * CM_Set_DevNode_Problem_Ex [SETUPAPI.@]
2394 */
2395 CONFIGRET WINAPI CM_Set_DevNode_Problem_Ex(
2396 DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags, HMACHINE hMachine)
2397 {
2398 RPC_BINDING_HANDLE BindingHandle = NULL;
2399 HSTRING_TABLE StringTable = NULL;
2400 LPWSTR lpDevInst;
2401
2402 TRACE("%lx %lx %lx %lx\n", dnDevInst, ulProblem, ulFlags, hMachine);
2403
2404 if (dnDevInst == 0)
2405 return CR_INVALID_DEVNODE;
2406
2407 if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
2408 return CR_INVALID_FLAG;
2409
2410 if (hMachine != NULL)
2411 {
2412 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2413 if (BindingHandle == NULL)
2414 return CR_FAILURE;
2415
2416 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2417 if (StringTable == 0)
2418 return CR_FAILURE;
2419 }
2420 else
2421 {
2422 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2423 return CR_FAILURE;
2424 }
2425
2426 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2427 if (lpDevInst == NULL)
2428 return CR_INVALID_DEVNODE;
2429
2430 return PNP_SetDeviceProblem(BindingHandle,
2431 lpDevInst,
2432 ulProblem,
2433 ulFlags);
2434 }
2435
2436
2437 /***********************************************************************
2438 * CM_Set_DevNode_Registry_PropertyA [SETUPAPI.@]
2439 */
2440 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyA(
2441 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
2442 ULONG ulFlags)
2443 {
2444 TRACE("%lx %lu %p %lx %lx\n",
2445 dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
2446 return CM_Set_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
2447 Buffer, ulLength,
2448 ulFlags, NULL);
2449 }
2450
2451
2452 /***********************************************************************
2453 * CM_Set_DevNode_Registry_PropertyW [SETUPAPI.@]
2454 */
2455 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyW(
2456 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
2457 ULONG ulFlags)
2458 {
2459 TRACE("%lx %lu %p %lx %lx\n",
2460 dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
2461 return CM_Set_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
2462 Buffer, ulLength,
2463 ulFlags, NULL);
2464 }
2465
2466
2467 /***********************************************************************
2468 * CM_Set_DevNode_Registry_Property_ExA [SETUPAPI.@]
2469 */
2470 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExA(
2471 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
2472 ULONG ulFlags, HMACHINE hMachine)
2473 {
2474 CONFIGRET ret = CR_SUCCESS;
2475 LPWSTR lpBuffer;
2476 ULONG ulType;
2477
2478 FIXME("%lx %lu %p %lx %lx %lx\n",
2479 dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
2480
2481 if (Buffer == NULL && ulLength != 0)
2482 return CR_INVALID_POINTER;
2483
2484 if (Buffer == NULL)
2485 {
2486 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
2487 ulProperty,
2488 NULL,
2489 0,
2490 ulFlags,
2491 hMachine);
2492 }
2493 else
2494 {
2495 /* Get property type */
2496 switch (ulProperty)
2497 {
2498 case CM_DRP_DEVICEDESC:
2499 ulType = REG_SZ;
2500 break;
2501
2502 case CM_DRP_HARDWAREID:
2503 ulType = REG_MULTI_SZ;
2504 break;
2505
2506 case CM_DRP_COMPATIBLEIDS:
2507 ulType = REG_MULTI_SZ;
2508 break;
2509
2510 case CM_DRP_SERVICE:
2511 ulType = REG_SZ;
2512 break;
2513
2514 case CM_DRP_CLASS:
2515 ulType = REG_SZ;
2516 break;
2517
2518 case CM_DRP_CLASSGUID:
2519 ulType = REG_SZ;
2520 break;
2521
2522 case CM_DRP_DRIVER:
2523 ulType = REG_SZ;
2524 break;
2525
2526 case CM_DRP_CONFIGFLAGS:
2527 ulType = REG_DWORD;
2528 break;
2529
2530 case CM_DRP_MFG:
2531 ulType = REG_SZ;
2532 break;
2533
2534 case CM_DRP_FRIENDLYNAME:
2535 ulType = REG_SZ;
2536 break;
2537
2538 case CM_DRP_LOCATION_INFORMATION:
2539 ulType = REG_SZ;
2540 break;
2541
2542 case CM_DRP_UPPERFILTERS:
2543 ulType = REG_MULTI_SZ;
2544 break;
2545
2546 case CM_DRP_LOWERFILTERS:
2547 ulType = REG_MULTI_SZ;
2548 break;
2549
2550 default:
2551 return CR_INVALID_PROPERTY;
2552 }
2553
2554 /* Allocate buffer if needed */
2555 if (ulType == REG_SZ ||
2556 ulType == REG_MULTI_SZ)
2557 {
2558 lpBuffer = MyMalloc(ulLength * sizeof(WCHAR));
2559 if (lpBuffer == NULL)
2560 {
2561 ret = CR_OUT_OF_MEMORY;
2562 }
2563 else
2564 {
2565 if (!MultiByteToWideChar(CP_ACP, 0, Buffer,
2566 ulLength, lpBuffer, ulLength))
2567 {
2568 MyFree(lpBuffer);
2569 ret = CR_FAILURE;
2570 }
2571 else
2572 {
2573 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
2574 ulProperty,
2575 lpBuffer,
2576 ulLength * sizeof(WCHAR),
2577 ulFlags,
2578 hMachine);
2579 MyFree(lpBuffer);
2580 }
2581 }
2582 }
2583 else
2584 {
2585 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
2586 ulProperty,
2587 Buffer,
2588 ulLength,
2589 ulFlags,
2590 hMachine);
2591 }
2592
2593 ret = CR_CALL_NOT_IMPLEMENTED;
2594 }
2595
2596 return ret;
2597 }
2598
2599
2600 /***********************************************************************
2601 * CM_Set_DevNode_Registry_Property_ExW [SETUPAPI.@]
2602 */
2603 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExW(
2604 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
2605 ULONG ulFlags, HMACHINE hMachine)
2606 {
2607 RPC_BINDING_HANDLE BindingHandle = NULL;
2608 HSTRING_TABLE StringTable = NULL;
2609 LPWSTR lpDevInst;
2610 ULONG ulType;
2611
2612 TRACE("%lx %lu %p %lx %lx %lx\n",
2613 dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
2614
2615 if (dnDevInst == 0)
2616 return CR_INVALID_DEVNODE;
2617
2618 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
2619 return CR_INVALID_PROPERTY;
2620
2621 if (Buffer != NULL && ulLength == 0)
2622 return CR_INVALID_POINTER;
2623
2624 if (ulFlags != 0)
2625 return CR_INVALID_FLAG;
2626
2627 if (hMachine != NULL)
2628 {
2629 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2630 if (BindingHandle == NULL)
2631 return CR_FAILURE;
2632
2633 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2634 if (StringTable == 0)
2635 return CR_FAILURE;
2636 }
2637 else
2638 {
2639 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2640 return CR_FAILURE;
2641 }
2642
2643 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2644 if (lpDevInst == NULL)
2645 return CR_INVALID_DEVNODE;
2646
2647 switch (ulProperty)
2648 {
2649 case CM_DRP_DEVICEDESC:
2650 ulType = REG_SZ;
2651 break;
2652
2653 case CM_DRP_HARDWAREID:
2654 ulType = REG_MULTI_SZ;
2655 break;
2656
2657 case CM_DRP_COMPATIBLEIDS:
2658 ulType = REG_MULTI_SZ;
2659 break;
2660
2661 case CM_DRP_SERVICE:
2662 ulType = REG_SZ;
2663 break;
2664
2665 case CM_DRP_CLASS:
2666 ulType = REG_SZ;
2667 break;
2668
2669 case CM_DRP_CLASSGUID:
2670 ulType = REG_SZ;
2671 break;
2672
2673 case CM_DRP_DRIVER:
2674 ulType = REG_SZ;
2675 break;
2676
2677 case CM_DRP_CONFIGFLAGS:
2678 ulType = REG_DWORD;
2679 break;
2680
2681 case CM_DRP_MFG:
2682 ulType = REG_SZ;
2683 break;
2684
2685 case CM_DRP_FRIENDLYNAME:
2686 ulType = REG_SZ;
2687 break;
2688
2689 case CM_DRP_LOCATION_INFORMATION:
2690 ulType = REG_SZ;
2691 break;
2692
2693 case CM_DRP_UPPERFILTERS:
2694 ulType = REG_MULTI_SZ;
2695 break;
2696
2697 case CM_DRP_LOWERFILTERS:
2698 ulType = REG_MULTI_SZ;
2699 break;
2700
2701 default:
2702 return CR_INVALID_PROPERTY;
2703 }
2704
2705 return PNP_SetDeviceRegProp(BindingHandle,
2706 lpDevInst,
2707 ulProperty,
2708 ulType,
2709 (char *)Buffer,
2710 ulLength,
2711 ulFlags);
2712 }
2713
2714
2715 /***********************************************************************
2716 * CM_Setup_DevNode [SETUPAPI.@]
2717 */
2718 CONFIGRET WINAPI CM_Setup_DevNode(
2719 DEVINST dnDevInst, ULONG ulFlags)
2720 {
2721 TRACE("%lx %lx\n", dnDevInst, ulFlags);
2722 return CM_Setup_DevNode_Ex(dnDevInst, ulFlags, NULL);
2723 }
2724
2725
2726 /***********************************************************************
2727 * CM_Setup_DevNode_Ex [SETUPAPI.@]
2728 */
2729 CONFIGRET WINAPI CM_Setup_DevNode_Ex(
2730 DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
2731 {
2732 RPC_BINDING_HANDLE BindingHandle = NULL;
2733 HSTRING_TABLE StringTable = NULL;
2734 LPWSTR lpDevInst;
2735
2736 FIXME("%lx %lx %lx\n", dnDevInst, ulFlags, hMachine);
2737
2738 if (!IsUserAdmin())
2739 return CR_ACCESS_DENIED;
2740
2741 if (dnDevInst == 0)
2742 return CR_INVALID_DEVNODE;
2743
2744 if (ulFlags & ~CM_SETUP_BITS)
2745 return CR_INVALID_FLAG;
2746
2747 if (hMachine != NULL)
2748 {
2749 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2750 if (BindingHandle == NULL)
2751 return CR_FAILURE;
2752
2753 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2754 if (StringTable == 0)
2755 return CR_FAILURE;
2756 }
2757 else
2758 {
2759 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2760 return CR_FAILURE;
2761 }
2762
2763 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2764 if (lpDevInst == NULL)
2765 return CR_INVALID_DEVNODE;
2766
2767 return PNP_DeviceInstanceAction(BindingHandle,
2768 3,
2769 ulFlags,
2770 lpDevInst,
2771 NULL);
2772 }
2773
2774
2775 /***********************************************************************
2776 * CM_Uninstall_DevNode [SETUPAPI.@]
2777 */
2778 CONFIGRET WINAPI CM_Uninstall_DevNode(
2779 DEVINST dnPhantom, ULONG ulFlags)
2780 {
2781 TRACE("%lx %lx\n", dnPhantom, ulFlags);
2782 return CM_Uninstall_DevNode_Ex(dnPhantom, ulFlags, NULL);
2783 }
2784
2785
2786 /***********************************************************************
2787 * CM_Uninstall_DevNode_Ex [SETUPAPI.@]
2788 */
2789 CONFIGRET WINAPI CM_Uninstall_DevNode_Ex(
2790 DEVINST dnPhantom, ULONG ulFlags, HMACHINE hMachine)
2791 {
2792 RPC_BINDING_HANDLE BindingHandle = NULL;
2793 HSTRING_TABLE StringTable = NULL;
2794 LPWSTR lpDevInst;
2795
2796 TRACE("%lx %lx %lx\n", dnPhantom, ulFlags, hMachine);
2797
2798 if (dnPhantom == 0)
2799 return CR_INVALID_DEVNODE;
2800
2801 if (ulFlags != 0)
2802 return CR_INVALID_FLAG;
2803
2804 if (hMachine != NULL)
2805 {
2806 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2807 if (BindingHandle == NULL)
2808 return CR_FAILURE;
2809
2810 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2811 if (StringTable == 0)
2812 return CR_FAILURE;
2813 }
2814 else
2815 {
2816 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2817 return CR_FAILURE;
2818 }
2819
2820 lpDevInst = StringTableStringFromId(StringTable, dnPhantom);
2821 if (lpDevInst == NULL)
2822 return CR_INVALID_DEVNODE;
2823
2824 return PNP_UninstallDevInst(BindingHandle,
2825 lpDevInst,
2826 ulFlags);
2827 }