- Implement CM_Enumerate_Enumerators[_Ex]A/W
[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 <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "winuser.h"
28 #include "winnls.h"
29 #include "winreg.h"
30 #include "setupapi.h"
31 #include "cfgmgr32.h"
32 #include "setupapi_private.h"
33
34 #include "rpc.h"
35 #include "rpc_private.h"
36
37 #include "pnp_c.h"
38
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
42
43 /* Registry key and value names */
44 static const WCHAR Backslash[] = {'\\', 0};
45 static const WCHAR Class[] = {'C','l','a','s','s',0};
46
47 static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
48 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
49 'C','o','n','t','r','o','l','\\',
50 'C','l','a','s','s',0};
51
52 static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
53 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
54 'C','o','n','t','r','o','l','\\',
55 'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
56
57 typedef struct _MACHINE_INFO
58 {
59 WCHAR szMachineName[MAX_PATH];
60 RPC_BINDING_HANDLE BindingHandle;
61 HSTRING_TABLE StringTable;
62 } MACHINE_INFO, *PMACHINE_INFO;
63
64
65 static BOOL GuidToString(LPGUID Guid, LPWSTR String)
66 {
67 LPWSTR lpString;
68
69 if (UuidToStringW(Guid, &lpString) != RPC_S_OK)
70 return FALSE;
71
72 lstrcpyW(&String[1], lpString);
73
74 String[0] = L'{';
75 String[MAX_GUID_STRING_LEN - 2] = L'}';
76 String[MAX_GUID_STRING_LEN - 1] = 0;
77
78 RpcStringFree(&lpString);
79
80 return TRUE;
81 }
82
83
84 /***********************************************************************
85 * CM_Connect_MachineA [SETUPAPI.@]
86 */
87 CONFIGRET WINAPI CM_Connect_MachineA(PCSTR UNCServerName, PHMACHINE phMachine)
88 {
89 PWSTR pServerNameW;
90 CONFIGRET ret;
91
92 TRACE("%s %p\n", UNCServerName, phMachine);
93
94 if (UNCServerName == NULL || *UNCServerName == 0)
95 return CM_Connect_MachineW(NULL, phMachine);
96
97 if (CaptureAndConvertAnsiArg(UNCServerName, &pServerNameW))
98 return CR_INVALID_DATA;
99
100 ret = CM_Connect_MachineW(pServerNameW, phMachine);
101
102 MyFree(pServerNameW);
103
104 return ret;
105 }
106
107
108 /***********************************************************************
109 * CM_Connect_MachineW [SETUPAPI.@]
110 */
111 CONFIGRET WINAPI CM_Connect_MachineW(PCWSTR UNCServerName, PHMACHINE phMachine)
112 {
113 PMACHINE_INFO pMachine;
114
115 TRACE("%s %p\n", debugstr_w(UNCServerName), phMachine);
116
117 pMachine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MACHINE_INFO));
118 if (pMachine == NULL)
119 return CR_OUT_OF_MEMORY;
120
121 lstrcpyW(pMachine->szMachineName, UNCServerName);
122
123 pMachine->StringTable = StringTableInitialize();
124 if (pMachine->StringTable == NULL)
125 {
126 HeapFree(GetProcessHeap(), 0, pMachine);
127 return CR_FAILURE;
128 }
129
130 StringTableAddString(pMachine->StringTable, L"PLT", 1);
131
132 if (!PnpBindRpc(UNCServerName, &pMachine->BindingHandle))
133 {
134 StringTableDestroy(pMachine->StringTable);
135 HeapFree(GetProcessHeap(), 0, pMachine);
136 return CR_INVALID_MACHINENAME;
137 }
138
139 phMachine = (PHMACHINE)pMachine;
140
141 return CR_SUCCESS;
142 }
143
144
145 /***********************************************************************
146 * CM_Delete_Class_Key [SETUPAPI.@]
147 */
148 CONFIGRET WINAPI CM_Delete_Class_Key(LPGUID ClassGuid, ULONG ulFlags)
149 {
150 TRACE("%p %lx\n", ClassGuid, ulFlags);
151 return CM_Delete_Class_Key_Ex(ClassGuid, ulFlags, NULL);
152 }
153
154
155 /***********************************************************************
156 * CM_Delete_Class_Key_Ex [SETUPAPI.@]
157 */
158 CONFIGRET WINAPI CM_Delete_Class_Key_Ex(
159 LPGUID ClassGuid, ULONG ulFlags, HANDLE hMachine)
160 {
161 WCHAR szGuidString[MAX_GUID_STRING_LEN];
162 RPC_BINDING_HANDLE BindingHandle = NULL;
163
164 TRACE("%p %lx %lx\n", ClassGuid, ulFlags, hMachine);
165
166 if (ClassGuid == NULL)
167 return CR_INVALID_POINTER;
168
169 if (ulFlags & ~CM_DELETE_CLASS_BITS)
170 return CR_INVALID_FLAG;
171
172 if (!GuidToString(ClassGuid, szGuidString))
173 return CR_INVALID_DATA;
174
175 if (hMachine != NULL)
176 {
177 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
178 if (BindingHandle == NULL)
179 return CR_FAILURE;
180 }
181 else
182 {
183 if (!PnpGetLocalHandles(&BindingHandle, NULL))
184 return CR_FAILURE;
185 }
186
187 return PNP_DeleteClassKey(BindingHandle,
188 szGuidString,
189 ulFlags);
190 }
191
192
193 /***********************************************************************
194 * CM_Disconnect_Machine [SETUPAPI.@]
195 */
196 CONFIGRET WINAPI CM_Disconnect_Machine(HMACHINE hMachine)
197 {
198 PMACHINE_INFO pMachine;
199
200 TRACE("%lx\n", hMachine);
201
202 pMachine = (PMACHINE_INFO)hMachine;
203 if (pMachine == NULL)
204 return CR_SUCCESS;
205
206 if (pMachine->StringTable != NULL)
207 StringTableDestroy(pMachine->StringTable);
208
209 if (!PnpUnbindRpc(pMachine->BindingHandle))
210 return CR_ACCESS_DENIED;
211
212 HeapFree(GetProcessHeap(), 0, pMachine);
213
214 return CR_SUCCESS;
215 }
216
217
218 /***********************************************************************
219 * CM_Enumerate_Classes [SETUPAPI.@]
220 */
221 CONFIGRET WINAPI CM_Enumerate_Classes(
222 ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags)
223 {
224 TRACE("%lx %p %lx\n", ulClassIndex, ClassGuid, ulFlags);
225 return CM_Enumerate_Classes_Ex(ulClassIndex, ClassGuid, ulFlags, NULL);
226 }
227
228
229 static CONFIGRET GetCmCodeFromErrorCode(DWORD ErrorCode)
230 {
231 switch (ErrorCode)
232 {
233 case ERROR_SUCCESS:
234 return CR_SUCCESS;
235
236 case ERROR_ACCESS_DENIED:
237 return CR_ACCESS_DENIED;
238
239 case ERROR_INSUFFICIENT_BUFFER:
240 return CR_BUFFER_SMALL;
241
242 case ERROR_INVALID_DATA:
243 return CR_INVALID_DATA;
244
245 case ERROR_INVALID_PARAMETER:
246 return CR_INVALID_DATA;
247
248 case ERROR_NO_MORE_ITEMS:
249 return CR_NO_SUCH_VALUE;
250
251 case ERROR_NO_SYSTEM_RESOURCES:
252 return CR_OUT_OF_MEMORY;
253
254 default:
255 return CR_FAILURE;
256 }
257 }
258
259
260 /***********************************************************************
261 * CM_Enumerate_Classes_Ex [SETUPAPI.@]
262 */
263 CONFIGRET WINAPI CM_Enumerate_Classes_Ex(
264 ULONG ulClassIndex, LPGUID ClassGuid, ULONG ulFlags, HMACHINE hMachine)
265 {
266 HKEY hRelativeKey, hKey;
267 DWORD rc;
268 WCHAR Buffer[MAX_GUID_STRING_LEN];
269
270 TRACE("%lx %p %lx %p\n", ulClassIndex, ClassGuid, ulFlags, hMachine);
271
272 if (ClassGuid == NULL)
273 return CR_INVALID_POINTER;
274
275 if (ulFlags != 0)
276 return CR_INVALID_FLAG;
277
278 if (hMachine != NULL)
279 {
280 FIXME("hMachine argument ignored\n");
281 hRelativeKey = HKEY_LOCAL_MACHINE; /* FIXME: use here a field in hMachine */
282 }
283 else
284 hRelativeKey = HKEY_LOCAL_MACHINE;
285
286 rc = RegOpenKeyExW(
287 hRelativeKey,
288 ControlClass,
289 0, /* options */
290 KEY_ENUMERATE_SUB_KEYS,
291 &hKey);
292 if (rc != ERROR_SUCCESS)
293 return GetCmCodeFromErrorCode(rc);
294
295 rc = RegEnumKeyW(
296 hKey,
297 ulClassIndex,
298 Buffer,
299 sizeof(Buffer) / sizeof(WCHAR));
300
301 RegCloseKey(hKey);
302
303 if (rc == ERROR_SUCCESS)
304 {
305 /* Remove the {} */
306 Buffer[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
307 /* Convert the buffer to a GUID */
308 if (UuidFromStringW(&Buffer[1], ClassGuid) != RPC_S_OK)
309 return CR_FAILURE;
310 }
311
312 return GetCmCodeFromErrorCode(rc);
313 }
314
315
316 /***********************************************************************
317 * CM_Enumerate_EnumeratorsA [SETUPAPI.@]
318 */
319 CONFIGRET WINAPI CM_Enumerate_EnumeratorsA(
320 ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
321 {
322 TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
323 return CM_Enumerate_Enumerators_ExA(ulEnumIndex, Buffer, pulLength,
324 ulFlags, NULL);
325 }
326
327
328 /***********************************************************************
329 * CM_Enumerate_EnumeratorsW [SETUPAPI.@]
330 */
331 CONFIGRET WINAPI CM_Enumerate_EnumeratorsW(
332 ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
333 {
334 TRACE("%lu %p %p %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags);
335 return CM_Enumerate_Enumerators_ExW(ulEnumIndex, Buffer, pulLength,
336 ulFlags, NULL);
337 }
338
339
340 /***********************************************************************
341 * CM_Enumerate_Enumerators_ExA [SETUPAPI.@]
342 */
343 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExA(
344 ULONG ulEnumIndex, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
345 HMACHINE hMachine)
346 {
347 FIXME("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
348 hMachine);
349 return CR_CALL_NOT_IMPLEMENTED;
350 }
351
352
353 /***********************************************************************
354 * CM_Enumerate_Enumerators_ExW [SETUPAPI.@]
355 */
356 CONFIGRET WINAPI CM_Enumerate_Enumerators_ExW(
357 ULONG ulEnumIndex, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
358 HMACHINE hMachine)
359 {
360 RPC_BINDING_HANDLE BindingHandle = NULL;
361
362 FIXME("%lu %p %p %lx %lx\n", ulEnumIndex, Buffer, pulLength, ulFlags,
363 hMachine);
364
365 if (Buffer == NULL || pulLength == NULL)
366 return CR_INVALID_POINTER;
367
368 if (ulFlags != 0)
369 return CR_INVALID_FLAG;
370
371 Buffer[0] = (WCHAR)0;
372
373 if (hMachine != NULL)
374 {
375 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
376 if (BindingHandle == NULL)
377 return CR_FAILURE;
378 }
379 else
380 {
381 if (!PnpGetLocalHandles(&BindingHandle, NULL))
382 return CR_FAILURE;
383 }
384
385 return PNP_EnumerateSubKeys(BindingHandle,
386 PNP_BRANCH_ENUM,
387 ulEnumIndex,
388 Buffer,
389 *pulLength,
390 pulLength,
391 ulFlags);
392 }
393
394
395 /***********************************************************************
396 * CM_Get_Child [SETUPAPI.@]
397 */
398 CONFIGRET WINAPI CM_Get_Child(
399 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
400 {
401 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
402 return CM_Get_Child_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
403 }
404
405
406 /***********************************************************************
407 * CM_Get_Child_Ex [SETUPAPI.@]
408 */
409 CONFIGRET WINAPI CM_Get_Child_Ex(
410 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
411 {
412 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
413 RPC_BINDING_HANDLE BindingHandle = NULL;
414 HSTRING_TABLE StringTable = NULL;
415 LPWSTR lpDevInst;
416 DWORD dwIndex;
417 CONFIGRET ret;
418
419 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
420
421 if (pdnDevInst == NULL)
422 return CR_INVALID_POINTER;
423
424 if (dnDevInst == 0)
425 return CR_INVALID_DEVINST;
426
427 if (ulFlags != 0)
428 return CR_INVALID_FLAG;
429
430 *pdnDevInst = -1;
431
432 if (hMachine != NULL)
433 {
434 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
435 if (BindingHandle == NULL)
436 return CR_FAILURE;
437
438 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
439 if (StringTable == 0)
440 return CR_FAILURE;
441 }
442 else
443 {
444 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
445 return CR_FAILURE;
446 }
447
448 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
449 if (lpDevInst == NULL)
450 return CR_INVALID_DEVNODE;
451
452 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
453 PNP_DEVICE_CHILD,
454 lpDevInst,
455 szRelatedDevInst,
456 MAX_DEVICE_ID_LEN,
457 0);
458 if (ret != CR_SUCCESS)
459 return ret;
460
461 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
462
463 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
464 if (dwIndex == -1)
465 return CR_FAILURE;
466
467 *pdnDevInst = dwIndex;
468
469 return CR_SUCCESS;
470 }
471
472
473 /***********************************************************************
474 * CM_Get_Class_Key_NameA [SETUPAPI.@]
475 */
476 CONFIGRET WINAPI CM_Get_Class_Key_NameA(
477 LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
478 {
479 TRACE("%p %p %p %lx\n",
480 ClassGuid, pszKeyName, pulLength, ulFlags);
481 return CM_Get_Class_Key_Name_ExA(ClassGuid, pszKeyName, pulLength,
482 ulFlags, NULL);
483 }
484
485
486 /***********************************************************************
487 * CM_Get_Class_Key_NameW [SETUPAPI.@]
488 */
489 CONFIGRET WINAPI CM_Get_Class_Key_NameW(
490 LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags)
491 {
492 TRACE("%p %p %p %lx\n",
493 ClassGuid, pszKeyName, pulLength, ulFlags);
494 return CM_Get_Class_Key_Name_ExW(ClassGuid, pszKeyName, pulLength,
495 ulFlags, NULL);
496 }
497
498
499 /***********************************************************************
500 * CM_Get_Class_Key_Name_ExA [SETUPAPI.@]
501 */
502 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExA(
503 LPGUID ClassGuid, LPSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
504 HMACHINE hMachine)
505 {
506 WCHAR szBuffer[MAX_GUID_STRING_LEN];
507 CONFIGRET ret = CR_SUCCESS;
508 ULONG ulLength;
509 ULONG ulOrigLength;
510
511 TRACE("%p %p %p %lx %lx\n",
512 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
513
514 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
515 return CR_INVALID_POINTER;
516
517 ulOrigLength = *pulLength;
518 *pulLength = 0;
519
520 ulLength = MAX_GUID_STRING_LEN;
521 ret = CM_Get_Class_Key_Name_ExW(ClassGuid, szBuffer, &ulLength,
522 ulFlags, hMachine);
523 if (ret == CR_SUCCESS)
524 {
525 if (WideCharToMultiByte(CP_ACP,
526 0,
527 szBuffer,
528 ulLength,
529 pszKeyName,
530 ulOrigLength,
531 NULL,
532 NULL) == 0)
533 ret = CR_FAILURE;
534 else
535 *pulLength = lstrlenA(pszKeyName) + 1;
536 }
537
538 return CR_SUCCESS;
539 }
540
541
542 /***********************************************************************
543 * CM_Get_Class_Key_Name_ExW [SETUPAPI.@]
544 */
545 CONFIGRET WINAPI CM_Get_Class_Key_Name_ExW(
546 LPGUID ClassGuid, LPWSTR pszKeyName, PULONG pulLength, ULONG ulFlags,
547 HMACHINE hMachine)
548 {
549 TRACE("%p %p %p %lx %lx\n",
550 ClassGuid, pszKeyName, pulLength, ulFlags, hMachine);
551
552 if (ClassGuid == NULL || pszKeyName == NULL || pulLength == NULL)
553 return CR_INVALID_POINTER;
554
555 if (ulFlags != 0)
556 return CR_INVALID_FLAG;
557
558 if (*pulLength < MAX_GUID_STRING_LEN)
559 {
560 *pulLength = 0;
561 return CR_BUFFER_SMALL;
562 }
563
564 if (!GuidToString(ClassGuid, pszKeyName))
565 return CR_INVALID_DATA;
566
567 *pulLength = MAX_GUID_STRING_LEN;
568
569 return CR_SUCCESS;
570 }
571
572
573 /***********************************************************************
574 * CM_Get_Class_NameA [SETUPAPI.@]
575 */
576 CONFIGRET WINAPI CM_Get_Class_NameA(
577 LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags)
578 {
579 TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
580 return CM_Get_Class_Name_ExA(ClassGuid, Buffer, pulLength, ulFlags,
581 NULL);
582 }
583
584
585 /***********************************************************************
586 * CM_Get_Class_NameW [SETUPAPI.@]
587 */
588 CONFIGRET WINAPI CM_Get_Class_NameW(
589 LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags)
590 {
591 TRACE("%p %p %p %lx\n", ClassGuid, Buffer, pulLength, ulFlags);
592 return CM_Get_Class_Name_ExW(ClassGuid, Buffer, pulLength, ulFlags,
593 NULL);
594 }
595
596
597 /***********************************************************************
598 * CM_Get_Class_Name_ExA [SETUPAPI.@]
599 */
600 CONFIGRET WINAPI CM_Get_Class_Name_ExA(
601 LPGUID ClassGuid, PCHAR Buffer, PULONG pulLength, ULONG ulFlags,
602 HMACHINE hMachine)
603 {
604 WCHAR szBuffer[MAX_CLASS_NAME_LEN];
605 CONFIGRET ret = CR_SUCCESS;
606 ULONG ulLength;
607 ULONG ulOrigLength;
608
609 TRACE("%p %p %p %lx %lx\n",
610 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
611
612 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
613 return CR_INVALID_POINTER;
614
615 ulOrigLength = *pulLength;
616 *pulLength = 0;
617
618 ulLength = MAX_CLASS_NAME_LEN;
619 ret = CM_Get_Class_Name_ExW(ClassGuid, szBuffer, &ulLength,
620 ulFlags, hMachine);
621 if (ret == CR_SUCCESS)
622 {
623 if (WideCharToMultiByte(CP_ACP,
624 0,
625 szBuffer,
626 ulLength,
627 Buffer,
628 ulOrigLength,
629 NULL,
630 NULL) == 0)
631 ret = CR_FAILURE;
632 else
633 *pulLength = lstrlenA(Buffer) + 1;
634 }
635
636 return ret;
637 }
638
639
640 /***********************************************************************
641 * CM_Get_Class_Name_ExW [SETUPAPI.@]
642 */
643 CONFIGRET WINAPI
644 CM_Get_Class_Name_ExW(
645 LPGUID ClassGuid, PWCHAR Buffer, PULONG pulLength, ULONG ulFlags,
646 HMACHINE hMachine)
647 {
648 WCHAR szGuidString[MAX_GUID_STRING_LEN];
649 RPC_BINDING_HANDLE BindingHandle = NULL;
650
651 TRACE("%p %p %p %lx %lx\n",
652 ClassGuid, Buffer, pulLength, ulFlags, hMachine);
653
654 if (ClassGuid == NULL || Buffer == NULL || pulLength == NULL)
655 return CR_INVALID_POINTER;
656
657 if (ulFlags != 0)
658 return CR_INVALID_FLAG;
659
660 if (!GuidToString(ClassGuid, szGuidString))
661 return CR_INVALID_DATA;
662
663 TRACE("Guid %s\n", debugstr_w(szGuidString));
664
665 if (hMachine != NULL)
666 {
667 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
668 if (BindingHandle == NULL)
669 return CR_FAILURE;
670 }
671 else
672 {
673 if (!PnpGetLocalHandles(&BindingHandle, NULL))
674 return CR_FAILURE;
675 }
676
677 return PNP_GetClassName(BindingHandle,
678 szGuidString,
679 Buffer,
680 pulLength,
681 ulFlags);
682 }
683
684
685 /***********************************************************************
686 * CM_Get_Depth [SETUPAPI.@]
687 */
688 CONFIGRET WINAPI CM_Get_Depth(
689 PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags)
690 {
691 TRACE("%p %lx %lx\n", pulDepth, dnDevInst, ulFlags);
692 return CM_Get_Depth_Ex(pulDepth, dnDevInst, ulFlags, NULL);
693 }
694
695
696 /***********************************************************************
697 * CM_Get_Depth_Ex [SETUPAPI.@]
698 */
699 CONFIGRET WINAPI CM_Get_Depth_Ex(
700 PULONG pulDepth, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
701 {
702 RPC_BINDING_HANDLE BindingHandle = NULL;
703 HSTRING_TABLE StringTable = NULL;
704 LPWSTR lpDevInst;
705
706 TRACE("%p %lx %lx %lx\n",
707 pulDepth, dnDevInst, ulFlags, hMachine);
708
709 if (pulDepth == NULL)
710 return CR_INVALID_POINTER;
711
712 if (dnDevInst == 0)
713 return CR_INVALID_DEVINST;
714
715 if (ulFlags != 0)
716 return CR_INVALID_FLAG;
717
718 if (hMachine != NULL)
719 {
720 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
721 if (BindingHandle == NULL)
722 return CR_FAILURE;
723
724 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
725 if (StringTable == 0)
726 return CR_FAILURE;
727 }
728 else
729 {
730 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
731 return CR_FAILURE;
732 }
733
734 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
735 if (lpDevInst == NULL)
736 return CR_INVALID_DEVNODE;
737
738 return PNP_GetDepth(BindingHandle,
739 lpDevInst,
740 pulDepth,
741 ulFlags);
742 }
743
744
745 /***********************************************************************
746 * CM_Get_DevNode_Registry_PropertyA [SETUPAPI.@]
747 */
748 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyA(
749 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
750 PVOID Buffer, PULONG pulLength, ULONG ulFlags)
751 {
752 TRACE("%lx %lu %p %p %p %lx\n",
753 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
754
755 return CM_Get_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
756 pulRegDataType, Buffer,
757 pulLength, ulFlags, NULL);
758 }
759
760
761 /***********************************************************************
762 * CM_Get_DevNode_Registry_PropertyW [SETUPAPI.@]
763 */
764 CONFIGRET WINAPI CM_Get_DevNode_Registry_PropertyW(
765 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
766 PVOID Buffer, PULONG pulLength, ULONG ulFlags)
767 {
768 TRACE("%lx %lu %p %p %p %lx\n",
769 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
770
771 return CM_Get_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
772 pulRegDataType, Buffer,
773 pulLength, ulFlags, NULL);
774 }
775
776
777 /***********************************************************************
778 * CM_Get_DevNode_Registry_Property_ExA [SETUPAPI.@]
779 */
780 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExA(
781 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
782 PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
783 {
784 FIXME("%lx %lu %p %p %p %lx %lx\n",
785 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
786 ulFlags, hMachine);
787
788 return CR_CALL_NOT_IMPLEMENTED;
789 }
790
791
792 /***********************************************************************
793 * CM_Get_DevNode_Registry_Property_ExW [SETUPAPI.@]
794 */
795 CONFIGRET WINAPI CM_Get_DevNode_Registry_Property_ExW(
796 DEVINST dnDevInst, ULONG ulProperty, PULONG pulRegDataType,
797 PVOID Buffer, PULONG pulLength, ULONG ulFlags, HMACHINE hMachine)
798 {
799 RPC_BINDING_HANDLE BindingHandle = NULL;
800 HSTRING_TABLE StringTable = NULL;
801 CONFIGRET ret = CR_SUCCESS;
802 LPWSTR lpDevInst;
803 ULONG ulDataType = 0;
804 ULONG ulTransferLength = 0;
805
806 FIXME("%lx %lu %p %p %p %lx %lx\n",
807 dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength,
808 ulFlags, hMachine);
809
810 if (dnDevInst == 0)
811 return CR_INVALID_DEVNODE;
812
813 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
814 return CR_INVALID_PROPERTY;
815
816 /* pulRegDataType is optional */
817
818 /* Buffer is optional */
819
820 if (pulLength == NULL)
821 return CR_INVALID_POINTER;
822
823 if (*pulLength == 0)
824 return CR_INVALID_POINTER;
825
826 if (ulFlags != 0)
827 return CR_INVALID_FLAG;
828
829 if (hMachine != NULL)
830 {
831 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
832 if (BindingHandle == NULL)
833 return CR_FAILURE;
834
835 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
836 if (StringTable == 0)
837 return CR_FAILURE;
838 }
839 else
840 {
841 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
842 return CR_FAILURE;
843 }
844
845 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
846 if (lpDevInst == NULL)
847 return CR_INVALID_DEVNODE;
848
849 ulTransferLength = *pulLength;
850 ret = PNP_GetDeviceRegProp(BindingHandle,
851 lpDevInst,
852 ulProperty,
853 &ulDataType,
854 Buffer,
855 &ulTransferLength,
856 pulLength,
857 ulFlags);
858 if (ret == CR_SUCCESS)
859 {
860 if (pulRegDataType != NULL)
861 *pulRegDataType = ulDataType;
862 }
863
864 return ret;
865 }
866
867
868 /***********************************************************************
869 * CM_Get_DevNode_Status [SETUPAPI.@]
870 */
871 CONFIGRET WINAPI CM_Get_DevNode_Status(
872 PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
873 ULONG ulFlags)
874 {
875 TRACE("%p %p %lx %lx\n",
876 pulStatus, pulProblemNumber, dnDevInst, ulFlags);
877 return CM_Get_DevNode_Status_Ex(pulStatus, pulProblemNumber, dnDevInst,
878 ulFlags, NULL);
879 }
880
881
882 /***********************************************************************
883 * CM_Get_DevNode_Status_Ex [SETUPAPI.@]
884 */
885 CONFIGRET WINAPI
886 CM_Get_DevNode_Status_Ex(
887 PULONG pulStatus, PULONG pulProblemNumber, DEVINST dnDevInst,
888 ULONG ulFlags, HMACHINE hMachine)
889 {
890 RPC_BINDING_HANDLE BindingHandle = NULL;
891 HSTRING_TABLE StringTable = NULL;
892 LPWSTR lpDevInst;
893
894 TRACE("%p %p %lx %lx %lx\n",
895 pulStatus, pulProblemNumber, dnDevInst, ulFlags, hMachine);
896
897 if (pulStatus == NULL || pulProblemNumber == NULL)
898 return CR_INVALID_POINTER;
899
900 if (dnDevInst == 0)
901 return CR_INVALID_DEVINST;
902
903 if (ulFlags != 0)
904 return CR_INVALID_FLAG;
905
906 if (hMachine != NULL)
907 {
908 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
909 if (BindingHandle == NULL)
910 return CR_FAILURE;
911
912 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
913 if (StringTable == 0)
914 return CR_FAILURE;
915 }
916 else
917 {
918 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
919 return CR_FAILURE;
920 }
921
922 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
923 if (lpDevInst == NULL)
924 return CR_INVALID_DEVNODE;
925
926 return PNP_GetDeviceStatus(BindingHandle,
927 lpDevInst,
928 pulStatus,
929 pulProblemNumber,
930 ulFlags);
931 }
932
933
934 /***********************************************************************
935 * CM_Get_Device_IDA [SETUPAPI.@]
936 */
937 CONFIGRET WINAPI CM_Get_Device_IDA(
938 DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
939 {
940 TRACE("%lx %p %ld %ld\n",
941 dnDevInst, Buffer, BufferLen, ulFlags);
942 return CM_Get_Device_ID_ExA(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
943 }
944
945
946 /***********************************************************************
947 * CM_Get_Device_IDW [SETUPAPI.@]
948 */
949 CONFIGRET WINAPI CM_Get_Device_IDW(
950 DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
951 {
952 TRACE("%lx %p %ld %ld\n",
953 dnDevInst, Buffer, BufferLen, ulFlags);
954 return CM_Get_Device_ID_ExW(dnDevInst, Buffer, BufferLen, ulFlags, NULL);
955 }
956
957
958 /***********************************************************************
959 * CM_Get_Device_ID_ExA [SETUPAPI.@]
960 */
961 CONFIGRET WINAPI CM_Get_Device_ID_ExA(
962 DEVINST dnDevInst, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
963 HMACHINE hMachine)
964 {
965 WCHAR szBufferW[MAX_DEVICE_ID_LEN];
966 CONFIGRET ret = CR_SUCCESS;
967
968 FIXME("%lx %p %ld %ld %lx\n",
969 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
970
971 if (Buffer == NULL)
972 return CR_INVALID_POINTER;
973
974 ret = CM_Get_Device_ID_ExW(dnDevInst,
975 szBufferW,
976 MAX_DEVICE_ID_LEN,
977 ulFlags,
978 hMachine);
979 if (ret == CR_SUCCESS)
980 {
981 if (WideCharToMultiByte(CP_ACP,
982 0,
983 szBufferW,
984 lstrlenW(szBufferW) + 1,
985 Buffer,
986 BufferLen,
987 NULL,
988 NULL) == 0)
989 ret = CR_FAILURE;
990 }
991
992 return ret;
993 }
994
995
996 /***********************************************************************
997 * CM_Get_Device_ID_ExW [SETUPAPI.@]
998 */
999 CONFIGRET WINAPI CM_Get_Device_ID_ExW(
1000 DEVINST dnDevInst, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1001 HMACHINE hMachine)
1002 {
1003 HSTRING_TABLE StringTable = NULL;
1004
1005 TRACE("%lx %p %ld %ld %lx\n",
1006 dnDevInst, Buffer, BufferLen, ulFlags, hMachine);
1007
1008 if (dnDevInst == 0)
1009 return CR_INVALID_DEVINST;
1010
1011 if (Buffer == NULL)
1012 return CR_INVALID_POINTER;
1013
1014 if (ulFlags != 0)
1015 return CR_INVALID_FLAG;
1016
1017 if (hMachine != NULL)
1018 {
1019 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1020 if (StringTable == NULL)
1021 return CR_FAILURE;
1022 }
1023 else
1024 {
1025 if (!PnpGetLocalHandles(NULL, &StringTable))
1026 return CR_FAILURE;
1027 }
1028
1029 if (!StringTableStringFromIdEx(StringTable,
1030 dnDevInst,
1031 Buffer,
1032 &BufferLen))
1033 return CR_FAILURE;
1034
1035 return CR_SUCCESS;
1036 }
1037
1038
1039 /***********************************************************************
1040 * CM_Get_Device_ID_ListA [SETUPAPI.@]
1041 */
1042 CONFIGRET WINAPI CM_Get_Device_ID_ListA(
1043 PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1044 {
1045 TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
1046 return CM_Get_Device_ID_List_ExA(pszFilter, Buffer, BufferLen,
1047 ulFlags, NULL);
1048 }
1049
1050
1051 /***********************************************************************
1052 * CM_Get_Device_ID_ListW [SETUPAPI.@]
1053 */
1054 CONFIGRET WINAPI CM_Get_Device_ID_ListW(
1055 PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags)
1056 {
1057 TRACE("%p %p %ld %ld\n", pszFilter, Buffer, BufferLen, ulFlags);
1058 return CM_Get_Device_ID_List_ExW(pszFilter, Buffer, BufferLen,
1059 ulFlags, NULL);
1060 }
1061
1062
1063 /***********************************************************************
1064 * CM_Get_Device_ID_List_ExA [SETUPAPI.@]
1065 */
1066 CONFIGRET WINAPI CM_Get_Device_ID_List_ExA(
1067 PCSTR pszFilter, PCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1068 HMACHINE hMachine)
1069 {
1070 LPWSTR BufferW = NULL;
1071 LPWSTR pszFilterW = NULL;
1072 CONFIGRET ret = CR_SUCCESS;
1073
1074 FIXME("%p %p %ld %ld %lx\n",
1075 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
1076
1077 BufferW = MyMalloc(BufferLen * sizeof(WCHAR));
1078 if (BufferW == NULL)
1079 return CR_OUT_OF_MEMORY;
1080
1081 if (pszFilter == NULL)
1082 {
1083 ret = CM_Get_Device_ID_List_ExW(NULL,
1084 BufferW,
1085 BufferLen,
1086 ulFlags,
1087 hMachine);
1088 }
1089 else
1090 {
1091 if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
1092 {
1093 ret = CR_INVALID_DEVICE_ID;
1094 goto Done;
1095 }
1096
1097 ret = CM_Get_Device_ID_List_ExW(pszFilterW,
1098 BufferW,
1099 BufferLen,
1100 ulFlags,
1101 hMachine);
1102
1103 MyFree(pszFilterW);
1104 }
1105
1106 if (WideCharToMultiByte(CP_ACP,
1107 0,
1108 BufferW,
1109 lstrlenW(BufferW) + 1,
1110 Buffer,
1111 BufferLen,
1112 NULL,
1113 NULL) == 0)
1114 ret = CR_FAILURE;
1115
1116 Done:
1117 MyFree(BufferW);
1118
1119 return ret;
1120 }
1121
1122
1123 /***********************************************************************
1124 * CM_Get_Device_ID_List_ExW [SETUPAPI.@]
1125 */
1126 CONFIGRET WINAPI CM_Get_Device_ID_List_ExW(
1127 PCWSTR pszFilter, PWCHAR Buffer, ULONG BufferLen, ULONG ulFlags,
1128 HMACHINE hMachine)
1129 {
1130 FIXME("%p %p %ld %ld %lx\n",
1131 pszFilter, Buffer, BufferLen, ulFlags, hMachine);
1132 memset(Buffer,0,2);
1133 return CR_SUCCESS;
1134 }
1135
1136
1137 /***********************************************************************
1138 * CM_Get_Device_ID_List_SizeA [SETUPAPI.@]
1139 */
1140 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeA(
1141 PULONG pulLen, PCSTR pszFilter, ULONG ulFlags)
1142 {
1143 TRACE("%p %s %ld\n", pulLen, pszFilter, ulFlags);
1144 return CM_Get_Device_ID_List_Size_ExA(pulLen, pszFilter, ulFlags, NULL);
1145 }
1146
1147
1148 /***********************************************************************
1149 * CM_Get_Device_ID_List_SizeW [SETUPAPI.@]
1150 */
1151 CONFIGRET WINAPI CM_Get_Device_ID_List_SizeW(
1152 PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags)
1153 {
1154 TRACE("%p %s %ld\n", pulLen, debugstr_w(pszFilter), ulFlags);
1155 return CM_Get_Device_ID_List_Size_ExW(pulLen, pszFilter, ulFlags, NULL);
1156 }
1157
1158
1159 /***********************************************************************
1160 * CM_Get_Device_ID_List_Size_ExA [SETUPAPI.@]
1161 */
1162 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExA(
1163 PULONG pulLen, PCSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
1164 {
1165 LPWSTR pszFilterW = NULL;
1166 CONFIGRET ret = CR_SUCCESS;
1167
1168 FIXME("%p %s %lx %lx\n", pulLen, pszFilter, ulFlags, hMachine);
1169
1170 if (pszFilter == NULL)
1171 {
1172 ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
1173 NULL,
1174 ulFlags,
1175 hMachine);
1176 }
1177 else
1178 {
1179 if (CaptureAndConvertAnsiArg(pszFilter, &pszFilterW))
1180 return CR_INVALID_DEVICE_ID;
1181
1182 ret = CM_Get_Device_ID_List_Size_ExW(pulLen,
1183 pszFilterW,
1184 ulFlags,
1185 hMachine);
1186
1187 MyFree(pszFilterW);
1188 }
1189
1190 return ret;
1191 }
1192
1193
1194 /***********************************************************************
1195 * CM_Get_Device_ID_List_Size_ExW [SETUPAPI.@]
1196 */
1197 CONFIGRET WINAPI CM_Get_Device_ID_List_Size_ExW(
1198 PULONG pulLen, PCWSTR pszFilter, ULONG ulFlags, HMACHINE hMachine)
1199 {
1200 FIXME("%p %s %ld %lx\n", pulLen, debugstr_w(pszFilter), ulFlags, hMachine);
1201 *pulLen = 2;
1202 return CR_SUCCESS;
1203 }
1204
1205
1206 /***********************************************************************
1207 * CM_Get_Device_ID_Size [SETUPAPI.@]
1208 */
1209 CONFIGRET WINAPI CM_Get_Device_ID_Size(
1210 PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags)
1211 {
1212 TRACE("%p %lx %lx\n", pulLen, dnDevInst, ulFlags);
1213 return CM_Get_Device_ID_Size_Ex(pulLen, dnDevInst, ulFlags, NULL);
1214 }
1215
1216
1217 /***********************************************************************
1218 * CM_Get_Device_ID_Size_Ex [SETUPAPI.@]
1219 */
1220 CONFIGRET WINAPI CM_Get_Device_ID_Size_Ex(
1221 PULONG pulLen, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1222 {
1223 HSTRING_TABLE StringTable = NULL;
1224 LPWSTR DeviceId;
1225
1226 TRACE("%p %lx %lx %lx\n", pulLen, dnDevInst, ulFlags, hMachine);
1227
1228 if (pulLen == NULL)
1229 return CR_INVALID_POINTER;
1230
1231 if (dnDevInst == 0)
1232 return CR_INVALID_DEVINST;
1233
1234 if (ulFlags != 0)
1235 return CR_INVALID_FLAG;
1236
1237 if (hMachine != NULL)
1238 {
1239 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1240 if (StringTable == NULL)
1241 return CR_FAILURE;
1242 }
1243 else
1244 {
1245 if (!PnpGetLocalHandles(NULL, &StringTable))
1246 return CR_FAILURE;
1247 }
1248
1249 DeviceId = StringTableStringFromId(StringTable, dnDevInst);
1250 if (DeviceId == NULL)
1251 {
1252 *pulLen = 0;
1253 return CR_SUCCESS;
1254 }
1255
1256 *pulLen = lstrlenW(DeviceId);
1257
1258 return CR_SUCCESS;
1259 }
1260
1261
1262 /***********************************************************************
1263 * CM_Get_Global_State [SETUPAPI.@]
1264 */
1265 CONFIGRET WINAPI CM_Get_Global_State(
1266 PULONG pulState, ULONG ulFlags)
1267 {
1268 TRACE("%p %lx\n", pulState, ulFlags);
1269 return CM_Get_Global_State_Ex(pulState, ulFlags, NULL);
1270 }
1271
1272
1273 /***********************************************************************
1274 * CM_Get_Global_State_Ex [SETUPAPI.@]
1275 */
1276 CONFIGRET WINAPI CM_Get_Global_State_Ex(
1277 PULONG pulState, ULONG ulFlags, HMACHINE hMachine)
1278 {
1279 RPC_BINDING_HANDLE BindingHandle = NULL;
1280
1281 TRACE("%p %lx %lx\n", pulState, ulFlags, hMachine);
1282
1283 if (pulState == NULL)
1284 return CR_INVALID_POINTER;
1285
1286 if (ulFlags != 0)
1287 return CR_INVALID_FLAG;
1288
1289 if (hMachine != NULL)
1290 {
1291 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1292 if (BindingHandle == NULL)
1293 return CR_FAILURE;
1294 }
1295 else
1296 {
1297 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1298 return CR_FAILURE;
1299 }
1300
1301 return PNP_GetGlobalState(BindingHandle, pulState, ulFlags);
1302 }
1303
1304
1305 /***********************************************************************
1306 * CM_Get_Parent [SETUPAPI.@]
1307 */
1308 CONFIGRET WINAPI CM_Get_Parent(
1309 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
1310 {
1311 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
1312 return CM_Get_Parent_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
1313 }
1314
1315
1316 /***********************************************************************
1317 * CM_Get_Parent_Ex [SETUPAPI.@]
1318 */
1319 CONFIGRET WINAPI CM_Get_Parent_Ex(
1320 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1321 {
1322 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
1323 RPC_BINDING_HANDLE BindingHandle = NULL;
1324 HSTRING_TABLE StringTable = NULL;
1325 LPWSTR lpDevInst;
1326 DWORD dwIndex;
1327 CONFIGRET ret;
1328
1329 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
1330
1331 if (pdnDevInst == NULL)
1332 return CR_INVALID_POINTER;
1333
1334 if (dnDevInst == 0)
1335 return CR_INVALID_DEVINST;
1336
1337 if (ulFlags != 0)
1338 return CR_INVALID_FLAG;
1339
1340 *pdnDevInst = -1;
1341
1342 if (hMachine != NULL)
1343 {
1344 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1345 if (BindingHandle == NULL)
1346 return CR_FAILURE;
1347
1348 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1349 if (StringTable == 0)
1350 return CR_FAILURE;
1351 }
1352 else
1353 {
1354 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1355 return CR_FAILURE;
1356 }
1357
1358 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1359 if (lpDevInst == NULL)
1360 return CR_INVALID_DEVNODE;
1361
1362 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
1363 PNP_DEVICE_PARENT,
1364 lpDevInst,
1365 szRelatedDevInst,
1366 MAX_DEVICE_ID_LEN,
1367 0);
1368 if (ret != CR_SUCCESS)
1369 return ret;
1370
1371 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
1372
1373 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
1374 if (dwIndex == -1)
1375 return CR_FAILURE;
1376
1377 *pdnDevInst = dwIndex;
1378
1379 return CR_SUCCESS;
1380 }
1381
1382
1383 /***********************************************************************
1384 * CM_Get_Sibling [SETUPAPI.@]
1385 */
1386 CONFIGRET WINAPI CM_Get_Sibling(
1387 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags)
1388 {
1389 TRACE("%p %p %lx\n", pdnDevInst, dnDevInst, ulFlags);
1390 return CM_Get_Sibling_Ex(pdnDevInst, dnDevInst, ulFlags, NULL);
1391 }
1392
1393
1394 /***********************************************************************
1395 * CM_Get_Sibling_Ex [SETUPAPI.@]
1396 */
1397 CONFIGRET WINAPI CM_Get_Sibling_Ex(
1398 PDEVINST pdnDevInst, DEVINST dnDevInst, ULONG ulFlags, HMACHINE hMachine)
1399 {
1400 WCHAR szRelatedDevInst[MAX_DEVICE_ID_LEN];
1401 RPC_BINDING_HANDLE BindingHandle = NULL;
1402 HSTRING_TABLE StringTable = NULL;
1403 LPWSTR lpDevInst;
1404 DWORD dwIndex;
1405 CONFIGRET ret;
1406
1407 TRACE("%p %lx %lx %lx\n", pdnDevInst, dnDevInst, ulFlags, hMachine);
1408
1409 if (pdnDevInst == NULL)
1410 return CR_INVALID_POINTER;
1411
1412 if (dnDevInst == 0)
1413 return CR_INVALID_DEVINST;
1414
1415 if (ulFlags != 0)
1416 return CR_INVALID_FLAG;
1417
1418 *pdnDevInst = -1;
1419
1420 if (hMachine != NULL)
1421 {
1422 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1423 if (BindingHandle == NULL)
1424 return CR_FAILURE;
1425
1426 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1427 if (StringTable == 0)
1428 return CR_FAILURE;
1429 }
1430 else
1431 {
1432 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1433 return CR_FAILURE;
1434 }
1435
1436 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1437 if (lpDevInst == NULL)
1438 return CR_INVALID_DEVNODE;
1439
1440 ret = PNP_GetRelatedDeviceInstance(BindingHandle,
1441 PNP_DEVICE_SIBLING,
1442 lpDevInst,
1443 szRelatedDevInst,
1444 MAX_DEVICE_ID_LEN,
1445 0);
1446 if (ret != CR_SUCCESS)
1447 return ret;
1448
1449 TRACE("szRelatedDevInst: %s\n", debugstr_w(szRelatedDevInst));
1450
1451 dwIndex = StringTableAddString(StringTable, szRelatedDevInst, 1);
1452 if (dwIndex == -1)
1453 return CR_FAILURE;
1454
1455 *pdnDevInst = dwIndex;
1456
1457 return CR_SUCCESS;
1458 }
1459
1460
1461 /***********************************************************************
1462 * CM_Get_Version [SETUPAPI.@]
1463 */
1464 WORD WINAPI CM_Get_Version(VOID)
1465 {
1466 TRACE("\n");
1467 return CM_Get_Version_Ex(NULL);
1468 }
1469
1470
1471 /***********************************************************************
1472 * CM_Get_Version_Ex [SETUPAPI.@]
1473 */
1474 WORD WINAPI CM_Get_Version_Ex(HMACHINE hMachine)
1475 {
1476 RPC_BINDING_HANDLE BindingHandle = NULL;
1477 WORD Version = 0;
1478
1479 TRACE("%lx\n", hMachine);
1480
1481 if (hMachine != NULL)
1482 {
1483 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1484 if (BindingHandle == NULL)
1485 return 0;
1486 }
1487 else
1488 {
1489 if (!PnpGetLocalHandles(&BindingHandle, NULL))
1490 return CR_FAILURE;
1491 }
1492
1493 if (PNP_GetVersion(BindingHandle, &Version) != CR_SUCCESS)
1494 return 0;
1495
1496 return Version;
1497 }
1498
1499
1500 /***********************************************************************
1501 * CM_Locate_DevNodeA [SETUPAPI.@]
1502 */
1503 CONFIGRET WINAPI CM_Locate_DevNodeA(
1504 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags)
1505 {
1506 TRACE("%p %s %lu\n", pdnDevInst, pDeviceID, ulFlags);
1507 return CM_Locate_DevNode_ExA(pdnDevInst, pDeviceID, ulFlags, NULL);
1508 }
1509
1510
1511 /***********************************************************************
1512 * CM_Locate_DevNodeW [SETUPAPI.@]
1513 */
1514 CONFIGRET WINAPI CM_Locate_DevNodeW(
1515 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags)
1516 {
1517 TRACE("%p %s %lu\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags);
1518 return CM_Locate_DevNode_ExW(pdnDevInst, pDeviceID, ulFlags, NULL);
1519 }
1520
1521
1522 /***********************************************************************
1523 * CM_Locate_DevNode_ExA [SETUPAPI.@]
1524 */
1525 CONFIGRET WINAPI CM_Locate_DevNode_ExA(
1526 PDEVINST pdnDevInst, DEVINSTID_A pDeviceID, ULONG ulFlags, HMACHINE hMachine)
1527 {
1528 DEVINSTID_W pDevIdW = NULL;
1529 CONFIGRET ret = CR_SUCCESS;
1530
1531 TRACE("%p %s %lu %lx\n", pdnDevInst, pDeviceID, ulFlags, hMachine);
1532
1533 if (pDeviceID != NULL)
1534 {
1535 if (CaptureAndConvertAnsiArg(pDeviceID, &pDevIdW))
1536 return CR_INVALID_DEVICE_ID;
1537 }
1538
1539 ret = CM_Locate_DevNode_ExW(pdnDevInst, pDevIdW, ulFlags, hMachine);
1540
1541 if (pDevIdW != NULL)
1542 MyFree(pDevIdW);
1543
1544 return ret;
1545 }
1546
1547
1548 /***********************************************************************
1549 * CM_Locate_DevNode_ExW [SETUPAPI.@]
1550 */
1551 CONFIGRET WINAPI CM_Locate_DevNode_ExW(
1552 PDEVINST pdnDevInst, DEVINSTID_W pDeviceID, ULONG ulFlags, HMACHINE hMachine)
1553 {
1554 WCHAR DeviceIdBuffer[MAX_DEVICE_ID_LEN];
1555 RPC_BINDING_HANDLE BindingHandle = NULL;
1556 HSTRING_TABLE StringTable = NULL;
1557 CONFIGRET ret = CR_SUCCESS;
1558
1559 TRACE("%p %s %lu %lx\n", pdnDevInst, debugstr_w(pDeviceID), ulFlags, hMachine);
1560
1561 if (pdnDevInst == NULL)
1562 return CR_INVALID_POINTER;
1563
1564 if (ulFlags & ~CM_LOCATE_DEVNODE_BITS)
1565 return CR_INVALID_FLAG;
1566
1567 if (hMachine != NULL)
1568 {
1569 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1570 if (BindingHandle == NULL)
1571 return CR_FAILURE;
1572
1573 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1574 if (StringTable == 0)
1575 return CR_FAILURE;
1576 }
1577 else
1578 {
1579 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1580 return CR_FAILURE;
1581 }
1582
1583 if (pDeviceID != NULL && lstrlenW(pDeviceID) != 0)
1584 {
1585 lstrcpyW(DeviceIdBuffer, pDeviceID);
1586 }
1587 else
1588 {
1589 /* Get the root device ID */
1590 ret = PNP_GetRootDeviceInstance(BindingHandle,
1591 DeviceIdBuffer,
1592 MAX_DEVICE_ID_LEN);
1593 if (ret != CR_SUCCESS)
1594 return CR_FAILURE;
1595 }
1596 TRACE("DeviceIdBuffer: %s\n", debugstr_w(DeviceIdBuffer));
1597
1598 /* Validate the device ID */
1599 ret = PNP_ValidateDeviceInstance(BindingHandle,
1600 DeviceIdBuffer,
1601 ulFlags);
1602 if (ret == CR_SUCCESS)
1603 {
1604 *pdnDevInst = StringTableAddString(StringTable, DeviceIdBuffer, 1);
1605 if (*pdnDevInst == -1)
1606 ret = CR_FAILURE;
1607 }
1608
1609 return ret;
1610 }
1611
1612
1613 /***********************************************************************
1614 * CM_Open_Class_KeyA [SETUPAPI.@]
1615 */
1616 CONFIGRET WINAPI CM_Open_Class_KeyA(
1617 LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
1618 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
1619 {
1620 TRACE("%p %s %lx %lx %p %lx\n",
1621 debugstr_guid(pClassGuid), pszClassName,
1622 samDesired, Disposition, phkClass, ulFlags);
1623
1624 return CM_Open_Class_Key_ExA(pClassGuid, pszClassName, samDesired,
1625 Disposition, phkClass, ulFlags, NULL);
1626 }
1627
1628
1629 /***********************************************************************
1630 * CM_Open_Class_KeyW [SETUPAPI.@]
1631 */
1632 CONFIGRET WINAPI CM_Open_Class_KeyW(
1633 LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
1634 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags)
1635 {
1636 TRACE("%p %s %lx %lx %p %lx\n",
1637 debugstr_guid(pClassGuid), debugstr_w(pszClassName),
1638 samDesired, Disposition, phkClass, ulFlags);
1639
1640 return CM_Open_Class_Key_ExW(pClassGuid, pszClassName, samDesired,
1641 Disposition, phkClass, ulFlags, NULL);
1642 }
1643
1644
1645 /***********************************************************************
1646 * CM_Open_Class_Key_ExA [SETUPAPI.@]
1647 */
1648 CONFIGRET WINAPI CM_Open_Class_Key_ExA(
1649 LPGUID pClassGuid, LPCSTR pszClassName, REGSAM samDesired,
1650 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
1651 HMACHINE hMachine)
1652 {
1653 CONFIGRET rc = CR_SUCCESS;
1654 LPWSTR pszClassNameW = NULL;
1655
1656 TRACE("%p %s %lx %lx %p %lx %lx\n",
1657 debugstr_guid(pClassGuid), pszClassName,
1658 samDesired, Disposition, phkClass, ulFlags, hMachine);
1659
1660 if (pszClassName != NULL)
1661 {
1662 if (CaptureAndConvertAnsiArg(pszClassName, &pszClassNameW))
1663 return CR_INVALID_DATA;
1664 }
1665
1666 rc = CM_Open_Class_Key_ExW(pClassGuid, pszClassNameW, samDesired,
1667 Disposition, phkClass, ulFlags, hMachine);
1668
1669 if (pszClassNameW != NULL)
1670 MyFree(pszClassNameW);
1671
1672 return CR_SUCCESS;
1673 }
1674
1675
1676 /***********************************************************************
1677 * CM_Open_Class_Key_ExW [SETUPAPI.@]
1678 */
1679 CONFIGRET WINAPI CM_Open_Class_Key_ExW(
1680 LPGUID pClassGuid, LPCWSTR pszClassName, REGSAM samDesired,
1681 REGDISPOSITION Disposition, PHKEY phkClass, ULONG ulFlags,
1682 HMACHINE hMachine)
1683 {
1684 WCHAR szKeyName[MAX_PATH];
1685 LPWSTR lpGuidString;
1686 DWORD dwDisposition;
1687 DWORD dwError;
1688 HKEY hKey;
1689
1690 TRACE("%p %s %lx %lx %p %lx %lx\n",
1691 debugstr_guid(pClassGuid), debugstr_w(pszClassName),
1692 samDesired, Disposition, phkClass, ulFlags, hMachine);
1693
1694 /* Check Disposition and ulFlags */
1695 if ((Disposition & ~RegDisposition_Bits) ||
1696 (ulFlags & ~CM_OPEN_CLASS_KEY_BITS))
1697 return CR_INVALID_FLAG;
1698
1699 /* Check phkClass */
1700 if (phkClass == NULL)
1701 return CR_INVALID_POINTER;
1702
1703 *phkClass = NULL;
1704
1705 if (ulFlags == CM_OPEN_CLASS_KEY_INTERFACE &&
1706 pszClassName != NULL)
1707 return CR_INVALID_DATA;
1708
1709 if (hMachine == NULL)
1710 {
1711 hKey = HKEY_LOCAL_MACHINE;
1712 }
1713 else
1714 {
1715 if (RegConnectRegistryW(((PMACHINE_INFO)hMachine)->szMachineName,
1716 HKEY_LOCAL_MACHINE, &hKey))
1717 return CR_REGISTRY_ERROR;
1718 }
1719
1720 if (ulFlags & CM_OPEN_CLASS_KEY_INTERFACE)
1721 {
1722 lstrcpyW(szKeyName, DeviceClasses);
1723 }
1724 else
1725 {
1726 lstrcpyW(szKeyName, ControlClass);
1727 }
1728
1729 if (pClassGuid != NULL)
1730 {
1731 if (UuidToStringW((UUID*)pClassGuid, &lpGuidString) != RPC_S_OK)
1732 {
1733 RegCloseKey(hKey);
1734 return CR_INVALID_DATA;
1735 }
1736
1737 lstrcatW(szKeyName, Backslash);
1738 lstrcatW(szKeyName, lpGuidString);
1739 }
1740
1741 if (Disposition == RegDisposition_OpenAlways)
1742 {
1743 dwError = RegCreateKeyExW(hKey, szKeyName, 0, NULL, 0, samDesired,
1744 NULL, phkClass, &dwDisposition);
1745 }
1746 else
1747 {
1748 dwError = RegOpenKeyExW(hKey, szKeyName, 0, samDesired, phkClass);
1749 }
1750
1751 RegCloseKey(hKey);
1752
1753 if (pClassGuid != NULL)
1754 RpcStringFreeW(&lpGuidString);
1755
1756 if (dwError != ERROR_SUCCESS)
1757 {
1758 *phkClass = NULL;
1759 return CR_NO_SUCH_REGISTRY_KEY;
1760 }
1761
1762 if (pszClassName != NULL)
1763 {
1764 RegSetValueExW(*phkClass, Class, 0, REG_SZ, (LPBYTE)pszClassName,
1765 (lstrlenW(pszClassName) + 1) * sizeof(WCHAR));
1766 }
1767
1768 return CR_SUCCESS;
1769 }
1770
1771
1772 /***********************************************************************
1773 * CM_Set_DevNode_Problem [SETUPAPI.@]
1774 */
1775 CONFIGRET WINAPI CM_Set_DevNode_Problem(
1776 DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags)
1777 {
1778 TRACE("%lx %lx %lx\n", dnDevInst, ulProblem, ulFlags);
1779 return CM_Set_DevNode_Problem_Ex(dnDevInst, ulProblem, ulFlags, NULL);
1780 }
1781
1782
1783 /***********************************************************************
1784 * CM_Set_DevNode_Problem_Ex [SETUPAPI.@]
1785 */
1786 CONFIGRET WINAPI CM_Set_DevNode_Problem_Ex(
1787 DEVINST dnDevInst, ULONG ulProblem, ULONG ulFlags, HMACHINE hMachine)
1788 {
1789 RPC_BINDING_HANDLE BindingHandle = NULL;
1790 HSTRING_TABLE StringTable = NULL;
1791 LPWSTR lpDevInst;
1792
1793 TRACE("%lx %lx %lx %lx\n", dnDevInst, ulProblem, ulFlags, hMachine);
1794
1795 if (dnDevInst == 0)
1796 return CR_INVALID_DEVNODE;
1797
1798 if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
1799 return CR_INVALID_FLAG;
1800
1801 if (hMachine != NULL)
1802 {
1803 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
1804 if (BindingHandle == NULL)
1805 return CR_FAILURE;
1806
1807 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
1808 if (StringTable == 0)
1809 return CR_FAILURE;
1810 }
1811 else
1812 {
1813 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
1814 return CR_FAILURE;
1815 }
1816
1817 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
1818 if (lpDevInst == NULL)
1819 return CR_INVALID_DEVNODE;
1820
1821 return PNP_SetDeviceProblem(BindingHandle,
1822 lpDevInst,
1823 ulProblem,
1824 ulFlags);
1825 }
1826
1827
1828 /***********************************************************************
1829 * CM_Set_DevNode_Registry_PropertyA [SETUPAPI.@]
1830 */
1831 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyA(
1832 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
1833 ULONG ulFlags)
1834 {
1835 TRACE("%lx %lu %p %lx %lx\n",
1836 dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
1837 return CM_Set_DevNode_Registry_Property_ExA(dnDevInst, ulProperty,
1838 Buffer, ulLength,
1839 ulFlags, NULL);
1840 }
1841
1842
1843 /***********************************************************************
1844 * CM_Set_DevNode_Registry_PropertyW [SETUPAPI.@]
1845 */
1846 CONFIGRET WINAPI CM_Set_DevNode_Registry_PropertyW(
1847 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
1848 ULONG ulFlags)
1849 {
1850 TRACE("%lx %lu %p %lx %lx\n",
1851 dnDevInst, ulProperty, Buffer, ulLength, ulFlags);
1852 return CM_Set_DevNode_Registry_Property_ExW(dnDevInst, ulProperty,
1853 Buffer, ulLength,
1854 ulFlags, NULL);
1855 }
1856
1857
1858 /***********************************************************************
1859 * CM_Set_DevNode_Registry_Property_ExA [SETUPAPI.@]
1860 */
1861 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExA(
1862 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
1863 ULONG ulFlags, HMACHINE hMachine)
1864 {
1865 CONFIGRET ret = CR_SUCCESS;
1866 LPWSTR lpBuffer;
1867 ULONG ulType;
1868
1869 FIXME("%lx %lu %p %lx %lx %lx\n",
1870 dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
1871
1872 if (Buffer == NULL && ulLength != 0)
1873 return CR_INVALID_POINTER;
1874
1875 if (Buffer == NULL)
1876 {
1877 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
1878 ulProperty,
1879 NULL,
1880 0,
1881 ulFlags,
1882 hMachine);
1883 }
1884 else
1885 {
1886 /* Get property type */
1887 switch (ulProperty)
1888 {
1889 case CM_DRP_DEVICEDESC:
1890 ulType = REG_SZ;
1891 break;
1892
1893 case CM_DRP_HARDWAREID:
1894 ulType = REG_MULTI_SZ;
1895 break;
1896
1897 case CM_DRP_COMPATIBLEIDS:
1898 ulType = REG_MULTI_SZ;
1899 break;
1900
1901 case CM_DRP_SERVICE:
1902 ulType = REG_SZ;
1903 break;
1904
1905 case CM_DRP_CLASS:
1906 ulType = REG_SZ;
1907 break;
1908
1909 case CM_DRP_CLASSGUID:
1910 ulType = REG_SZ;
1911 break;
1912
1913 case CM_DRP_DRIVER:
1914 ulType = REG_SZ;
1915 break;
1916
1917 case CM_DRP_CONFIGFLAGS:
1918 ulType = REG_DWORD;
1919 break;
1920
1921 case CM_DRP_MFG:
1922 ulType = REG_SZ;
1923 break;
1924
1925 case CM_DRP_FRIENDLYNAME:
1926 ulType = REG_SZ;
1927 break;
1928
1929 case CM_DRP_LOCATION_INFORMATION:
1930 ulType = REG_SZ;
1931 break;
1932
1933 case CM_DRP_UPPERFILTERS:
1934 ulType = REG_MULTI_SZ;
1935 break;
1936
1937 case CM_DRP_LOWERFILTERS:
1938 ulType = REG_MULTI_SZ;
1939 break;
1940
1941 default:
1942 return CR_INVALID_PROPERTY;
1943 }
1944
1945 /* Allocate buffer if needed */
1946 if (ulType == REG_SZ ||
1947 ulType == REG_MULTI_SZ)
1948 {
1949 lpBuffer = MyMalloc(ulLength * sizeof(WCHAR));
1950 if (lpBuffer == NULL)
1951 {
1952 ret = CR_OUT_OF_MEMORY;
1953 }
1954 else
1955 {
1956 if (!MultiByteToWideChar(CP_ACP, 0, Buffer,
1957 ulLength, lpBuffer, ulLength))
1958 {
1959 MyFree(lpBuffer);
1960 ret = CR_FAILURE;
1961 }
1962 else
1963 {
1964 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
1965 ulProperty,
1966 lpBuffer,
1967 ulLength * sizeof(WCHAR),
1968 ulFlags,
1969 hMachine);
1970 MyFree(lpBuffer);
1971 }
1972 }
1973 }
1974 else
1975 {
1976 ret = CM_Set_DevNode_Registry_Property_ExW(dnDevInst,
1977 ulProperty,
1978 Buffer,
1979 ulLength,
1980 ulFlags,
1981 hMachine);
1982 }
1983
1984 ret = CR_CALL_NOT_IMPLEMENTED;
1985 }
1986
1987 return ret;
1988 }
1989
1990
1991 /***********************************************************************
1992 * CM_Set_DevNode_Registry_Property_ExW [SETUPAPI.@]
1993 */
1994 CONFIGRET WINAPI CM_Set_DevNode_Registry_Property_ExW(
1995 DEVINST dnDevInst, ULONG ulProperty, PCVOID Buffer, ULONG ulLength,
1996 ULONG ulFlags, HMACHINE hMachine)
1997 {
1998 RPC_BINDING_HANDLE BindingHandle = NULL;
1999 HSTRING_TABLE StringTable = NULL;
2000 LPWSTR lpDevInst;
2001 ULONG ulType;
2002
2003 TRACE("%lx %lu %p %lx %lx %lx\n",
2004 dnDevInst, ulProperty, Buffer, ulLength, ulFlags, hMachine);
2005
2006 if (dnDevInst == 0)
2007 return CR_INVALID_DEVNODE;
2008
2009 if (ulProperty < CM_DRP_MIN || ulProperty > CM_DRP_MAX)
2010 return CR_INVALID_PROPERTY;
2011
2012 if (Buffer != NULL && ulLength == 0)
2013 return CR_INVALID_POINTER;
2014
2015 if (ulFlags != 0)
2016 return CR_INVALID_FLAG;
2017
2018 if (hMachine != NULL)
2019 {
2020 BindingHandle = ((PMACHINE_INFO)hMachine)->BindingHandle;
2021 if (BindingHandle == NULL)
2022 return CR_FAILURE;
2023
2024 StringTable = ((PMACHINE_INFO)hMachine)->StringTable;
2025 if (StringTable == 0)
2026 return CR_FAILURE;
2027 }
2028 else
2029 {
2030 if (!PnpGetLocalHandles(&BindingHandle, &StringTable))
2031 return CR_FAILURE;
2032 }
2033
2034 lpDevInst = StringTableStringFromId(StringTable, dnDevInst);
2035 if (lpDevInst == NULL)
2036 return CR_INVALID_DEVNODE;
2037
2038 switch (ulProperty)
2039 {
2040 case CM_DRP_DEVICEDESC:
2041 ulType = REG_SZ;
2042 break;
2043
2044 case CM_DRP_HARDWAREID:
2045 ulType = REG_MULTI_SZ;
2046 break;
2047
2048 case CM_DRP_COMPATIBLEIDS:
2049 ulType = REG_MULTI_SZ;
2050 break;
2051
2052 case CM_DRP_SERVICE:
2053 ulType = REG_SZ;
2054 break;
2055
2056 case CM_DRP_CLASS:
2057 ulType = REG_SZ;
2058 break;
2059
2060 case CM_DRP_CLASSGUID:
2061 ulType = REG_SZ;
2062 break;
2063
2064 case CM_DRP_DRIVER:
2065 ulType = REG_SZ;
2066 break;
2067
2068 case CM_DRP_CONFIGFLAGS:
2069 ulType = REG_DWORD;
2070 break;
2071
2072 case CM_DRP_MFG:
2073 ulType = REG_SZ;
2074 break;
2075
2076 case CM_DRP_FRIENDLYNAME:
2077 ulType = REG_SZ;
2078 break;
2079
2080 case CM_DRP_LOCATION_INFORMATION:
2081 ulType = REG_SZ;
2082 break;
2083
2084 case CM_DRP_UPPERFILTERS:
2085 ulType = REG_MULTI_SZ;
2086 break;
2087
2088 case CM_DRP_LOWERFILTERS:
2089 ulType = REG_MULTI_SZ;
2090 break;
2091
2092 default:
2093 return CR_INVALID_PROPERTY;
2094 }
2095
2096 return PNP_SetDeviceRegProp(BindingHandle,
2097 lpDevInst,
2098 ulProperty,
2099 ulType,
2100 (char *)Buffer,
2101 ulLength,
2102 ulFlags);
2103 }