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