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