1 /*
2 * ReactOS kernel
3 * Copyright (C) 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: base/services/umpnpmgr/rpcserver.c
23 * PURPOSE: RPC server
24 * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
25 * Hervé Poussineau (hpoussin@reactos.org)
26 * Colin Finck (colin@reactos.org)
27 */
28
29 /* INCLUDES *****************************************************************/
30
31 #include "precomp.h"
32
33 #define NDEBUG
34 #include <debug.h>
35
36
37 /* GLOBALS ******************************************************************/
38
39 static WCHAR szRootDeviceInstanceID[] = L"HTREE\\ROOT\\0";
40
41 LIST_ENTRY NotificationListHead;
42
43 /* FUNCTIONS *****************************************************************/
44
45 DWORD WINAPI
RpcServerThread(LPVOID lpParameter)46 RpcServerThread(LPVOID lpParameter)
47 {
48 RPC_STATUS Status;
49 BOOLEAN RegisteredProtSeq = FALSE;
50
51 UNREFERENCED_PARAMETER(lpParameter);
52
53 DPRINT("RpcServerThread() called\n");
54
55 InitializeListHead(&NotificationListHead);
56
57 #if 0
58 /* 2k/XP/2k3-compatible protocol sequence/endpoint */
59 Status = RpcServerUseProtseqEpW(L"ncacn_np",
60 20,
61 L"\\pipe\\ntsvcs",
62 NULL); // Security descriptor
63 if (Status == RPC_S_OK)
64 RegisteredProtSeq = TRUE;
65 else
66 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
67 #endif
68
69 /* Vista/7-compatible protocol sequence/endpoint */
70 Status = RpcServerUseProtseqEpW(L"ncacn_np",
71 20,
72 L"\\pipe\\plugplay",
73 NULL); // Security descriptor
74 if (Status == RPC_S_OK)
75 RegisteredProtSeq = TRUE;
76 else
77 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
78
79 /* Make sure there's a usable endpoint */
80 if (RegisteredProtSeq == FALSE)
81 return 0;
82
83 Status = RpcServerRegisterIf(pnp_v1_0_s_ifspec,
84 NULL,
85 NULL);
86 if (Status != RPC_S_OK)
87 {
88 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
89 return 0;
90 }
91
92 Status = RpcServerListen(1,
93 20,
94 FALSE);
95 if (Status != RPC_S_OK)
96 {
97 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
98 return 0;
99 }
100
101 /* ROS HACK (this should never happen...) */
102 DPRINT1("*** Other devices won't be installed correctly. If something\n");
103 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
104
105 DPRINT("RpcServerThread() done\n");
106
107 return 0;
108 }
109
110
midl_user_allocate(SIZE_T len)111 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len)
112 {
113 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
114 }
115
116
midl_user_free(void __RPC_FAR * ptr)117 void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
118 {
119 HeapFree(GetProcessHeap(), 0, ptr);
120 }
121
122
123 static CONFIGRET WINAPI
NtStatusToCrError(NTSTATUS Status)124 NtStatusToCrError(NTSTATUS Status)
125 {
126 switch (Status)
127 {
128 case STATUS_NOT_IMPLEMENTED:
129 return CR_CALL_NOT_IMPLEMENTED;
130
131 case STATUS_INVALID_PARAMETER:
132 return CR_INVALID_DATA;
133
134 case STATUS_NO_SUCH_DEVICE:
135 return CR_NO_SUCH_DEVINST;
136
137 case STATUS_ACCESS_DENIED:
138 return CR_ACCESS_DENIED;
139
140 case STATUS_BUFFER_TOO_SMALL:
141 return CR_BUFFER_SMALL;
142
143 case STATUS_OBJECT_NAME_NOT_FOUND:
144 return CR_NO_SUCH_VALUE;
145
146 default:
147 return CR_FAILURE;
148 }
149 }
150
151
152 static VOID
SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID,OUT LPWSTR pszEnumerator,OUT LPWSTR pszDevice,OUT LPWSTR pszInstance)153 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID,
154 OUT LPWSTR pszEnumerator,
155 OUT LPWSTR pszDevice,
156 OUT LPWSTR pszInstance)
157 {
158 WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN];
159 LPWSTR lpEnumerator = NULL;
160 LPWSTR lpDevice = NULL;
161 LPWSTR lpInstance = NULL;
162 LPWSTR ptr;
163
164 wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID);
165
166 *pszEnumerator = 0;
167 *pszDevice = 0;
168 *pszInstance = 0;
169
170 lpEnumerator = szLocalDeviceInstanceID;
171
172 ptr = wcschr(lpEnumerator, L'\\');
173 if (ptr != NULL)
174 {
175 *ptr = 0;
176 lpDevice = ++ptr;
177
178 ptr = wcschr(lpDevice, L'\\');
179 if (ptr != NULL)
180 {
181 *ptr = 0;
182 lpInstance = ++ptr;
183 }
184 }
185
186 if (lpEnumerator != NULL)
187 wcscpy(pszEnumerator, lpEnumerator);
188
189 if (lpDevice != NULL)
190 wcscpy(pszDevice, lpDevice);
191
192 if (lpInstance != NULL)
193 wcscpy(pszInstance, lpInstance);
194 }
195
196
197 static
198 CONFIGRET
ClearDeviceStatus(_In_ LPWSTR pszDeviceID,_In_ DWORD ulStatus,_In_ DWORD ulProblem)199 ClearDeviceStatus(
200 _In_ LPWSTR pszDeviceID,
201 _In_ DWORD ulStatus,
202 _In_ DWORD ulProblem)
203 {
204 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
205 CONFIGRET ret = CR_SUCCESS;
206 NTSTATUS Status;
207
208 DPRINT1("ClearDeviceStatus(%S 0x%lx 0x%lx)\n",
209 pszDeviceID, ulStatus, ulProblem);
210
211 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
212 pszDeviceID);
213 PlugPlayData.Operation = PNP_CLEAR_DEVICE_STATUS;
214 PlugPlayData.DeviceStatus = ulStatus;
215 PlugPlayData.DeviceProblem = ulProblem;
216
217 Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
218 (PVOID)&PlugPlayData,
219 sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
220 if (!NT_SUCCESS(Status))
221 ret = NtStatusToCrError(Status);
222
223 return ret;
224 }
225
226
227 static
228 CONFIGRET
GetDeviceStatus(_In_ LPWSTR pszDeviceID,_Out_ DWORD * pulStatus,_Out_ DWORD * pulProblem)229 GetDeviceStatus(
230 _In_ LPWSTR pszDeviceID,
231 _Out_ DWORD *pulStatus,
232 _Out_ DWORD *pulProblem)
233 {
234 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
235 CONFIGRET ret = CR_SUCCESS;
236 NTSTATUS Status;
237
238 DPRINT("GetDeviceStatus(%S %p %p)\n",
239 pszDeviceID, pulStatus, pulProblem);
240
241 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
242 pszDeviceID);
243 PlugPlayData.Operation = PNP_GET_DEVICE_STATUS;
244
245 Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
246 (PVOID)&PlugPlayData,
247 sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
248 if (NT_SUCCESS(Status))
249 {
250 *pulStatus = PlugPlayData.DeviceStatus;
251 *pulProblem = PlugPlayData.DeviceProblem;
252 }
253 else
254 {
255 ret = NtStatusToCrError(Status);
256 }
257
258 return ret;
259 }
260
261
262 static
263 CONFIGRET
SetDeviceStatus(_In_ LPWSTR pszDeviceID,_In_ DWORD ulStatus,_In_ DWORD ulProblem)264 SetDeviceStatus(
265 _In_ LPWSTR pszDeviceID,
266 _In_ DWORD ulStatus,
267 _In_ DWORD ulProblem)
268 {
269 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData;
270 CONFIGRET ret = CR_SUCCESS;
271 NTSTATUS Status;
272
273 DPRINT1("SetDeviceStatus(%S 0x%lx 0x%lx)\n",
274 pszDeviceID, ulStatus, ulProblem);
275
276 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
277 pszDeviceID);
278 PlugPlayData.Operation = PNP_SET_DEVICE_STATUS;
279 PlugPlayData.DeviceStatus = ulStatus;
280 PlugPlayData.DeviceProblem = ulProblem;
281
282 Status = NtPlugPlayControl(PlugPlayControlDeviceStatus,
283 (PVOID)&PlugPlayData,
284 sizeof(PLUGPLAY_CONTROL_STATUS_DATA));
285 if (!NT_SUCCESS(Status))
286 ret = NtStatusToCrError(Status);
287
288 return ret;
289 }
290
291
292 static
293 CONFIGRET
DisableDeviceInstance(_In_ LPWSTR pszDeviceInstance,_Inout_opt_ PPNP_VETO_TYPE pVetoType,_Inout_opt_ LPWSTR pszVetoName,_In_ DWORD ulNameLength)294 DisableDeviceInstance(
295 _In_ LPWSTR pszDeviceInstance,
296 _Inout_opt_ PPNP_VETO_TYPE pVetoType,
297 _Inout_opt_ LPWSTR pszVetoName,
298 _In_ DWORD ulNameLength)
299 {
300 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA QueryRemoveData;
301 CONFIGRET ret = CR_SUCCESS;
302 NTSTATUS Status;
303
304 DPRINT1("DisableDeviceInstance(%S %p %p %lu)\n",
305 pszDeviceInstance, pVetoType, pszVetoName, ulNameLength);
306
307 RtlInitUnicodeString(&QueryRemoveData.DeviceInstance,
308 pszDeviceInstance);
309
310 QueryRemoveData.Flags = 0;
311 QueryRemoveData.VetoType = 0;
312 QueryRemoveData.VetoName = pszVetoName;
313 QueryRemoveData.NameLength = ulNameLength;
314
315 Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice,
316 &QueryRemoveData,
317 sizeof(PLUGPLAY_CONTROL_QUERY_REMOVE_DATA));
318 if (Status == STATUS_NO_SUCH_DEVICE)
319 {
320 ret = CR_INVALID_DEVNODE;
321 }
322 else if (Status == STATUS_PLUGPLAY_QUERY_VETOED)
323 {
324 if (pVetoType != NULL)
325 *pVetoType = QueryRemoveData.VetoType;
326
327 ret = CR_REMOVE_VETOED;
328 }
329 else if (!NT_SUCCESS(Status))
330 {
331 ret = NtStatusToCrError(Status);
332 }
333
334 return ret;
335 }
336
337
338 static
339 BOOL
IsValidDeviceInstanceID(_In_ PWSTR pszDeviceInstanceID)340 IsValidDeviceInstanceID(
341 _In_ PWSTR pszDeviceInstanceID)
342 {
343 INT nPartLength[3] = {0, 0, 0};
344 INT nLength = 0, nParts = 0;
345 PWCHAR p;
346
347 DPRINT("IsValidDeviceInstanceID(%S)\n",
348 pszDeviceInstanceID);
349
350 if (pszDeviceInstanceID == NULL)
351 {
352 DPRINT("Device instance ID is NULL!\n");
353 return FALSE;
354 }
355
356 p = pszDeviceInstanceID;
357 while (*p != UNICODE_NULL)
358 {
359 if (*p == L'\\')
360 {
361 nParts++;
362 if (nParts >= 3)
363 {
364 DPRINT("Too many separators: %d\n", nParts);
365 return FALSE;
366 }
367 }
368 else
369 {
370 nPartLength[nParts]++;
371 }
372
373 nLength++;
374 if (nLength >= MAX_DEVICE_ID_LEN)
375 {
376 DPRINT("Too long: %d\n", nLength);
377 return FALSE;
378 }
379
380 p++;
381 }
382
383 if (nParts != 2)
384 {
385 DPRINT("Invalid number of separtors: %d\n", nParts);
386 return FALSE;
387 }
388
389 if ((nPartLength[0] == 0) ||
390 (nPartLength[1] == 0) ||
391 (nPartLength[2] == 0))
392 {
393 DPRINT("Invalid part lengths: %d %d %d\n",
394 nPartLength[0], nPartLength[1], nPartLength[2]);
395 return FALSE;
396 }
397
398 DPRINT("Valid device instance ID!\n");
399
400 return TRUE;
401 }
402
403
404 static
405 BOOL
IsRootDeviceInstanceID(_In_ PWSTR pszDeviceInstanceID)406 IsRootDeviceInstanceID(
407 _In_ PWSTR pszDeviceInstanceID)
408 {
409 if (_wcsicmp(pszDeviceInstanceID, szRootDeviceInstanceID) == 0)
410 return TRUE;
411
412 return FALSE;
413 }
414
415
416 static
417 BOOL
IsPresentDeviceInstanceID(_In_ LPWSTR pszDeviceInstanceID)418 IsPresentDeviceInstanceID(
419 _In_ LPWSTR pszDeviceInstanceID)
420 {
421 DWORD ulStatus, ulProblem;
422
423 return (GetDeviceStatus(pszDeviceInstanceID, &ulStatus, &ulProblem) == CR_SUCCESS);
424 }
425
426
427 static
428 CONFIGRET
OpenConfigurationKey(_In_ LPCWSTR pszDeviceID,_In_ DWORD ulLogConfType,_Out_ PHKEY phKey)429 OpenConfigurationKey(
430 _In_ LPCWSTR pszDeviceID,
431 _In_ DWORD ulLogConfType,
432 _Out_ PHKEY phKey)
433 {
434 WCHAR szKeyName[MAX_PATH];
435 PCWSTR pszSubKeyName;
436 HKEY hInstanceKey;
437 DWORD dwError;
438
439 /* Build the full device instance key name */
440 wcscpy(szKeyName, L"System\\CurrentControlSet\\Enum\\");
441 wcscat(szKeyName, pszDeviceID);
442
443 /* Open the device instance key */
444 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
445 szKeyName,
446 0,
447 KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY,
448 &hInstanceKey);
449 if (dwError != ERROR_SUCCESS)
450 return CR_INVALID_DEVINST;
451
452 switch (ulLogConfType)
453 {
454 case BOOT_LOG_CONF:
455 case BASIC_LOG_CONF:
456 pszSubKeyName = L"LogConf";
457 break;
458
459 case ALLOC_LOG_CONF:
460 case FILTERED_LOG_CONF:
461 pszSubKeyName = L"Control";
462 break;
463
464 default:
465 DPRINT1("Unsupported configuration type!\n");
466 return CR_FAILURE;
467 }
468
469 /* Create or open the LogConf key */
470 dwError = RegCreateKeyExW(hInstanceKey,
471 pszSubKeyName,
472 0,
473 NULL,
474 REG_OPTION_NON_VOLATILE,
475 KEY_ALL_ACCESS,
476 NULL,
477 phKey,
478 NULL);
479
480 /* Close the device instance key */
481 RegCloseKey(hInstanceKey);
482
483 if (dwError != ERROR_SUCCESS)
484 return CR_REGISTRY_ERROR;
485
486 return CR_SUCCESS;
487 }
488
489
490 static
491 CONFIGRET
GetConfigurationData(_In_ HKEY hKey,_In_ ULONG ulLogConfType,_Out_ PULONG pulRegDataType,_Out_ PULONG pulDataSize,_Out_ LPBYTE * ppBuffer)492 GetConfigurationData(
493 _In_ HKEY hKey,
494 _In_ ULONG ulLogConfType,
495 _Out_ PULONG pulRegDataType,
496 _Out_ PULONG pulDataSize,
497 _Out_ LPBYTE *ppBuffer)
498 {
499 LPCWSTR pszValueName;
500
501 switch (ulLogConfType)
502 {
503 case BOOT_LOG_CONF:
504 pszValueName = L"BootConfig";
505 *pulRegDataType = REG_RESOURCE_LIST;
506 break;
507
508 case ALLOC_LOG_CONF:
509 pszValueName = L"AllocConfig";
510 *pulRegDataType = REG_RESOURCE_LIST;
511 break;
512
513 case FORCED_LOG_CONF:
514 pszValueName = L"ForcedConfig";
515 *pulRegDataType = REG_RESOURCE_LIST;
516 break;
517
518 case FILTERED_LOG_CONF:
519 pszValueName = L"FilteredConfigVector";
520 *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
521 break;
522
523 case BASIC_LOG_CONF:
524 pszValueName = L"BasicConfigVector";
525 *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
526 break;
527
528 case OVERRIDE_LOG_CONF:
529 pszValueName = L"OverrideConfigVector";
530 *pulRegDataType = REG_RESOURCE_REQUIREMENTS_LIST;
531 break;
532
533 default:
534 DPRINT1("Unsupported configuration type!\n");
535 return CR_FAILURE;
536 }
537
538 /* Get the configuration data size */
539 if (RegQueryValueExW(hKey,
540 pszValueName,
541 NULL,
542 NULL,
543 NULL,
544 pulDataSize) != ERROR_SUCCESS)
545 {
546 return CR_INVALID_LOG_CONF;
547 }
548
549 /* Allocate the buffer */
550 *ppBuffer = HeapAlloc(GetProcessHeap(), 0, *pulDataSize);
551 if (*ppBuffer == NULL)
552 {
553 return CR_OUT_OF_MEMORY;
554 }
555
556 /* Retrieve the configuration data */
557 if (RegQueryValueExW(hKey,
558 pszValueName,
559 NULL,
560 NULL,
561 (LPBYTE)*ppBuffer,
562 pulDataSize) != ERROR_SUCCESS)
563 {
564 return CR_INVALID_LOG_CONF;
565 }
566
567 return CR_SUCCESS;
568 }
569
570
571 static
572 BOOL
IsCallerInteractive(_In_ handle_t hBinding)573 IsCallerInteractive(
574 _In_ handle_t hBinding)
575 {
576 SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
577 HANDLE hToken;
578 PSID pInteractiveSid = NULL;
579 BOOL bInteractive = FALSE;
580 RPC_STATUS RpcStatus;
581
582 DPRINT("IsCallerInteractive(%p)\n", hBinding);
583
584 /* Allocate an interactive user sid */
585 if (!AllocateAndInitializeSid(&NtAuthority,
586 1,
587 SECURITY_INTERACTIVE_RID,
588 0, 0, 0, 0, 0, 0, 0,
589 &pInteractiveSid))
590 {
591 DPRINT1("AllocateAndInitializeSid failed\n");
592 return FALSE;
593 }
594
595 /* Impersonate the client */
596 RpcStatus = RpcImpersonateClient(hBinding);
597 if (RpcStatus != RPC_S_OK)
598 {
599 DPRINT1("RpcImpersonateClient failed (Status 0x%08lx)\n", RpcStatus);
600 goto done;
601 }
602
603 /* Open the thread token and check for interactive user membership */
604 if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
605 {
606 CheckTokenMembership(hToken, pInteractiveSid, &bInteractive);
607 CloseHandle(hToken);
608 }
609
610 /* Revert the impersonation */
611 RpcRevertToSelf();
612
613 done:
614 if (pInteractiveSid)
615 FreeSid(pInteractiveSid);
616
617 return bInteractive;
618 }
619
620
621 VOID
622 __RPC_USER
PNP_NOTIFY_HANDLE_rundown(PNP_NOTIFY_HANDLE pHandle)623 PNP_NOTIFY_HANDLE_rundown(
624 PNP_NOTIFY_HANDLE pHandle)
625 {
626 DPRINT1("PNP_NOTIFY_HANDLE_rundown(%p)\n", pHandle);
627 }
628
629
630 /* PUBLIC FUNCTIONS **********************************************************/
631
632 /* Function 0 */
633 DWORD
634 WINAPI
PNP_Disconnect(handle_t hBinding)635 PNP_Disconnect(
636 handle_t hBinding)
637 {
638 UNREFERENCED_PARAMETER(hBinding);
639 return CR_SUCCESS;
640 }
641
642
643 /* Function 1 */
644 DWORD
645 WINAPI
PNP_Connect(handle_t hBinding)646 PNP_Connect(
647 handle_t hBinding)
648 {
649 UNREFERENCED_PARAMETER(hBinding);
650 return CR_SUCCESS;
651 }
652
653
654 /* Function 2 */
655 DWORD
656 WINAPI
PNP_GetVersion(handle_t hBinding,WORD * pVersion)657 PNP_GetVersion(
658 handle_t hBinding,
659 WORD *pVersion)
660 {
661 UNREFERENCED_PARAMETER(hBinding);
662
663 DPRINT("PNP_GetVersion(%p %p)\n",
664 hBinding, pVersion);
665
666 *pVersion = CONFIGMG_VERSION;
667
668 return CR_SUCCESS;
669 }
670
671
672 /* Function 3 */
673 DWORD
674 WINAPI
PNP_GetGlobalState(handle_t hBinding,DWORD * pulState,DWORD ulFlags)675 PNP_GetGlobalState(
676 handle_t hBinding,
677 DWORD *pulState,
678 DWORD ulFlags)
679 {
680 UNREFERENCED_PARAMETER(hBinding);
681
682 DPRINT("PNP_GetGlobalState(%p %p 0x%08lx)\n",
683 hBinding, pulState, ulFlags);
684
685 if (ulFlags != 0)
686 return CR_INVALID_FLAG;
687
688 *pulState = CM_GLOBAL_STATE_CAN_DO_UI | CM_GLOBAL_STATE_SERVICES_AVAILABLE;
689
690 if (g_ShuttingDown)
691 *pulState |= CM_GLOBAL_STATE_SHUTTING_DOWN;
692
693 return CR_SUCCESS;
694 }
695
696
697 /* Function 4 */
698 DWORD
699 WINAPI
PNP_InitDetection(handle_t hBinding)700 PNP_InitDetection(
701 handle_t hBinding)
702 {
703 UNREFERENCED_PARAMETER(hBinding);
704
705 DPRINT("PNP_InitDetection(%p)\n",
706 hBinding);
707
708 return CR_SUCCESS;
709 }
710
711
712 /* Function 5 */
713 DWORD
714 WINAPI
PNP_ReportLogOn(handle_t hBinding,BOOL Admin,DWORD ProcessId)715 PNP_ReportLogOn(
716 handle_t hBinding,
717 BOOL Admin,
718 DWORD ProcessId)
719 {
720 DWORD ReturnValue = CR_FAILURE;
721 HANDLE hProcess = NULL;
722
723 UNREFERENCED_PARAMETER(Admin);
724
725 DPRINT("PNP_ReportLogOn(%p %u, %u)\n",
726 hBinding, Admin, ProcessId);
727
728 /* Fail, if the caller is not an interactive user */
729 if (!IsCallerInteractive(hBinding))
730 goto cleanup;
731
732 /* Get the users token */
733 hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, ProcessId);
734
735 if (!hProcess)
736 {
737 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
738 goto cleanup;
739 }
740
741 if (hUserToken)
742 {
743 CloseHandle(hUserToken);
744 hUserToken = NULL;
745 }
746
747 if (!OpenProcessToken(hProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY, &hUserToken))
748 {
749 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
750 goto cleanup;
751 }
752
753 /* Trigger the installer thread */
754 if (hInstallEvent)
755 SetEvent(hInstallEvent);
756
757 ReturnValue = CR_SUCCESS;
758
759 cleanup:
760 if (hProcess)
761 CloseHandle(hProcess);
762
763 return ReturnValue;
764 }
765
766
767 /* Function 6 */
768 DWORD
769 WINAPI
PNP_ValidateDeviceInstance(handle_t hBinding,LPWSTR pDeviceID,DWORD ulFlags)770 PNP_ValidateDeviceInstance(
771 handle_t hBinding,
772 LPWSTR pDeviceID,
773 DWORD ulFlags)
774 {
775 CONFIGRET ret = CR_SUCCESS;
776 HKEY hDeviceKey = NULL;
777
778 UNREFERENCED_PARAMETER(hBinding);
779 UNREFERENCED_PARAMETER(ulFlags);
780
781 DPRINT("PNP_ValidateDeviceInstance(%p %S 0x%08lx)\n",
782 hBinding, pDeviceID, ulFlags);
783
784 if (!IsValidDeviceInstanceID(pDeviceID))
785 return CR_INVALID_DEVINST;
786
787 if (RegOpenKeyExW(hEnumKey,
788 pDeviceID,
789 0,
790 KEY_READ,
791 &hDeviceKey))
792 {
793 DPRINT("Could not open the Device Key!\n");
794 ret = CR_NO_SUCH_DEVNODE;
795 goto Done;
796 }
797
798 /* FIXME: add more tests */
799
800 Done:
801 if (hDeviceKey != NULL)
802 RegCloseKey(hDeviceKey);
803
804 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret);
805
806 return ret;
807 }
808
809
810 /* Function 7 */
811 DWORD
812 WINAPI
PNP_GetRootDeviceInstance(handle_t hBinding,LPWSTR pDeviceID,PNP_RPC_STRING_LEN ulLength)813 PNP_GetRootDeviceInstance(
814 handle_t hBinding,
815 LPWSTR pDeviceID,
816 PNP_RPC_STRING_LEN ulLength)
817 {
818 CONFIGRET ret = CR_SUCCESS;
819
820 UNREFERENCED_PARAMETER(hBinding);
821
822 DPRINT("PNP_GetRootDeviceInstance(%p %S %lu)\n",
823 hBinding, pDeviceID, ulLength);
824
825 if (!pDeviceID)
826 {
827 ret = CR_INVALID_POINTER;
828 goto Done;
829 }
830
831 if (ulLength < lstrlenW(szRootDeviceInstanceID) + 1)
832 {
833 ret = CR_BUFFER_SMALL;
834 goto Done;
835 }
836
837 lstrcpyW(pDeviceID,
838 szRootDeviceInstanceID);
839
840 Done:
841 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret);
842
843 return ret;
844 }
845
846
847 /* Function 8 */
848 DWORD
849 WINAPI
PNP_GetRelatedDeviceInstance(handle_t hBinding,DWORD ulRelationship,LPWSTR pDeviceID,LPWSTR pRelatedDeviceId,PNP_RPC_STRING_LEN * pulLength,DWORD ulFlags)850 PNP_GetRelatedDeviceInstance(
851 handle_t hBinding,
852 DWORD ulRelationship,
853 LPWSTR pDeviceID,
854 LPWSTR pRelatedDeviceId,
855 PNP_RPC_STRING_LEN *pulLength,
856 DWORD ulFlags)
857 {
858 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData;
859 CONFIGRET ret = CR_SUCCESS;
860 NTSTATUS Status;
861
862 UNREFERENCED_PARAMETER(hBinding);
863 UNREFERENCED_PARAMETER(ulFlags);
864
865 DPRINT("PNP_GetRelatedDeviceInstance(%p %lu %S %p %p 0x%lx)\n",
866 hBinding, ulRelationship, pDeviceID, pRelatedDeviceId,
867 pulLength, ulFlags);
868
869 if (!IsValidDeviceInstanceID(pDeviceID))
870 return CR_INVALID_DEVINST;
871
872 if (ulRelationship == PNP_GET_PARENT_DEVICE_INSTANCE)
873 {
874 /* The root device does not have a parent */
875 if (IsRootDeviceInstanceID(pDeviceID))
876 return CR_NO_SUCH_DEVINST;
877
878 /* Return the root device for non existing devices */
879 if (!IsPresentDeviceInstanceID(pDeviceID))
880 {
881 if ((wcslen(szRootDeviceInstanceID) + 1) > *pulLength)
882 {
883 *pulLength = wcslen(szRootDeviceInstanceID) + 1;
884 return CR_BUFFER_SMALL;
885 }
886
887 wcscpy(pRelatedDeviceId, szRootDeviceInstanceID);
888 *pulLength = wcslen(szRootDeviceInstanceID) + 1;
889 return CR_SUCCESS;
890 }
891 }
892 else if (ulRelationship == PNP_GET_SIBLING_DEVICE_INSTANCE)
893 {
894 /* The root device does not have siblings */
895 if (IsRootDeviceInstanceID(pDeviceID))
896 return CR_NO_SUCH_DEVINST;
897 }
898
899 RtlInitUnicodeString(&PlugPlayData.TargetDeviceInstance,
900 pDeviceID);
901
902 PlugPlayData.Relation = ulRelationship;
903
904 PlugPlayData.RelatedDeviceInstanceLength = *pulLength;
905 PlugPlayData.RelatedDeviceInstance = pRelatedDeviceId;
906
907 Status = NtPlugPlayControl(PlugPlayControlGetRelatedDevice,
908 (PVOID)&PlugPlayData,
909 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA));
910 if (!NT_SUCCESS(Status))
911 {
912 ret = NtStatusToCrError(Status);
913 }
914
915 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret);
916 if (ret == CR_SUCCESS)
917 {
918 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData.RelatedDeviceInstance);
919 }
920
921 return ret;
922 }
923
924
925 /* Function 9 */
926 DWORD
927 WINAPI
PNP_EnumerateSubKeys(handle_t hBinding,DWORD ulBranch,DWORD ulIndex,LPWSTR Buffer,PNP_RPC_STRING_LEN ulLength,PNP_RPC_STRING_LEN * pulRequiredLen,DWORD ulFlags)928 PNP_EnumerateSubKeys(
929 handle_t hBinding,
930 DWORD ulBranch,
931 DWORD ulIndex,
932 LPWSTR Buffer,
933 PNP_RPC_STRING_LEN ulLength,
934 PNP_RPC_STRING_LEN *pulRequiredLen,
935 DWORD ulFlags)
936 {
937 CONFIGRET ret = CR_SUCCESS;
938 HKEY hKey;
939 DWORD dwError;
940
941 UNREFERENCED_PARAMETER(hBinding);
942 UNREFERENCED_PARAMETER(ulFlags);
943
944 DPRINT("PNP_EnumerateSubKeys(%p %lu %lu %p %lu %p 0x%08lx)\n",
945 hBinding, ulBranch, ulIndex, Buffer, ulLength,
946 pulRequiredLen, ulFlags);
947
948 switch (ulBranch)
949 {
950 case PNP_ENUMERATOR_SUBKEYS:
951 hKey = hEnumKey;
952 break;
953
954 case PNP_CLASS_SUBKEYS:
955 hKey = hClassKey;
956 break;
957
958 default:
959 return CR_FAILURE;
960 }
961
962 *pulRequiredLen = ulLength;
963 dwError = RegEnumKeyExW(hKey,
964 ulIndex,
965 Buffer,
966 pulRequiredLen,
967 NULL,
968 NULL,
969 NULL,
970 NULL);
971 if (dwError != ERROR_SUCCESS)
972 {
973 ret = (dwError == ERROR_NO_MORE_ITEMS) ? CR_NO_SUCH_VALUE : CR_FAILURE;
974 }
975 else
976 {
977 (*pulRequiredLen)++;
978 }
979
980 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret);
981
982 return ret;
983 }
984
985
986 static
987 CONFIGRET
GetRelationsInstanceList(_In_ PWSTR pszDevice,_In_ DWORD ulFlags,_Inout_ PWSTR pszBuffer,_Inout_ PDWORD pulLength)988 GetRelationsInstanceList(
989 _In_ PWSTR pszDevice,
990 _In_ DWORD ulFlags,
991 _Inout_ PWSTR pszBuffer,
992 _Inout_ PDWORD pulLength)
993 {
994 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
995 NTSTATUS Status;
996 CONFIGRET ret = CR_SUCCESS;
997
998 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
999 pszDevice);
1000
1001 if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
1002 {
1003 PlugPlayData.Relations = 3;
1004 }
1005 else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
1006 {
1007 PlugPlayData.Relations = 2;
1008 }
1009 else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
1010 {
1011 PlugPlayData.Relations = 1;
1012 }
1013 else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
1014 {
1015 PlugPlayData.Relations = 0;
1016 }
1017
1018 PlugPlayData.BufferSize = *pulLength * sizeof(WCHAR);
1019 PlugPlayData.Buffer = pszBuffer;
1020
1021 Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations,
1022 (PVOID)&PlugPlayData,
1023 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA));
1024 if (NT_SUCCESS(Status))
1025 {
1026 *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
1027 }
1028 else
1029 {
1030 ret = NtStatusToCrError(Status);
1031 }
1032
1033 return ret;
1034 }
1035
1036
1037 static
1038 CONFIGRET
GetServiceInstanceList(_In_ PWSTR pszService,_Inout_ PWSTR pszBuffer,_Inout_ PDWORD pulLength)1039 GetServiceInstanceList(
1040 _In_ PWSTR pszService,
1041 _Inout_ PWSTR pszBuffer,
1042 _Inout_ PDWORD pulLength)
1043 {
1044 WCHAR szPathBuffer[512];
1045 WCHAR szName[16];
1046 HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL;
1047 DWORD dwValues, dwSize, dwIndex, dwUsedLength, dwPathLength;
1048 DWORD dwError;
1049 PWSTR pPtr;
1050 CONFIGRET ret = CR_SUCCESS;
1051
1052 /* Open the device key */
1053 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1054 L"System\\CurrentControlSet\\Services",
1055 0,
1056 KEY_READ,
1057 &hServicesKey);
1058 if (dwError != ERROR_SUCCESS)
1059 {
1060 DPRINT("Failed to open the services key (Error %lu)\n", dwError);
1061 return CR_REGISTRY_ERROR;
1062 }
1063
1064 dwError = RegOpenKeyExW(hServicesKey,
1065 pszService,
1066 0,
1067 KEY_READ,
1068 &hServiceKey);
1069 if (dwError != ERROR_SUCCESS)
1070 {
1071 DPRINT("Failed to open the service key (Error %lu)\n", dwError);
1072 ret = CR_REGISTRY_ERROR;
1073 goto Done;
1074 }
1075
1076 dwError = RegOpenKeyExW(hServiceKey,
1077 L"Enum",
1078 0,
1079 KEY_READ,
1080 &hEnumKey);
1081 if (dwError != ERROR_SUCCESS)
1082 {
1083 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError);
1084 ret = CR_REGISTRY_ERROR;
1085 goto Done;
1086 }
1087
1088 /* Retrieve the number of device instances */
1089 dwSize = sizeof(DWORD);
1090 dwError = RegQueryValueExW(hEnumKey,
1091 L"Count",
1092 NULL,
1093 NULL,
1094 (LPBYTE)&dwValues,
1095 &dwSize);
1096 if (dwError != ERROR_SUCCESS)
1097 {
1098 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError);
1099 dwValues = 1;
1100 }
1101
1102 DPRINT("dwValues %lu\n", dwValues);
1103
1104 dwUsedLength = 0;
1105 pPtr = pszBuffer;
1106
1107 for (dwIndex = 0; dwIndex < dwValues; dwIndex++)
1108 {
1109 wsprintf(szName, L"%lu", dwIndex);
1110
1111 dwSize = sizeof(szPathBuffer);
1112 dwError = RegQueryValueExW(hEnumKey,
1113 szName,
1114 NULL,
1115 NULL,
1116 (LPBYTE)szPathBuffer,
1117 &dwSize);
1118 if (dwError != ERROR_SUCCESS)
1119 break;
1120
1121 DPRINT("Path: %S\n", szPathBuffer);
1122
1123 dwPathLength = wcslen(szPathBuffer) + 1;
1124 if (dwUsedLength + dwPathLength + 1 > *pulLength)
1125 {
1126 ret = CR_BUFFER_SMALL;
1127 break;
1128 }
1129
1130 wcscpy(pPtr, szPathBuffer);
1131 dwUsedLength += dwPathLength;
1132 pPtr += dwPathLength;
1133
1134 *pPtr = UNICODE_NULL;
1135 }
1136
1137 Done:
1138 if (hEnumKey != NULL)
1139 RegCloseKey(hEnumKey);
1140
1141 if (hServiceKey != NULL)
1142 RegCloseKey(hServiceKey);
1143
1144 if (hServicesKey != NULL)
1145 RegCloseKey(hServicesKey);
1146
1147 if (ret == CR_SUCCESS)
1148 *pulLength = dwUsedLength + 1;
1149 else
1150 *pulLength = 0;
1151
1152 return ret;
1153 }
1154
1155
1156 static
1157 CONFIGRET
GetDeviceInstanceList(_In_ PWSTR pszDevice,_Inout_ PWSTR pszBuffer,_Inout_ PDWORD pulLength)1158 GetDeviceInstanceList(
1159 _In_ PWSTR pszDevice,
1160 _Inout_ PWSTR pszBuffer,
1161 _Inout_ PDWORD pulLength)
1162 {
1163 WCHAR szInstanceBuffer[MAX_DEVICE_ID_LEN];
1164 WCHAR szPathBuffer[512];
1165 HKEY hDeviceKey;
1166 DWORD dwInstanceLength, dwPathLength, dwUsedLength;
1167 DWORD dwIndex, dwError;
1168 PWSTR pPtr;
1169 CONFIGRET ret = CR_SUCCESS;
1170
1171 /* Open the device key */
1172 dwError = RegOpenKeyExW(hEnumKey,
1173 pszDevice,
1174 0,
1175 KEY_ENUMERATE_SUB_KEYS,
1176 &hDeviceKey);
1177 if (dwError != ERROR_SUCCESS)
1178 {
1179 DPRINT("Failed to open the device key (Error %lu)\n", dwError);
1180 return CR_REGISTRY_ERROR;
1181 }
1182
1183 dwUsedLength = 0;
1184 pPtr = pszBuffer;
1185
1186 for (dwIndex = 0; ; dwIndex++)
1187 {
1188 dwInstanceLength = MAX_DEVICE_ID_LEN;
1189 dwError = RegEnumKeyExW(hDeviceKey,
1190 dwIndex,
1191 szInstanceBuffer,
1192 &dwInstanceLength,
1193 NULL,
1194 NULL,
1195 NULL,
1196 NULL);
1197 if (dwError != ERROR_SUCCESS)
1198 break;
1199
1200 wsprintf(szPathBuffer, L"%s\\%s", pszDevice, szInstanceBuffer);
1201 DPRINT("Path: %S\n", szPathBuffer);
1202
1203 dwPathLength = wcslen(szPathBuffer) + 1;
1204 if (dwUsedLength + dwPathLength + 1 > *pulLength)
1205 {
1206 ret = CR_BUFFER_SMALL;
1207 break;
1208 }
1209
1210 wcscpy(pPtr, szPathBuffer);
1211 dwUsedLength += dwPathLength;
1212 pPtr += dwPathLength;
1213
1214 *pPtr = UNICODE_NULL;
1215 }
1216
1217 RegCloseKey(hDeviceKey);
1218
1219 if (ret == CR_SUCCESS)
1220 *pulLength = dwUsedLength + 1;
1221 else
1222 *pulLength = 0;
1223
1224 return ret;
1225 }
1226
1227
1228 CONFIGRET
GetEnumeratorInstanceList(_In_ PWSTR pszEnumerator,_Inout_ PWSTR pszBuffer,_Inout_ PDWORD pulLength)1229 GetEnumeratorInstanceList(
1230 _In_ PWSTR pszEnumerator,
1231 _Inout_ PWSTR pszBuffer,
1232 _Inout_ PDWORD pulLength)
1233 {
1234 WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN];
1235 WCHAR szPathBuffer[512];
1236 HKEY hEnumeratorKey;
1237 PWSTR pPtr;
1238 DWORD dwIndex, dwDeviceLength, dwUsedLength, dwRemainingLength, dwPathLength;
1239 DWORD dwError;
1240 CONFIGRET ret = CR_SUCCESS;
1241
1242 /* Open the enumerator key */
1243 dwError = RegOpenKeyExW(hEnumKey,
1244 pszEnumerator,
1245 0,
1246 KEY_ENUMERATE_SUB_KEYS,
1247 &hEnumeratorKey);
1248 if (dwError != ERROR_SUCCESS)
1249 {
1250 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError);
1251 return CR_REGISTRY_ERROR;
1252 }
1253
1254 dwUsedLength = 0;
1255 dwRemainingLength = *pulLength;
1256 pPtr = pszBuffer;
1257
1258 for (dwIndex = 0; ; dwIndex++)
1259 {
1260 dwDeviceLength = MAX_DEVICE_ID_LEN;
1261 dwError = RegEnumKeyExW(hEnumeratorKey,
1262 dwIndex,
1263 szDeviceBuffer,
1264 &dwDeviceLength,
1265 NULL,
1266 NULL,
1267 NULL,
1268 NULL);
1269 if (dwError != ERROR_SUCCESS)
1270 break;
1271
1272 wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer);
1273 DPRINT("Path: %S\n", szPathBuffer);
1274
1275 dwPathLength = dwRemainingLength;
1276 ret = GetDeviceInstanceList(szPathBuffer,
1277 pPtr,
1278 &dwPathLength);
1279 if (ret != CR_SUCCESS)
1280 break;
1281
1282 dwUsedLength += dwPathLength - 1;
1283 dwRemainingLength -= dwPathLength - 1;
1284 pPtr += dwPathLength - 1;
1285 }
1286
1287 RegCloseKey(hEnumeratorKey);
1288
1289 if (ret == CR_SUCCESS)
1290 *pulLength = dwUsedLength + 1;
1291 else
1292 *pulLength = 0;
1293
1294 return ret;
1295 }
1296
1297
1298 static
1299 CONFIGRET
GetAllInstanceList(_Inout_ PWSTR pszBuffer,_Inout_ PDWORD pulLength)1300 GetAllInstanceList(
1301 _Inout_ PWSTR pszBuffer,
1302 _Inout_ PDWORD pulLength)
1303 {
1304 WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN];
1305 PWSTR pPtr;
1306 DWORD dwIndex, dwEnumeratorLength, dwUsedLength, dwRemainingLength, dwPathLength;
1307 DWORD dwError;
1308 CONFIGRET ret = CR_SUCCESS;
1309
1310 dwUsedLength = 0;
1311 dwRemainingLength = *pulLength;
1312 pPtr = pszBuffer;
1313
1314 for (dwIndex = 0; ; dwIndex++)
1315 {
1316 dwEnumeratorLength = MAX_DEVICE_ID_LEN;
1317 dwError = RegEnumKeyExW(hEnumKey,
1318 dwIndex,
1319 szEnumeratorBuffer,
1320 &dwEnumeratorLength,
1321 NULL, NULL, NULL, NULL);
1322 if (dwError != ERROR_SUCCESS)
1323 break;
1324
1325 dwPathLength = dwRemainingLength;
1326 ret = GetEnumeratorInstanceList(szEnumeratorBuffer,
1327 pPtr,
1328 &dwPathLength);
1329 if (ret != CR_SUCCESS)
1330 break;
1331
1332 dwUsedLength += dwPathLength - 1;
1333 dwRemainingLength -= dwPathLength - 1;
1334 pPtr += dwPathLength - 1;
1335 }
1336
1337 if (ret == CR_SUCCESS)
1338 *pulLength = dwUsedLength + 1;
1339 else
1340 *pulLength = 0;
1341
1342 return ret;
1343 }
1344
1345
1346 /* Function 10 */
1347 DWORD
1348 WINAPI
PNP_GetDeviceList(handle_t hBinding,LPWSTR pszFilter,LPWSTR Buffer,PNP_RPC_STRING_LEN * pulLength,DWORD ulFlags)1349 PNP_GetDeviceList(
1350 handle_t hBinding,
1351 LPWSTR pszFilter,
1352 LPWSTR Buffer,
1353 PNP_RPC_STRING_LEN *pulLength,
1354 DWORD ulFlags)
1355 {
1356 WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
1357 WCHAR szDevice[MAX_DEVICE_ID_LEN];
1358 WCHAR szInstance[MAX_DEVICE_ID_LEN];
1359 CONFIGRET ret = CR_SUCCESS;
1360
1361 DPRINT("PNP_GetDeviceList(%p %S %p %p 0x%08lx)\n",
1362 hBinding, pszFilter, Buffer, pulLength, ulFlags);
1363
1364 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
1365 return CR_INVALID_FLAG;
1366
1367 if (pulLength == NULL)
1368 return CR_INVALID_POINTER;
1369
1370 if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
1371 (pszFilter == NULL))
1372 return CR_INVALID_POINTER;
1373
1374 if (ulFlags &
1375 (CM_GETIDLIST_FILTER_BUSRELATIONS |
1376 CM_GETIDLIST_FILTER_POWERRELATIONS |
1377 CM_GETIDLIST_FILTER_REMOVALRELATIONS |
1378 CM_GETIDLIST_FILTER_EJECTRELATIONS))
1379 {
1380 ret = GetRelationsInstanceList(pszFilter,
1381 ulFlags,
1382 Buffer,
1383 pulLength);
1384 }
1385 else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
1386 {
1387 ret = GetServiceInstanceList(pszFilter,
1388 Buffer,
1389 pulLength);
1390 }
1391 else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
1392 {
1393 SplitDeviceInstanceID(pszFilter,
1394 szEnumerator,
1395 szDevice,
1396 szInstance);
1397
1398 if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
1399 {
1400 ret = GetDeviceInstanceList(pszFilter,
1401 Buffer,
1402 pulLength);
1403 }
1404 else
1405 {
1406 ret = GetEnumeratorInstanceList(pszFilter,
1407 Buffer,
1408 pulLength);
1409 }
1410 }
1411 else /* CM_GETIDLIST_FILTER_NONE */
1412 {
1413 ret = GetAllInstanceList(Buffer,
1414 pulLength);
1415 }
1416
1417 return ret;
1418 }
1419
1420
1421 static
1422 CONFIGRET
GetRelationsInstanceListSize(_In_ PWSTR pszDevice,_In_ DWORD ulFlags,_Inout_ PDWORD pulLength)1423 GetRelationsInstanceListSize(
1424 _In_ PWSTR pszDevice,
1425 _In_ DWORD ulFlags,
1426 _Inout_ PDWORD pulLength)
1427 {
1428 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
1429 NTSTATUS Status;
1430 CONFIGRET ret = CR_SUCCESS;
1431
1432 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
1433 pszDevice);
1434
1435 if (ulFlags & CM_GETIDLIST_FILTER_BUSRELATIONS)
1436 {
1437 PlugPlayData.Relations = 3;
1438 }
1439 else if (ulFlags & CM_GETIDLIST_FILTER_POWERRELATIONS)
1440 {
1441 PlugPlayData.Relations = 2;
1442 }
1443 else if (ulFlags & CM_GETIDLIST_FILTER_REMOVALRELATIONS)
1444 {
1445 PlugPlayData.Relations = 1;
1446 }
1447 else if (ulFlags & CM_GETIDLIST_FILTER_EJECTRELATIONS)
1448 {
1449 PlugPlayData.Relations = 0;
1450 }
1451
1452 PlugPlayData.BufferSize = 0;
1453 PlugPlayData.Buffer = NULL;
1454
1455 Status = NtPlugPlayControl(PlugPlayControlQueryDeviceRelations,
1456 (PVOID)&PlugPlayData,
1457 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA));
1458 if (NT_SUCCESS(Status))
1459 {
1460 *pulLength = PlugPlayData.BufferSize / sizeof(WCHAR);
1461 }
1462 else
1463 {
1464 ret = NtStatusToCrError(Status);
1465 }
1466
1467 return ret;
1468 }
1469
1470
1471 static
1472 CONFIGRET
GetServiceInstanceListSize(_In_ PWSTR pszService,_Out_ PDWORD pulLength)1473 GetServiceInstanceListSize(
1474 _In_ PWSTR pszService,
1475 _Out_ PDWORD pulLength)
1476 {
1477 HKEY hServicesKey = NULL, hServiceKey = NULL, hEnumKey = NULL;
1478 DWORD dwValues, dwMaxValueLength, dwSize;
1479 DWORD dwError;
1480 CONFIGRET ret = CR_SUCCESS;
1481
1482 /* Open the device key */
1483 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1484 L"System\\CurrentControlSet\\Services",
1485 0,
1486 KEY_READ,
1487 &hServicesKey);
1488 if (dwError != ERROR_SUCCESS)
1489 {
1490 DPRINT("Failed to open the services key (Error %lu)\n", dwError);
1491 return CR_REGISTRY_ERROR;
1492 }
1493
1494 dwError = RegOpenKeyExW(hServicesKey,
1495 pszService,
1496 0,
1497 KEY_READ,
1498 &hServiceKey);
1499 if (dwError != ERROR_SUCCESS)
1500 {
1501 DPRINT("Failed to open the service key (Error %lu)\n", dwError);
1502 ret = CR_REGISTRY_ERROR;
1503 goto Done;
1504 }
1505
1506 dwError = RegOpenKeyExW(hServiceKey,
1507 L"Enum",
1508 0,
1509 KEY_READ,
1510 &hEnumKey);
1511 if (dwError != ERROR_SUCCESS)
1512 {
1513 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError);
1514 ret = CR_REGISTRY_ERROR;
1515 goto Done;
1516 }
1517
1518 /* Retrieve the number of device instances */
1519 dwSize = sizeof(DWORD);
1520 dwError = RegQueryValueExW(hEnumKey,
1521 L"Count",
1522 NULL,
1523 NULL,
1524 (LPBYTE)&dwValues,
1525 &dwSize);
1526 if (dwError != ERROR_SUCCESS)
1527 {
1528 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError);
1529 dwValues = 1;
1530 }
1531
1532 /* Retrieve the maximum instance name length */
1533 dwError = RegQueryInfoKeyW(hEnumKey,
1534 NULL,
1535 NULL,
1536 NULL,
1537 NULL,
1538 NULL,
1539 NULL,
1540 NULL,
1541 NULL,
1542 &dwMaxValueLength,
1543 NULL,
1544 NULL);
1545 if (dwError != ERROR_SUCCESS)
1546 {
1547 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
1548 dwMaxValueLength = MAX_DEVICE_ID_LEN;
1549 }
1550
1551 DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues, dwMaxValueLength / sizeof(WCHAR));
1552
1553 /* Return the largest possible buffer size */
1554 *pulLength = dwValues * dwMaxValueLength / sizeof(WCHAR) + 2;
1555
1556 Done:
1557 if (hEnumKey != NULL)
1558 RegCloseKey(hEnumKey);
1559
1560 if (hServiceKey != NULL)
1561 RegCloseKey(hServiceKey);
1562
1563 if (hServicesKey != NULL)
1564 RegCloseKey(hServicesKey);
1565
1566 return ret;
1567 }
1568
1569
1570 static
1571 CONFIGRET
GetDeviceInstanceListSize(_In_ LPCWSTR pszDevice,_Out_ PULONG pulLength)1572 GetDeviceInstanceListSize(
1573 _In_ LPCWSTR pszDevice,
1574 _Out_ PULONG pulLength)
1575 {
1576 HKEY hDeviceKey;
1577 DWORD dwSubKeys, dwMaxSubKeyLength;
1578 DWORD dwError;
1579
1580 /* Open the device key */
1581 dwError = RegOpenKeyExW(hEnumKey,
1582 pszDevice,
1583 0,
1584 KEY_READ,
1585 &hDeviceKey);
1586 if (dwError != ERROR_SUCCESS)
1587 {
1588 DPRINT("Failed to open the device key (Error %lu)\n", dwError);
1589 return CR_REGISTRY_ERROR;
1590 }
1591
1592 /* Retrieve the number of device instances and the maximum name length */
1593 dwError = RegQueryInfoKeyW(hDeviceKey,
1594 NULL,
1595 NULL,
1596 NULL,
1597 &dwSubKeys,
1598 &dwMaxSubKeyLength,
1599 NULL,
1600 NULL,
1601 NULL,
1602 NULL,
1603 NULL,
1604 NULL);
1605 if (dwError != ERROR_SUCCESS)
1606 {
1607 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
1608 dwSubKeys = 0;
1609 dwMaxSubKeyLength = 0;
1610 }
1611
1612 /* Close the device key */
1613 RegCloseKey(hDeviceKey);
1614
1615 /* Return the largest possible buffer size */
1616 *pulLength = dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1);
1617
1618 return CR_SUCCESS;
1619 }
1620
1621
1622 static
1623 CONFIGRET
GetEnumeratorInstanceListSize(_In_ LPCWSTR pszEnumerator,_Out_ PULONG pulLength)1624 GetEnumeratorInstanceListSize(
1625 _In_ LPCWSTR pszEnumerator,
1626 _Out_ PULONG pulLength)
1627 {
1628 WCHAR szDeviceBuffer[MAX_DEVICE_ID_LEN];
1629 WCHAR szPathBuffer[512];
1630 HKEY hEnumeratorKey;
1631 DWORD dwIndex, dwDeviceLength, dwBufferLength;
1632 DWORD dwError;
1633 CONFIGRET ret = CR_SUCCESS;
1634
1635 *pulLength = 0;
1636
1637 /* Open the enumerator key */
1638 dwError = RegOpenKeyExW(hEnumKey,
1639 pszEnumerator,
1640 0,
1641 KEY_ENUMERATE_SUB_KEYS,
1642 &hEnumeratorKey);
1643 if (dwError != ERROR_SUCCESS)
1644 {
1645 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError);
1646 return CR_REGISTRY_ERROR;
1647 }
1648
1649 for (dwIndex = 0; ; dwIndex++)
1650 {
1651 dwDeviceLength = MAX_DEVICE_ID_LEN;
1652 dwError = RegEnumKeyExW(hEnumeratorKey,
1653 dwIndex,
1654 szDeviceBuffer,
1655 &dwDeviceLength,
1656 NULL,
1657 NULL,
1658 NULL,
1659 NULL);
1660 if (dwError != ERROR_SUCCESS)
1661 break;
1662
1663 wsprintf(szPathBuffer, L"%s\\%s", pszEnumerator, szDeviceBuffer);
1664 DPRINT("Path: %S\n", szPathBuffer);
1665
1666 ret = GetDeviceInstanceListSize(szPathBuffer, &dwBufferLength);
1667 if (ret != CR_SUCCESS)
1668 {
1669 *pulLength = 0;
1670 break;
1671 }
1672
1673 *pulLength += dwBufferLength;
1674 }
1675
1676 /* Close the enumerator key */
1677 RegCloseKey(hEnumeratorKey);
1678
1679 return ret;
1680 }
1681
1682
1683 static
1684 CONFIGRET
GetAllInstanceListSize(_Out_ PULONG pulLength)1685 GetAllInstanceListSize(
1686 _Out_ PULONG pulLength)
1687 {
1688 WCHAR szEnumeratorBuffer[MAX_DEVICE_ID_LEN];
1689 DWORD dwIndex, dwEnumeratorLength, dwBufferLength;
1690 DWORD dwError;
1691 CONFIGRET ret = CR_SUCCESS;
1692
1693 for (dwIndex = 0; ; dwIndex++)
1694 {
1695 dwEnumeratorLength = MAX_DEVICE_ID_LEN;
1696 dwError = RegEnumKeyExW(hEnumKey,
1697 dwIndex,
1698 szEnumeratorBuffer,
1699 &dwEnumeratorLength,
1700 NULL, NULL, NULL, NULL);
1701 if (dwError != ERROR_SUCCESS)
1702 break;
1703
1704 /* Get the size of all device instances for the enumerator */
1705 ret = GetEnumeratorInstanceListSize(szEnumeratorBuffer,
1706 &dwBufferLength);
1707 if (ret != CR_SUCCESS)
1708 break;
1709
1710 *pulLength += dwBufferLength;
1711 }
1712
1713 return ret;
1714 }
1715
1716
1717 /* Function 11 */
1718 DWORD
1719 WINAPI
PNP_GetDeviceListSize(handle_t hBinding,LPWSTR pszFilter,PNP_RPC_BUFFER_SIZE * pulLength,DWORD ulFlags)1720 PNP_GetDeviceListSize(
1721 handle_t hBinding,
1722 LPWSTR pszFilter,
1723 PNP_RPC_BUFFER_SIZE *pulLength,
1724 DWORD ulFlags)
1725 {
1726 WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
1727 WCHAR szDevice[MAX_DEVICE_ID_LEN];
1728 WCHAR szInstance[MAX_DEVICE_ID_LEN];
1729 CONFIGRET ret = CR_SUCCESS;
1730
1731 DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%08lx)\n",
1732 hBinding, pszFilter, pulLength, ulFlags);
1733
1734 if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
1735 return CR_INVALID_FLAG;
1736
1737 if (pulLength == NULL)
1738 return CR_INVALID_POINTER;
1739
1740 if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
1741 (pszFilter == NULL))
1742 return CR_INVALID_POINTER;
1743
1744 *pulLength = 0;
1745
1746 if (ulFlags &
1747 (CM_GETIDLIST_FILTER_BUSRELATIONS |
1748 CM_GETIDLIST_FILTER_POWERRELATIONS |
1749 CM_GETIDLIST_FILTER_REMOVALRELATIONS |
1750 CM_GETIDLIST_FILTER_EJECTRELATIONS))
1751 {
1752 ret = GetRelationsInstanceListSize(pszFilter,
1753 ulFlags,
1754 pulLength);
1755 }
1756 else if (ulFlags & CM_GETIDLIST_FILTER_SERVICE)
1757 {
1758 ret = GetServiceInstanceListSize(pszFilter,
1759 pulLength);
1760 }
1761 else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
1762 {
1763 SplitDeviceInstanceID(pszFilter,
1764 szEnumerator,
1765 szDevice,
1766 szInstance);
1767
1768 if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
1769 {
1770 ret = GetDeviceInstanceListSize(pszFilter,
1771 pulLength);
1772 }
1773 else
1774 {
1775 ret = GetEnumeratorInstanceListSize(pszFilter,
1776 pulLength);
1777 }
1778 }
1779 else /* CM_GETIDLIST_FILTER_NONE */
1780 {
1781 ret = GetAllInstanceListSize(pulLength);
1782 }
1783
1784 /* Add one character for the terminating double UNICODE_NULL */
1785 if (ret == CR_SUCCESS)
1786 (*pulLength) += 1;
1787
1788 return ret;
1789 }
1790
1791
1792 /* Function 12 */
1793 DWORD
1794 WINAPI
PNP_GetDepth(handle_t hBinding,LPWSTR pszDeviceID,DWORD * pulDepth,DWORD ulFlags)1795 PNP_GetDepth(
1796 handle_t hBinding,
1797 LPWSTR pszDeviceID,
1798 DWORD *pulDepth,
1799 DWORD ulFlags)
1800 {
1801 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData;
1802 CONFIGRET ret = CR_SUCCESS;
1803 NTSTATUS Status;
1804
1805 UNREFERENCED_PARAMETER(hBinding);
1806 UNREFERENCED_PARAMETER(ulFlags);
1807
1808 DPRINT("PNP_GetDepth(%p %S %p 0x%08lx)\n",
1809 hBinding, pszDeviceID, pulDepth, ulFlags);
1810
1811 if (!IsValidDeviceInstanceID(pszDeviceID))
1812 return CR_INVALID_DEVINST;
1813
1814 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
1815 pszDeviceID);
1816
1817 Status = NtPlugPlayControl(PlugPlayControlGetDeviceDepth,
1818 (PVOID)&PlugPlayData,
1819 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA));
1820 if (NT_SUCCESS(Status))
1821 {
1822 *pulDepth = PlugPlayData.Depth;
1823 }
1824 else
1825 {
1826 ret = NtStatusToCrError(Status);
1827 }
1828
1829 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret);
1830
1831 return ret;
1832 }
1833
1834
1835 /* Function 13 */
1836 DWORD
1837 WINAPI
PNP_GetDeviceRegProp(handle_t hBinding,LPWSTR pDeviceID,DWORD ulProperty,DWORD * pulRegDataType,BYTE * Buffer,PNP_PROP_SIZE * pulTransferLen,PNP_PROP_SIZE * pulLength,DWORD ulFlags)1838 PNP_GetDeviceRegProp(
1839 handle_t hBinding,
1840 LPWSTR pDeviceID,
1841 DWORD ulProperty,
1842 DWORD *pulRegDataType,
1843 BYTE *Buffer,
1844 PNP_PROP_SIZE *pulTransferLen,
1845 PNP_PROP_SIZE *pulLength,
1846 DWORD ulFlags)
1847 {
1848 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData;
1849 CONFIGRET ret = CR_SUCCESS;
1850 LPWSTR lpValueName = NULL;
1851 HKEY hKey = NULL;
1852 LONG lError;
1853 NTSTATUS Status;
1854
1855 UNREFERENCED_PARAMETER(hBinding);
1856
1857 DPRINT("PNP_GetDeviceRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
1858 hBinding, pDeviceID, ulProperty, pulRegDataType, Buffer,
1859 pulTransferLen, pulLength, ulFlags);
1860
1861 if (pulTransferLen == NULL || pulLength == NULL)
1862 {
1863 ret = CR_INVALID_POINTER;
1864 goto done;
1865 }
1866
1867 if (ulFlags != 0)
1868 {
1869 ret = CR_INVALID_FLAG;
1870 goto done;
1871 }
1872
1873 /* Check pDeviceID */
1874 if (!IsValidDeviceInstanceID(pDeviceID))
1875 {
1876 ret = CR_INVALID_DEVINST;
1877 goto done;
1878 }
1879
1880 if (*pulLength < *pulTransferLen)
1881 *pulLength = *pulTransferLen;
1882
1883 *pulTransferLen = 0;
1884
1885 switch (ulProperty)
1886 {
1887 case CM_DRP_DEVICEDESC:
1888 lpValueName = L"DeviceDesc";
1889 break;
1890
1891 case CM_DRP_HARDWAREID:
1892 lpValueName = L"HardwareID";
1893 break;
1894
1895 case CM_DRP_COMPATIBLEIDS:
1896 lpValueName = L"CompatibleIDs";
1897 break;
1898
1899 case CM_DRP_SERVICE:
1900 lpValueName = L"Service";
1901 break;
1902
1903 case CM_DRP_CLASS:
1904 lpValueName = L"Class";
1905 break;
1906
1907 case CM_DRP_CLASSGUID:
1908 lpValueName = L"ClassGUID";
1909 break;
1910
1911 case CM_DRP_DRIVER:
1912 lpValueName = L"Driver";
1913 break;
1914
1915 case CM_DRP_CONFIGFLAGS:
1916 lpValueName = L"ConfigFlags";
1917 break;
1918
1919 case CM_DRP_MFG:
1920 lpValueName = L"Mfg";
1921 break;
1922
1923 case CM_DRP_FRIENDLYNAME:
1924 lpValueName = L"FriendlyName";
1925 break;
1926
1927 case CM_DRP_LOCATION_INFORMATION:
1928 lpValueName = L"LocationInformation";
1929 break;
1930
1931 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME:
1932 PlugPlayData.Property = PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME;
1933 *pulRegDataType = REG_SZ;
1934 break;
1935
1936 case CM_DRP_CAPABILITIES:
1937 lpValueName = L"Capabilities";
1938 break;
1939
1940 case CM_DRP_UI_NUMBER:
1941 PlugPlayData.Property = PNP_PROPERTY_UI_NUMBER;
1942 break;
1943
1944 case CM_DRP_UPPERFILTERS:
1945 lpValueName = L"UpperFilters";
1946 break;
1947
1948 case CM_DRP_LOWERFILTERS:
1949 lpValueName = L"LowerFilters";
1950 break;
1951
1952 case CM_DRP_BUSTYPEGUID:
1953 PlugPlayData.Property = PNP_PROPERTY_BUSTYPEGUID;
1954 *pulRegDataType = REG_BINARY;
1955 break;
1956
1957 case CM_DRP_LEGACYBUSTYPE:
1958 PlugPlayData.Property = PNP_PROPERTY_LEGACYBUSTYPE;
1959 *pulRegDataType = REG_DWORD;
1960 break;
1961
1962 case CM_DRP_BUSNUMBER:
1963 PlugPlayData.Property = PNP_PROPERTY_BUSNUMBER;
1964 *pulRegDataType = REG_DWORD;
1965 break;
1966
1967 case CM_DRP_ENUMERATOR_NAME:
1968 PlugPlayData.Property = PNP_PROPERTY_ENUMERATOR_NAME;
1969 *pulRegDataType = REG_SZ;
1970 break;
1971
1972 case CM_DRP_SECURITY:
1973 lpValueName = L"Security";
1974 break;
1975
1976 case CM_DRP_DEVTYPE:
1977 lpValueName = L"DeviceType";
1978 break;
1979
1980 case CM_DRP_EXCLUSIVE:
1981 lpValueName = L"Exclusive";
1982 break;
1983
1984 case CM_DRP_CHARACTERISTICS:
1985 lpValueName = L"DeviceCharacteristics";
1986 break;
1987
1988 case CM_DRP_ADDRESS:
1989 PlugPlayData.Property = PNP_PROPERTY_ADDRESS;
1990 *pulRegDataType = REG_DWORD;
1991 break;
1992
1993 case CM_DRP_UI_NUMBER_DESC_FORMAT:
1994 lpValueName = L"UINumberDescFormat";
1995 break;
1996
1997 case CM_DRP_DEVICE_POWER_DATA:
1998 PlugPlayData.Property = PNP_PROPERTY_POWER_DATA;
1999 *pulRegDataType = REG_BINARY;
2000 break;
2001
2002 case CM_DRP_REMOVAL_POLICY:
2003 PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY;
2004 *pulRegDataType = REG_DWORD;
2005 break;
2006
2007 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT:
2008 PlugPlayData.Property = PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT;
2009 *pulRegDataType = REG_DWORD;
2010 break;
2011
2012 case CM_DRP_REMOVAL_POLICY_OVERRIDE:
2013 lpValueName = L"RemovalPolicy";
2014 *pulRegDataType = REG_DWORD;
2015 break;
2016
2017 case CM_DRP_INSTALL_STATE:
2018 PlugPlayData.Property = PNP_PROPERTY_INSTALL_STATE;
2019 *pulRegDataType = REG_DWORD;
2020 break;
2021
2022 #if (WINVER >= _WIN32_WINNT_WS03)
2023 case CM_DRP_LOCATION_PATHS:
2024 PlugPlayData.Property = PNP_PROPERTY_LOCATION_PATHS;
2025 *pulRegDataType = REG_MULTI_SZ;
2026 break;
2027 #endif
2028
2029 #if (WINVER >= _WIN32_WINNT_WIN7)
2030 case CM_DRP_BASE_CONTAINERID:
2031 PlugPlayData.Property = PNP_PROPERTY_CONTAINERID;
2032 *pulRegDataType = REG_SZ;
2033 break;
2034 #endif
2035
2036 default:
2037 ret = CR_INVALID_PROPERTY;
2038 goto done;
2039 }
2040
2041 DPRINT("Value name: %S\n", lpValueName);
2042
2043 if (lpValueName)
2044 {
2045 /* Retrieve information from the Registry */
2046 lError = RegOpenKeyExW(hEnumKey,
2047 pDeviceID,
2048 0,
2049 KEY_QUERY_VALUE,
2050 &hKey);
2051 if (lError != ERROR_SUCCESS)
2052 {
2053 hKey = NULL;
2054 *pulLength = 0;
2055 ret = CR_INVALID_DEVNODE;
2056 goto done;
2057 }
2058
2059 lError = RegQueryValueExW(hKey,
2060 lpValueName,
2061 NULL,
2062 pulRegDataType,
2063 Buffer,
2064 pulLength);
2065 if (lError != ERROR_SUCCESS)
2066 {
2067 if (lError == ERROR_MORE_DATA)
2068 {
2069 ret = CR_BUFFER_SMALL;
2070 }
2071 else
2072 {
2073 *pulLength = 0;
2074 ret = CR_NO_SUCH_VALUE;
2075 }
2076 }
2077 }
2078 else
2079 {
2080 /* Retrieve information from the Device Node */
2081 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2082 pDeviceID);
2083 PlugPlayData.Buffer = Buffer;
2084 PlugPlayData.BufferSize = *pulLength;
2085
2086 Status = NtPlugPlayControl(PlugPlayControlProperty,
2087 (PVOID)&PlugPlayData,
2088 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA));
2089 if (NT_SUCCESS(Status))
2090 {
2091 *pulLength = PlugPlayData.BufferSize;
2092 }
2093 else
2094 {
2095 ret = NtStatusToCrError(Status);
2096 }
2097 }
2098
2099 done:
2100 if (pulTransferLen)
2101 *pulTransferLen = (ret == CR_SUCCESS) ? *pulLength : 0;
2102
2103 if (hKey != NULL)
2104 RegCloseKey(hKey);
2105
2106 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret);
2107
2108 return ret;
2109 }
2110
2111
2112 /* Function 14 */
2113 DWORD
2114 WINAPI
PNP_SetDeviceRegProp(handle_t hBinding,LPWSTR pDeviceId,DWORD ulProperty,DWORD ulDataType,BYTE * Buffer,PNP_PROP_SIZE ulLength,DWORD ulFlags)2115 PNP_SetDeviceRegProp(
2116 handle_t hBinding,
2117 LPWSTR pDeviceId,
2118 DWORD ulProperty,
2119 DWORD ulDataType,
2120 BYTE *Buffer,
2121 PNP_PROP_SIZE ulLength,
2122 DWORD ulFlags)
2123 {
2124 CONFIGRET ret = CR_SUCCESS;
2125 LPWSTR lpValueName = NULL;
2126 HKEY hKey = 0;
2127
2128 UNREFERENCED_PARAMETER(hBinding);
2129 UNREFERENCED_PARAMETER(ulFlags);
2130
2131 DPRINT("PNP_SetDeviceRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2132 hBinding, pDeviceId, ulProperty, ulDataType, Buffer,
2133 ulLength, ulFlags);
2134
2135 if (!IsValidDeviceInstanceID(pDeviceId))
2136 return CR_INVALID_DEVINST;
2137
2138 switch (ulProperty)
2139 {
2140 case CM_DRP_DEVICEDESC:
2141 lpValueName = L"DeviceDesc";
2142 break;
2143
2144 case CM_DRP_HARDWAREID:
2145 lpValueName = L"HardwareID";
2146 break;
2147
2148 case CM_DRP_COMPATIBLEIDS:
2149 lpValueName = L"CompatibleIDs";
2150 break;
2151
2152 case CM_DRP_SERVICE:
2153 lpValueName = L"Service";
2154 break;
2155
2156 case CM_DRP_CLASS:
2157 lpValueName = L"Class";
2158 break;
2159
2160 case CM_DRP_CLASSGUID:
2161 lpValueName = L"ClassGUID";
2162 break;
2163
2164 case CM_DRP_DRIVER:
2165 lpValueName = L"Driver";
2166 break;
2167
2168 case CM_DRP_CONFIGFLAGS:
2169 lpValueName = L"ConfigFlags";
2170 break;
2171
2172 case CM_DRP_MFG:
2173 lpValueName = L"Mfg";
2174 break;
2175
2176 case CM_DRP_FRIENDLYNAME:
2177 lpValueName = L"FriendlyName";
2178 break;
2179
2180 case CM_DRP_LOCATION_INFORMATION:
2181 lpValueName = L"LocationInformation";
2182 break;
2183
2184 case CM_DRP_UPPERFILTERS:
2185 lpValueName = L"UpperFilters";
2186 break;
2187
2188 case CM_DRP_LOWERFILTERS:
2189 lpValueName = L"LowerFilters";
2190 break;
2191
2192 case CM_DRP_SECURITY:
2193 lpValueName = L"Security";
2194 break;
2195
2196 case CM_DRP_DEVTYPE:
2197 lpValueName = L"DeviceType";
2198 break;
2199
2200 case CM_DRP_EXCLUSIVE:
2201 lpValueName = L"Exclusive";
2202 break;
2203
2204 case CM_DRP_CHARACTERISTICS:
2205 lpValueName = L"DeviceCharacteristics";
2206 break;
2207
2208 case CM_DRP_UI_NUMBER_DESC_FORMAT:
2209 lpValueName = L"UINumberDescFormat";
2210 break;
2211
2212 case CM_DRP_REMOVAL_POLICY_OVERRIDE:
2213 lpValueName = L"RemovalPolicy";
2214 break;
2215
2216 default:
2217 return CR_INVALID_PROPERTY;
2218 }
2219
2220 DPRINT("Value name: %S\n", lpValueName);
2221
2222 if (RegOpenKeyExW(hEnumKey,
2223 pDeviceId,
2224 0,
2225 KEY_SET_VALUE,
2226 &hKey))
2227 return CR_INVALID_DEVNODE;
2228
2229 if (ulLength == 0)
2230 {
2231 if (RegDeleteValueW(hKey,
2232 lpValueName))
2233 ret = CR_REGISTRY_ERROR;
2234 }
2235 else
2236 {
2237 if (RegSetValueExW(hKey,
2238 lpValueName,
2239 0,
2240 ulDataType,
2241 Buffer,
2242 ulLength))
2243 ret = CR_REGISTRY_ERROR;
2244 }
2245
2246 RegCloseKey(hKey);
2247
2248 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret);
2249
2250 return ret;
2251 }
2252
2253
2254 /* Function 15 */
2255 DWORD
2256 WINAPI
PNP_GetClassInstance(handle_t hBinding,LPWSTR pDeviceId,LPWSTR pszClassInstance,PNP_RPC_STRING_LEN ulLength)2257 PNP_GetClassInstance(
2258 handle_t hBinding,
2259 LPWSTR pDeviceId,
2260 LPWSTR pszClassInstance,
2261 PNP_RPC_STRING_LEN ulLength)
2262 {
2263 WCHAR szClassGuid[40];
2264 WCHAR szClassInstance[5];
2265 HKEY hDeviceClassKey = NULL;
2266 HKEY hClassInstanceKey;
2267 ULONG ulTransferLength, ulDataLength;
2268 DWORD dwDataType, dwDisposition, i;
2269 DWORD dwError;
2270 CONFIGRET ret = CR_SUCCESS;
2271
2272 DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n",
2273 hBinding, pDeviceId, pszClassInstance, ulLength);
2274
2275 if (!IsValidDeviceInstanceID(pDeviceId))
2276 return CR_INVALID_DEVINST;
2277
2278 ulTransferLength = ulLength;
2279 ret = PNP_GetDeviceRegProp(hBinding,
2280 pDeviceId,
2281 CM_DRP_DRIVER,
2282 &dwDataType,
2283 (BYTE *)pszClassInstance,
2284 &ulTransferLength,
2285 &ulLength,
2286 0);
2287 if (ret == CR_SUCCESS)
2288 return ret;
2289
2290 ulTransferLength = sizeof(szClassGuid);
2291 ulDataLength = sizeof(szClassGuid);
2292 ret = PNP_GetDeviceRegProp(hBinding,
2293 pDeviceId,
2294 CM_DRP_CLASSGUID,
2295 &dwDataType,
2296 (BYTE *)szClassGuid,
2297 &ulTransferLength,
2298 &ulDataLength,
2299 0);
2300 if (ret != CR_SUCCESS)
2301 {
2302 DPRINT1("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret);
2303 goto done;
2304 }
2305
2306 dwError = RegOpenKeyExW(hClassKey,
2307 szClassGuid,
2308 0,
2309 KEY_READ,
2310 &hDeviceClassKey);
2311 if (dwError != ERROR_SUCCESS)
2312 {
2313 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
2314 ret = CR_FAILURE;
2315 goto done;
2316 }
2317
2318 for (i = 0; i < 10000; i++)
2319 {
2320 wsprintf(szClassInstance, L"%04lu", i);
2321
2322 dwError = RegCreateKeyExW(hDeviceClassKey,
2323 szClassInstance,
2324 0,
2325 NULL,
2326 REG_OPTION_NON_VOLATILE,
2327 KEY_ALL_ACCESS,
2328 NULL,
2329 &hClassInstanceKey,
2330 &dwDisposition);
2331 if (dwError == ERROR_SUCCESS)
2332 {
2333 RegCloseKey(hClassInstanceKey);
2334
2335 if (dwDisposition == REG_CREATED_NEW_KEY)
2336 {
2337 wsprintf(pszClassInstance,
2338 L"%s\\%s",
2339 szClassGuid,
2340 szClassInstance);
2341
2342 ulDataLength = (wcslen(pszClassInstance) + 1) * sizeof(WCHAR);
2343 ret = PNP_SetDeviceRegProp(hBinding,
2344 pDeviceId,
2345 CM_DRP_DRIVER,
2346 REG_SZ,
2347 (BYTE *)pszClassInstance,
2348 ulDataLength,
2349 0);
2350 if (ret != CR_SUCCESS)
2351 {
2352 DPRINT1("PNP_SetDeviceRegProp() failed (Error %lu)\n", ret);
2353 RegDeleteKeyW(hDeviceClassKey,
2354 szClassInstance);
2355 }
2356
2357 break;
2358 }
2359 }
2360 }
2361
2362 done:
2363 if (hDeviceClassKey != NULL)
2364 RegCloseKey(hDeviceClassKey);
2365
2366 return ret;
2367 }
2368
2369
2370 /* Function 16 */
2371 DWORD
2372 WINAPI
PNP_CreateKey(handle_t hBinding,LPWSTR pszSubKey,DWORD samDesired,DWORD ulFlags)2373 PNP_CreateKey(
2374 handle_t hBinding,
2375 LPWSTR pszSubKey,
2376 DWORD samDesired,
2377 DWORD ulFlags)
2378 {
2379 HKEY hDeviceKey = NULL, hParametersKey = NULL;
2380 DWORD dwError;
2381 CONFIGRET ret = CR_SUCCESS;
2382
2383 UNREFERENCED_PARAMETER(hBinding);
2384 UNREFERENCED_PARAMETER(samDesired);
2385
2386 DPRINT("PNP_CreateKey(%p %S 0x%lx 0x%08lx)\n",
2387 hBinding, pszSubKey, samDesired, ulFlags);
2388
2389 if (ulFlags != 0)
2390 return CR_INVALID_FLAG;
2391
2392 if (!IsValidDeviceInstanceID(pszSubKey))
2393 return CR_INVALID_DEVINST;
2394
2395 dwError = RegOpenKeyExW(hEnumKey,
2396 pszSubKey,
2397 0,
2398 KEY_WRITE,
2399 &hDeviceKey);
2400 if (dwError != ERROR_SUCCESS)
2401 {
2402 ret = CR_INVALID_DEVNODE;
2403 goto done;
2404 }
2405
2406 dwError = RegCreateKeyExW(hDeviceKey,
2407 L"Device Parameters",
2408 0,
2409 NULL,
2410 REG_OPTION_NON_VOLATILE,
2411 KEY_ALL_ACCESS,
2412 NULL,
2413 &hParametersKey,
2414 NULL);
2415 if (dwError != ERROR_SUCCESS)
2416 {
2417 ret = CR_REGISTRY_ERROR;
2418 goto done;
2419 }
2420
2421 /* FIXME: Set key security */
2422
2423 done:
2424 if (hParametersKey != NULL)
2425 RegCloseKey(hParametersKey);
2426
2427 if (hDeviceKey != NULL)
2428 RegCloseKey(hDeviceKey);
2429
2430 return ret;
2431 }
2432
2433
2434 /* Function 17 */
2435 DWORD
2436 WINAPI
PNP_DeleteRegistryKey(handle_t hBinding,LPWSTR pszDeviceID,LPWSTR pszParentKey,LPWSTR pszChildKey,DWORD ulFlags)2437 PNP_DeleteRegistryKey(
2438 handle_t hBinding,
2439 LPWSTR pszDeviceID,
2440 LPWSTR pszParentKey,
2441 LPWSTR pszChildKey,
2442 DWORD ulFlags)
2443 {
2444 UNIMPLEMENTED;
2445 return CR_CALL_NOT_IMPLEMENTED;
2446 }
2447
2448
2449 /* Function 18 */
2450 DWORD
2451 WINAPI
PNP_GetClassCount(handle_t hBinding,DWORD * pulClassCount,DWORD ulFlags)2452 PNP_GetClassCount(
2453 handle_t hBinding,
2454 DWORD *pulClassCount,
2455 DWORD ulFlags)
2456 {
2457 HKEY hKey;
2458 DWORD dwError;
2459
2460 UNREFERENCED_PARAMETER(hBinding);
2461 UNREFERENCED_PARAMETER(ulFlags);
2462
2463 DPRINT("PNP_GetClassCount(%p %p 0x%08lx)\n",
2464 hBinding, pulClassCount, ulFlags);
2465
2466 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2467 REGSTR_PATH_CLASS,
2468 0,
2469 KEY_QUERY_VALUE,
2470 &hKey);
2471 if (dwError != ERROR_SUCCESS)
2472 return CR_INVALID_DATA;
2473
2474 dwError = RegQueryInfoKeyW(hKey,
2475 NULL,
2476 NULL,
2477 NULL,
2478 pulClassCount,
2479 NULL,
2480 NULL,
2481 NULL,
2482 NULL,
2483 NULL,
2484 NULL,
2485 NULL);
2486 RegCloseKey(hKey);
2487 if (dwError != ERROR_SUCCESS)
2488 return CR_INVALID_DATA;
2489
2490 return CR_SUCCESS;
2491 }
2492
2493
2494 /* Function 19 */
2495 DWORD
2496 WINAPI
PNP_GetClassName(handle_t hBinding,LPWSTR pszClassGuid,LPWSTR Buffer,PNP_RPC_STRING_LEN * pulLength,DWORD ulFlags)2497 PNP_GetClassName(
2498 handle_t hBinding,
2499 LPWSTR pszClassGuid,
2500 LPWSTR Buffer,
2501 PNP_RPC_STRING_LEN *pulLength,
2502 DWORD ulFlags)
2503 {
2504 WCHAR szKeyName[MAX_PATH];
2505 CONFIGRET ret = CR_SUCCESS;
2506 HKEY hKey;
2507 DWORD dwSize;
2508
2509 UNREFERENCED_PARAMETER(hBinding);
2510 UNREFERENCED_PARAMETER(ulFlags);
2511
2512 DPRINT("PNP_GetClassName(%p %S %p %p 0x%08lx)\n",
2513 hBinding, pszClassGuid, Buffer, pulLength, ulFlags);
2514
2515 lstrcpyW(szKeyName, L"System\\CurrentControlSet\\Control\\Class\\");
2516 if (lstrlenW(pszClassGuid) + 1 < sizeof(szKeyName)/sizeof(WCHAR)-(lstrlenW(szKeyName) * sizeof(WCHAR)))
2517 lstrcatW(szKeyName, pszClassGuid);
2518 else
2519 return CR_INVALID_DATA;
2520
2521 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
2522 szKeyName,
2523 0,
2524 KEY_QUERY_VALUE,
2525 &hKey))
2526 return CR_REGISTRY_ERROR;
2527
2528 dwSize = *pulLength * sizeof(WCHAR);
2529 if (RegQueryValueExW(hKey,
2530 L"Class",
2531 NULL,
2532 NULL,
2533 (LPBYTE)Buffer,
2534 &dwSize))
2535 {
2536 *pulLength = 0;
2537 ret = CR_REGISTRY_ERROR;
2538 }
2539 else
2540 {
2541 *pulLength = dwSize / sizeof(WCHAR);
2542 }
2543
2544 RegCloseKey(hKey);
2545
2546 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret);
2547
2548 return ret;
2549 }
2550
2551
2552 /* Function 20 */
2553 DWORD
2554 WINAPI
PNP_DeleteClassKey(handle_t hBinding,LPWSTR pszClassGuid,DWORD ulFlags)2555 PNP_DeleteClassKey(
2556 handle_t hBinding,
2557 LPWSTR pszClassGuid,
2558 DWORD ulFlags)
2559 {
2560 CONFIGRET ret = CR_SUCCESS;
2561
2562 UNREFERENCED_PARAMETER(hBinding);
2563
2564 DPRINT("PNP_DeleteClassKey(%p %S 0x%08lx)\n",
2565 hBinding, pszClassGuid, ulFlags);
2566
2567 if (ulFlags & CM_DELETE_CLASS_SUBKEYS)
2568 {
2569 if (SHDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
2570 ret = CR_REGISTRY_ERROR;
2571 }
2572 else
2573 {
2574 if (RegDeleteKeyW(hClassKey, pszClassGuid) != ERROR_SUCCESS)
2575 ret = CR_REGISTRY_ERROR;
2576 }
2577
2578 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret);
2579
2580 return ret;
2581 }
2582
2583
2584 /* Function 21 */
2585 DWORD
2586 WINAPI
PNP_GetInterfaceDeviceAlias(handle_t hBinding,LPWSTR pszInterfaceDevice,GUID * AliasInterfaceGuid,LPWSTR pszAliasInterfaceDevice,PNP_RPC_STRING_LEN * pulLength,PNP_RPC_STRING_LEN * pulTransferLen,DWORD ulFlags)2587 PNP_GetInterfaceDeviceAlias(
2588 handle_t hBinding,
2589 LPWSTR pszInterfaceDevice,
2590 GUID *AliasInterfaceGuid,
2591 LPWSTR pszAliasInterfaceDevice,
2592 PNP_RPC_STRING_LEN *pulLength,
2593 PNP_RPC_STRING_LEN *pulTransferLen,
2594 DWORD ulFlags)
2595 {
2596 UNIMPLEMENTED;
2597 return CR_CALL_NOT_IMPLEMENTED;
2598 }
2599
2600
2601 /* Function 22 */
2602 DWORD
2603 WINAPI
PNP_GetInterfaceDeviceList(handle_t hBinding,GUID * InterfaceGuid,LPWSTR pszDeviceID,BYTE * Buffer,PNP_RPC_BUFFER_SIZE * pulLength,DWORD ulFlags)2604 PNP_GetInterfaceDeviceList(
2605 handle_t hBinding,
2606 GUID *InterfaceGuid,
2607 LPWSTR pszDeviceID,
2608 BYTE *Buffer,
2609 PNP_RPC_BUFFER_SIZE *pulLength,
2610 DWORD ulFlags)
2611 {
2612 NTSTATUS Status;
2613 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData;
2614 DWORD ret = CR_SUCCESS;
2615
2616 UNREFERENCED_PARAMETER(hBinding);
2617
2618 DPRINT("PNP_GetInterfaceDeviceList(%p %p %S %p %p 0x%08lx)\n",
2619 hBinding, InterfaceGuid, pszDeviceID, Buffer, pulLength, ulFlags);
2620
2621 if (!IsValidDeviceInstanceID(pszDeviceID))
2622 return CR_INVALID_DEVINST;
2623
2624 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2625 pszDeviceID);
2626
2627 PlugPlayData.Flags = ulFlags;
2628 PlugPlayData.FilterGuid = InterfaceGuid;
2629 PlugPlayData.Buffer = Buffer;
2630 PlugPlayData.BufferSize = *pulLength;
2631
2632 Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList,
2633 (PVOID)&PlugPlayData,
2634 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA));
2635 if (NT_SUCCESS(Status))
2636 {
2637 *pulLength = PlugPlayData.BufferSize;
2638 }
2639 else
2640 {
2641 ret = NtStatusToCrError(Status);
2642 }
2643
2644 DPRINT("PNP_GetInterfaceDeviceList() done (returns %lx)\n", ret);
2645 return ret;
2646 }
2647
2648
2649 /* Function 23 */
2650 DWORD
2651 WINAPI
PNP_GetInterfaceDeviceListSize(handle_t hBinding,PNP_RPC_BUFFER_SIZE * pulLen,GUID * InterfaceGuid,LPWSTR pszDeviceID,DWORD ulFlags)2652 PNP_GetInterfaceDeviceListSize(
2653 handle_t hBinding,
2654 PNP_RPC_BUFFER_SIZE *pulLen,
2655 GUID *InterfaceGuid,
2656 LPWSTR pszDeviceID,
2657 DWORD ulFlags)
2658 {
2659 NTSTATUS Status;
2660 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData;
2661 DWORD ret = CR_SUCCESS;
2662
2663 UNREFERENCED_PARAMETER(hBinding);
2664
2665 DPRINT("PNP_GetInterfaceDeviceListSize(%p %p %p %S 0x%08lx)\n",
2666 hBinding, pulLen, InterfaceGuid, pszDeviceID, ulFlags);
2667
2668 if (!IsValidDeviceInstanceID(pszDeviceID))
2669 return CR_INVALID_DEVINST;
2670
2671 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
2672 pszDeviceID);
2673
2674 PlugPlayData.FilterGuid = InterfaceGuid;
2675 PlugPlayData.Buffer = NULL;
2676 PlugPlayData.BufferSize = 0;
2677 PlugPlayData.Flags = ulFlags;
2678
2679 Status = NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList,
2680 (PVOID)&PlugPlayData,
2681 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA));
2682 if (NT_SUCCESS(Status))
2683 {
2684 *pulLen = PlugPlayData.BufferSize;
2685 }
2686 else
2687 {
2688 ret = NtStatusToCrError(Status);
2689 }
2690
2691 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret);
2692 return ret;
2693 }
2694
2695
2696 /* Function 24 */
2697 DWORD
2698 WINAPI
PNP_RegisterDeviceClassAssociation(handle_t hBinding,LPWSTR pszDeviceID,GUID * InterfaceGuid,LPWSTR pszReference,LPWSTR pszSymLink,PNP_RPC_STRING_LEN * pulLength,PNP_RPC_STRING_LEN * pulTransferLen,DWORD ulFlags)2699 PNP_RegisterDeviceClassAssociation(
2700 handle_t hBinding,
2701 LPWSTR pszDeviceID,
2702 GUID *InterfaceGuid,
2703 LPWSTR pszReference,
2704 LPWSTR pszSymLink,
2705 PNP_RPC_STRING_LEN *pulLength,
2706 PNP_RPC_STRING_LEN *pulTransferLen,
2707 DWORD ulFlags)
2708 {
2709 UNIMPLEMENTED;
2710 return CR_CALL_NOT_IMPLEMENTED;
2711 }
2712
2713
2714 /* Function 25 */
2715 DWORD
2716 WINAPI
PNP_UnregisterDeviceClassAssociation(handle_t hBinding,LPWSTR pszInterfaceDevice,DWORD ulFlags)2717 PNP_UnregisterDeviceClassAssociation(
2718 handle_t hBinding,
2719 LPWSTR pszInterfaceDevice,
2720 DWORD ulFlags)
2721 {
2722 UNIMPLEMENTED;
2723 return CR_CALL_NOT_IMPLEMENTED;
2724 }
2725
2726
2727 /* Function 26 */
2728 DWORD
2729 WINAPI
PNP_GetClassRegProp(handle_t hBinding,LPWSTR pszClassGuid,DWORD ulProperty,DWORD * pulRegDataType,BYTE * Buffer,PNP_RPC_STRING_LEN * pulTransferLen,PNP_RPC_STRING_LEN * pulLength,DWORD ulFlags)2730 PNP_GetClassRegProp(
2731 handle_t hBinding,
2732 LPWSTR pszClassGuid,
2733 DWORD ulProperty,
2734 DWORD *pulRegDataType,
2735 BYTE *Buffer,
2736 PNP_RPC_STRING_LEN *pulTransferLen,
2737 PNP_RPC_STRING_LEN *pulLength,
2738 DWORD ulFlags)
2739 {
2740 CONFIGRET ret = CR_SUCCESS;
2741 LPWSTR lpValueName = NULL;
2742 HKEY hInstKey = NULL;
2743 HKEY hPropKey = NULL;
2744 LONG lError;
2745
2746 UNREFERENCED_PARAMETER(hBinding);
2747
2748 DPRINT("PNP_GetClassRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
2749 hBinding, pszClassGuid, ulProperty, pulRegDataType,
2750 Buffer, pulTransferLen, pulLength, ulFlags);
2751
2752 if (pulTransferLen == NULL || pulLength == NULL)
2753 {
2754 ret = CR_INVALID_POINTER;
2755 goto done;
2756 }
2757
2758 if (ulFlags != 0)
2759 {
2760 ret = CR_INVALID_FLAG;
2761 goto done;
2762 }
2763
2764 if (*pulLength < *pulTransferLen)
2765 *pulLength = *pulTransferLen;
2766
2767 *pulTransferLen = 0;
2768
2769 switch (ulProperty)
2770 {
2771 case CM_CRP_SECURITY:
2772 lpValueName = L"Security";
2773 break;
2774
2775 case CM_CRP_DEVTYPE:
2776 lpValueName = L"DeviceType";
2777 break;
2778
2779 case CM_CRP_EXCLUSIVE:
2780 lpValueName = L"Exclusive";
2781 break;
2782
2783 case CM_CRP_CHARACTERISTICS:
2784 lpValueName = L"DeviceCharacteristics";
2785 break;
2786
2787 default:
2788 ret = CR_INVALID_PROPERTY;
2789 goto done;
2790 }
2791
2792 DPRINT("Value name: %S\n", lpValueName);
2793
2794 lError = RegOpenKeyExW(hClassKey,
2795 pszClassGuid,
2796 0,
2797 KEY_READ,
2798 &hInstKey);
2799 if (lError != ERROR_SUCCESS)
2800 {
2801 *pulLength = 0;
2802 ret = CR_NO_SUCH_REGISTRY_KEY;
2803 goto done;
2804 }
2805
2806 lError = RegOpenKeyExW(hInstKey,
2807 L"Properties",
2808 0,
2809 KEY_READ,
2810 &hPropKey);
2811 if (lError != ERROR_SUCCESS)
2812 {
2813 *pulLength = 0;
2814 ret = CR_NO_SUCH_REGISTRY_KEY;
2815 goto done;
2816 }
2817
2818 lError = RegQueryValueExW(hPropKey,
2819 lpValueName,
2820 NULL,
2821 pulRegDataType,
2822 Buffer,
2823 pulLength);
2824 if (lError != ERROR_SUCCESS)
2825 {
2826 if (lError == ERROR_MORE_DATA)
2827 {
2828 ret = CR_BUFFER_SMALL;
2829 }
2830 else
2831 {
2832 *pulLength = 0;
2833 ret = CR_NO_SUCH_VALUE;
2834 }
2835 }
2836
2837 done:
2838 if (ret == CR_SUCCESS)
2839 *pulTransferLen = *pulLength;
2840
2841 if (hPropKey != NULL)
2842 RegCloseKey(hPropKey);
2843
2844 if (hInstKey != NULL)
2845 RegCloseKey(hInstKey);
2846
2847 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret);
2848
2849 return ret;
2850 }
2851
2852
2853 /* Function 27 */
2854 DWORD
2855 WINAPI
PNP_SetClassRegProp(handle_t hBinding,LPWSTR pszClassGuid,DWORD ulProperty,DWORD ulDataType,BYTE * Buffer,PNP_PROP_SIZE ulLength,DWORD ulFlags)2856 PNP_SetClassRegProp(
2857 handle_t hBinding,
2858 LPWSTR pszClassGuid,
2859 DWORD ulProperty,
2860 DWORD ulDataType,
2861 BYTE *Buffer,
2862 PNP_PROP_SIZE ulLength,
2863 DWORD ulFlags)
2864 {
2865 CONFIGRET ret = CR_SUCCESS;
2866 LPWSTR lpValueName = NULL;
2867 HKEY hInstKey = 0;
2868 HKEY hPropKey = 0;
2869 LONG lError;
2870
2871 UNREFERENCED_PARAMETER(hBinding);
2872
2873 DPRINT("PNP_SetClassRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2874 hBinding, pszClassGuid, ulProperty, ulDataType,
2875 Buffer, ulLength, ulFlags);
2876
2877 if (ulFlags != 0)
2878 return CR_INVALID_FLAG;
2879
2880 switch (ulProperty)
2881 {
2882 case CM_CRP_SECURITY:
2883 lpValueName = L"Security";
2884 break;
2885
2886 case CM_CRP_DEVTYPE:
2887 lpValueName = L"DeviceType";
2888 break;
2889
2890 case CM_CRP_EXCLUSIVE:
2891 lpValueName = L"Exclusive";
2892 break;
2893
2894 case CM_CRP_CHARACTERISTICS:
2895 lpValueName = L"DeviceCharacteristics";
2896 break;
2897
2898 default:
2899 return CR_INVALID_PROPERTY;
2900 }
2901
2902 lError = RegOpenKeyExW(hClassKey,
2903 pszClassGuid,
2904 0,
2905 KEY_WRITE,
2906 &hInstKey);
2907 if (lError != ERROR_SUCCESS)
2908 {
2909 ret = CR_NO_SUCH_REGISTRY_KEY;
2910 goto done;
2911 }
2912
2913 /* FIXME: Set security descriptor */
2914 lError = RegCreateKeyExW(hInstKey,
2915 L"Properties",
2916 0,
2917 NULL,
2918 REG_OPTION_NON_VOLATILE,
2919 KEY_ALL_ACCESS,
2920 NULL,
2921 &hPropKey,
2922 NULL);
2923 if (lError != ERROR_SUCCESS)
2924 {
2925 ret = CR_REGISTRY_ERROR;
2926 goto done;
2927 }
2928
2929 if (ulLength == 0)
2930 {
2931 if (RegDeleteValueW(hPropKey,
2932 lpValueName))
2933 ret = CR_REGISTRY_ERROR;
2934 }
2935 else
2936 {
2937 if (RegSetValueExW(hPropKey,
2938 lpValueName,
2939 0,
2940 ulDataType,
2941 Buffer,
2942 ulLength))
2943 ret = CR_REGISTRY_ERROR;
2944 }
2945
2946 done:
2947 if (hPropKey != NULL)
2948 RegCloseKey(hPropKey);
2949
2950 if (hInstKey != NULL)
2951 RegCloseKey(hInstKey);
2952
2953 return ret;
2954 }
2955
2956
2957 static
2958 CONFIGRET
CreateDeviceInstance(_In_ LPWSTR pszDeviceID,_In_ BOOL bPhantomDevice)2959 CreateDeviceInstance(
2960 _In_ LPWSTR pszDeviceID,
2961 _In_ BOOL bPhantomDevice)
2962 {
2963 WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
2964 WCHAR szDevice[MAX_DEVICE_ID_LEN];
2965 WCHAR szInstance[MAX_DEVICE_ID_LEN];
2966 HKEY hKeyEnumerator;
2967 HKEY hKeyDevice;
2968 HKEY hKeyInstance;
2969 HKEY hKeyControl;
2970 LONG lError;
2971
2972 /* Split the instance ID */
2973 SplitDeviceInstanceID(pszDeviceID,
2974 szEnumerator,
2975 szDevice,
2976 szInstance);
2977
2978 /* Open or create the enumerator key */
2979 lError = RegCreateKeyExW(hEnumKey,
2980 szEnumerator,
2981 0,
2982 NULL,
2983 REG_OPTION_NON_VOLATILE,
2984 KEY_ALL_ACCESS,
2985 NULL,
2986 &hKeyEnumerator,
2987 NULL);
2988 if (lError != ERROR_SUCCESS)
2989 {
2990 return CR_REGISTRY_ERROR;
2991 }
2992
2993 /* Open or create the device key */
2994 lError = RegCreateKeyExW(hKeyEnumerator,
2995 szDevice,
2996 0,
2997 NULL,
2998 REG_OPTION_NON_VOLATILE,
2999 KEY_ALL_ACCESS,
3000 NULL,
3001 &hKeyDevice,
3002 NULL);
3003
3004 /* Close the enumerator key */
3005 RegCloseKey(hKeyEnumerator);
3006
3007 if (lError != ERROR_SUCCESS)
3008 {
3009 return CR_REGISTRY_ERROR;
3010 }
3011
3012 /* Try to open the instance key and fail if it exists */
3013 lError = RegOpenKeyExW(hKeyDevice,
3014 szInstance,
3015 0,
3016 KEY_SET_VALUE,
3017 &hKeyInstance);
3018 if (lError == ERROR_SUCCESS)
3019 {
3020 DPRINT1("Instance %S already exists!\n", szInstance);
3021 RegCloseKey(hKeyInstance);
3022 RegCloseKey(hKeyDevice);
3023 return CR_ALREADY_SUCH_DEVINST;
3024 }
3025
3026 /* Create a new instance key */
3027 lError = RegCreateKeyExW(hKeyDevice,
3028 szInstance,
3029 0,
3030 NULL,
3031 REG_OPTION_NON_VOLATILE,
3032 KEY_ALL_ACCESS,
3033 NULL,
3034 &hKeyInstance,
3035 NULL);
3036
3037 /* Close the device key */
3038 RegCloseKey(hKeyDevice);
3039
3040 if (lError != ERROR_SUCCESS)
3041 {
3042 return CR_REGISTRY_ERROR;
3043 }
3044
3045 if (bPhantomDevice)
3046 {
3047 DWORD dwPhantomValue = 1;
3048 RegSetValueExW(hKeyInstance,
3049 L"Phantom",
3050 0,
3051 REG_DWORD,
3052 (PBYTE)&dwPhantomValue,
3053 sizeof(dwPhantomValue));
3054 }
3055
3056 /* Create the 'Control' sub key */
3057 lError = RegCreateKeyExW(hKeyInstance,
3058 L"Control",
3059 0,
3060 NULL,
3061 REG_OPTION_NON_VOLATILE,
3062 KEY_ALL_ACCESS,
3063 NULL,
3064 &hKeyControl,
3065 NULL);
3066 if (lError == ERROR_SUCCESS)
3067 {
3068 RegCloseKey(hKeyControl);
3069 }
3070
3071 RegCloseKey(hKeyInstance);
3072
3073 return (lError == ERROR_SUCCESS) ? CR_SUCCESS : CR_REGISTRY_ERROR;
3074 }
3075
3076
3077 static
3078 CONFIGRET
GenerateDeviceID(_Inout_ LPWSTR pszDeviceID,_In_ PNP_RPC_STRING_LEN ulLength)3079 GenerateDeviceID(
3080 _Inout_ LPWSTR pszDeviceID,
3081 _In_ PNP_RPC_STRING_LEN ulLength)
3082 {
3083 WCHAR szGeneratedInstance[MAX_DEVICE_ID_LEN];
3084 HKEY hKey;
3085 DWORD dwInstanceNumber;
3086 DWORD dwError = ERROR_SUCCESS;
3087 CONFIGRET ret = CR_SUCCESS;
3088
3089 /* Fail, if the device name contains backslashes */
3090 if (wcschr(pszDeviceID, L'\\') != NULL)
3091 return CR_INVALID_DEVICE_ID;
3092
3093 /* Generated ID is: Root\<Device ID>\<Instance number> */
3094 dwInstanceNumber = 0;
3095 while (dwError == ERROR_SUCCESS)
3096 {
3097 if (dwInstanceNumber >= 10000)
3098 return CR_FAILURE;
3099
3100 swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu",
3101 pszDeviceID, dwInstanceNumber);
3102
3103 /* Try to open the enum key of the device instance */
3104 dwError = RegOpenKeyEx(hEnumKey, szGeneratedInstance, 0, KEY_QUERY_VALUE, &hKey);
3105 if (dwError == ERROR_SUCCESS)
3106 {
3107 RegCloseKey(hKey);
3108 dwInstanceNumber++;
3109 }
3110 }
3111
3112 /* pszDeviceID is an out parameter too for generated IDs */
3113 if (wcslen(szGeneratedInstance) > ulLength)
3114 {
3115 ret = CR_BUFFER_SMALL;
3116 }
3117 else
3118 {
3119 wcscpy(pszDeviceID, szGeneratedInstance);
3120 }
3121
3122 return ret;
3123 }
3124
3125
3126 /* Function 28 */
3127 DWORD
3128 WINAPI
PNP_CreateDevInst(handle_t hBinding,LPWSTR pszDeviceID,LPWSTR pszParentDeviceID,PNP_RPC_STRING_LEN ulLength,DWORD ulFlags)3129 PNP_CreateDevInst(
3130 handle_t hBinding,
3131 LPWSTR pszDeviceID,
3132 LPWSTR pszParentDeviceID,
3133 PNP_RPC_STRING_LEN ulLength,
3134 DWORD ulFlags)
3135 {
3136 PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData;
3137 HKEY hKey = NULL;
3138 DWORD dwSize, dwPhantom;
3139 NTSTATUS Status;
3140 CONFIGRET ret = CR_SUCCESS;
3141
3142 DPRINT("PNP_CreateDevInst(%p %S %S %lu 0x%08lx)\n",
3143 hBinding, pszParentDeviceID, pszDeviceID, ulLength, ulFlags);
3144
3145 if (ulFlags & ~CM_CREATE_DEVNODE_BITS)
3146 return CR_INVALID_FLAG;
3147
3148 if (pszDeviceID == NULL || pszParentDeviceID == NULL)
3149 return CR_INVALID_POINTER;
3150
3151 /* Fail, if the parent device is not the root device */
3152 if (!IsRootDeviceInstanceID(pszParentDeviceID))
3153 return CR_INVALID_DEVINST;
3154
3155 if (ulFlags & CM_CREATE_DEVNODE_GENERATE_ID)
3156 {
3157 ret = GenerateDeviceID(pszDeviceID,
3158 ulLength);
3159 if (ret != CR_SUCCESS)
3160 return ret;
3161 }
3162
3163 /* Try to open the device instance key */
3164 RegOpenKeyEx(hEnumKey, pszDeviceID, 0, KEY_READ | KEY_WRITE, &hKey);
3165
3166 if (ulFlags & CM_CREATE_DEVNODE_PHANTOM)
3167 {
3168 /* Fail, if the device already exists */
3169 if (hKey != NULL)
3170 {
3171 ret = CR_ALREADY_SUCH_DEVINST;
3172 goto done;
3173 }
3174
3175 /* Create the phantom device instance */
3176 ret = CreateDeviceInstance(pszDeviceID, TRUE);
3177 }
3178 else
3179 {
3180 /* Fail, if the device exists and is present */
3181 if ((hKey != NULL) && (IsPresentDeviceInstanceID(pszDeviceID)))
3182 {
3183 ret = CR_ALREADY_SUCH_DEVINST;
3184 goto done;
3185 }
3186
3187 /* If it does not already exist ... */
3188 if (hKey == NULL)
3189 {
3190 /* Create the device instance */
3191 ret = CreateDeviceInstance(pszDeviceID, FALSE);
3192
3193 /* Open the device instance key */
3194 RegOpenKeyEx(hEnumKey, pszDeviceID, 0, KEY_READ | KEY_WRITE, &hKey);
3195 }
3196
3197 /* Create a device node for the device */
3198 RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceID);
3199 Status = NtPlugPlayControl(PlugPlayControlInitializeDevice,
3200 &ControlData,
3201 sizeof(ControlData));
3202 if (!NT_SUCCESS(Status))
3203 {
3204 ret = CR_FAILURE;
3205 goto done;
3206 }
3207
3208 /* If the device is a phantom device, turn it into a normal device */
3209 if (hKey != NULL)
3210 {
3211 dwPhantom = 0;
3212 dwSize = sizeof(DWORD);
3213 RegQueryValueEx(hKey, L"Phantom", NULL, NULL, (PBYTE)&dwPhantom, &dwSize);
3214
3215 if (dwPhantom != 0)
3216 RegDeleteValue(hKey, L"Phantom");
3217 }
3218 }
3219
3220 done:
3221 if (hKey)
3222 RegCloseKey(hKey);
3223
3224 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret);
3225
3226 return ret;
3227 }
3228
3229
3230 static CONFIGRET
SetupDeviceInstance(_In_ LPWSTR pszDeviceInstance,_In_ DWORD ulMinorAction)3231 SetupDeviceInstance(
3232 _In_ LPWSTR pszDeviceInstance,
3233 _In_ DWORD ulMinorAction)
3234 {
3235 PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData;
3236 HKEY hDeviceKey = NULL;
3237 DWORD dwDisableCount, dwSize;
3238 DWORD ulStatus, ulProblem;
3239 DWORD dwError;
3240 CONFIGRET ret = CR_SUCCESS;
3241 NTSTATUS Status;
3242
3243 DPRINT1("SetupDeviceInstance(%S 0x%08lx)\n",
3244 pszDeviceInstance, ulMinorAction);
3245
3246 if (IsRootDeviceInstanceID(pszDeviceInstance))
3247 return CR_INVALID_DEVINST;
3248
3249 if (ulMinorAction & ~CM_SETUP_BITS)
3250 return CR_INVALID_FLAG;
3251
3252 if ((ulMinorAction == CM_SETUP_DOWNLOAD) ||
3253 (ulMinorAction == CM_SETUP_WRITE_LOG_CONFS))
3254 return CR_SUCCESS;
3255
3256 dwError = RegOpenKeyExW(hEnumKey,
3257 pszDeviceInstance,
3258 0,
3259 KEY_READ,
3260 &hDeviceKey);
3261 if (dwError != ERROR_SUCCESS)
3262 return CR_INVALID_DEVNODE;
3263
3264 dwSize = sizeof(dwDisableCount);
3265 dwError = RegQueryValueExW(hDeviceKey,
3266 L"DisableCount",
3267 NULL,
3268 NULL,
3269 (LPBYTE)&dwDisableCount,
3270 &dwSize);
3271 if ((dwError == ERROR_SUCCESS) &&
3272 (dwDisableCount > 0))
3273 {
3274 goto done;
3275 }
3276
3277 GetDeviceStatus(pszDeviceInstance,
3278 &ulStatus,
3279 &ulProblem);
3280
3281 if (ulStatus & DN_STARTED)
3282 {
3283 goto done;
3284 }
3285
3286 if (ulStatus & DN_HAS_PROBLEM)
3287 {
3288 ret = ClearDeviceStatus(pszDeviceInstance,
3289 DN_HAS_PROBLEM,
3290 ulProblem);
3291 }
3292
3293 if (ret != CR_SUCCESS)
3294 goto done;
3295
3296 /* Start the device */
3297 RtlInitUnicodeString(&ControlData.DeviceInstance,
3298 pszDeviceInstance);
3299 Status = NtPlugPlayControl(PlugPlayControlStartDevice,
3300 &ControlData,
3301 sizeof(PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA));
3302 if (!NT_SUCCESS(Status))
3303 ret = NtStatusToCrError(Status);
3304
3305 done:
3306 if (hDeviceKey != NULL)
3307 RegCloseKey(hDeviceKey);
3308
3309 return ret;
3310 }
3311
3312
3313 static CONFIGRET
EnableDeviceInstance(_In_ LPWSTR pszDeviceInstance)3314 EnableDeviceInstance(
3315 _In_ LPWSTR pszDeviceInstance)
3316 {
3317 PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData;
3318 CONFIGRET ret = CR_SUCCESS;
3319 NTSTATUS Status;
3320
3321 DPRINT("Enable device instance %S\n", pszDeviceInstance);
3322
3323 RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceInstance);
3324 Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(ControlData));
3325 if (!NT_SUCCESS(Status))
3326 ret = NtStatusToCrError(Status);
3327
3328 return ret;
3329 }
3330
3331
3332 static CONFIGRET
ReenumerateDeviceInstance(_In_ LPWSTR pszDeviceInstance,_In_ ULONG ulMinorAction)3333 ReenumerateDeviceInstance(
3334 _In_ LPWSTR pszDeviceInstance,
3335 _In_ ULONG ulMinorAction)
3336 {
3337 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData;
3338 CONFIGRET ret = CR_SUCCESS;
3339 NTSTATUS Status;
3340
3341 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
3342 pszDeviceInstance, ulMinorAction);
3343
3344 if (ulMinorAction & ~CM_REENUMERATE_BITS)
3345 return CR_INVALID_FLAG;
3346
3347 if (ulMinorAction & CM_REENUMERATE_RETRY_INSTALLATION)
3348 {
3349 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
3350 }
3351
3352 RtlInitUnicodeString(&EnumerateDeviceData.DeviceInstance,
3353 pszDeviceInstance);
3354 EnumerateDeviceData.Flags = 0;
3355
3356 Status = NtPlugPlayControl(PlugPlayControlEnumerateDevice,
3357 &EnumerateDeviceData,
3358 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA));
3359 if (!NT_SUCCESS(Status))
3360 ret = NtStatusToCrError(Status);
3361
3362 return ret;
3363 }
3364
3365
3366 /* Function 29 */
3367 DWORD
3368 WINAPI
PNP_DeviceInstanceAction(handle_t hBinding,DWORD ulMajorAction,DWORD ulMinorAction,LPWSTR pszDeviceInstance1,LPWSTR pszDeviceInstance2)3369 PNP_DeviceInstanceAction(
3370 handle_t hBinding,
3371 DWORD ulMajorAction,
3372 DWORD ulMinorAction,
3373 LPWSTR pszDeviceInstance1,
3374 LPWSTR pszDeviceInstance2)
3375 {
3376 CONFIGRET ret = CR_SUCCESS;
3377
3378 UNREFERENCED_PARAMETER(hBinding);
3379
3380 DPRINT("PNP_DeviceInstanceAction(%p %lu 0x%08lx %S %S)\n",
3381 hBinding, ulMajorAction, ulMinorAction,
3382 pszDeviceInstance1, pszDeviceInstance2);
3383
3384 switch (ulMajorAction)
3385 {
3386 case PNP_DEVINST_SETUP:
3387 ret = SetupDeviceInstance(pszDeviceInstance1,
3388 ulMinorAction);
3389 break;
3390
3391 case PNP_DEVINST_ENABLE:
3392 ret = EnableDeviceInstance(pszDeviceInstance1);
3393 break;
3394
3395 case PNP_DEVINST_REENUMERATE:
3396 ret = ReenumerateDeviceInstance(pszDeviceInstance1,
3397 ulMinorAction);
3398 break;
3399
3400 default:
3401 DPRINT1("Unknown device action %lu: not implemented\n", ulMajorAction);
3402 ret = CR_CALL_NOT_IMPLEMENTED;
3403 }
3404
3405 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret);
3406
3407 return ret;
3408 }
3409
3410
3411 /* Function 30 */
3412 DWORD
3413 WINAPI
PNP_GetDeviceStatus(handle_t hBinding,LPWSTR pDeviceID,DWORD * pulStatus,DWORD * pulProblem,DWORD ulFlags)3414 PNP_GetDeviceStatus(
3415 handle_t hBinding,
3416 LPWSTR pDeviceID,
3417 DWORD *pulStatus,
3418 DWORD *pulProblem,
3419 DWORD ulFlags)
3420 {
3421 DWORD ulDataType, ulTransferLength, ulLength;
3422 DWORD ulCapabilities, ulConfigFlags;
3423 CONFIGRET ret;
3424
3425 UNREFERENCED_PARAMETER(hBinding);
3426 UNREFERENCED_PARAMETER(ulFlags);
3427
3428 DPRINT("PNP_GetDeviceStatus(%p %S %p %p 0x%08lx)\n",
3429 hBinding, pDeviceID, pulStatus, pulProblem, ulFlags);
3430
3431 if (ulFlags != 0)
3432 return CR_INVALID_FLAG;
3433
3434 if ((pulStatus == NULL) || (pulProblem == NULL))
3435 return CR_INVALID_POINTER;
3436
3437 if (!IsValidDeviceInstanceID(pDeviceID))
3438 return CR_INVALID_DEVINST;
3439
3440 ret = GetDeviceStatus(pDeviceID, pulStatus, pulProblem);
3441 if (ret != CR_SUCCESS)
3442 return ret;
3443
3444 /* Check for DN_REMOVABLE */
3445 ulTransferLength = sizeof(ulCapabilities);
3446 ulLength = sizeof(ulCapabilities);
3447 ret = PNP_GetDeviceRegProp(NULL,
3448 pDeviceID,
3449 CM_DRP_CAPABILITIES,
3450 &ulDataType,
3451 (PBYTE)&ulCapabilities,
3452 &ulTransferLength,
3453 &ulLength,
3454 0);
3455 if (ret != CR_SUCCESS)
3456 ulCapabilities = 0;
3457
3458 if (ulCapabilities & CM_DEVCAP_REMOVABLE)
3459 *pulStatus |= DN_REMOVABLE;
3460
3461 /* Check for DN_MANUAL */
3462 ulTransferLength = sizeof(ulConfigFlags);
3463 ulLength = sizeof(ulConfigFlags);
3464 ret = PNP_GetDeviceRegProp(NULL,
3465 pDeviceID,
3466 CM_DRP_CONFIGFLAGS,
3467 &ulDataType,
3468 (PBYTE)&ulConfigFlags,
3469 &ulTransferLength,
3470 &ulLength,
3471 0);
3472 if (ret != CR_SUCCESS)
3473 ulConfigFlags = 0;
3474
3475 if (ulConfigFlags & CONFIGFLAG_MANUAL_INSTALL)
3476 *pulStatus |= DN_MANUAL;
3477
3478 /* Check for failed install */
3479 if (((*pulStatus & DN_HAS_PROBLEM) == 0) && (ulConfigFlags & CONFIGFLAG_FAILEDINSTALL))
3480 {
3481 *pulStatus |= DN_HAS_PROBLEM;
3482 *pulProblem = CM_PROB_FAILED_INSTALL;
3483 }
3484
3485 return CR_SUCCESS;
3486 }
3487
3488
3489 /* Function 31 */
3490 DWORD
3491 WINAPI
PNP_SetDeviceProblem(handle_t hBinding,LPWSTR pDeviceID,DWORD ulProblem,DWORD ulFlags)3492 PNP_SetDeviceProblem(
3493 handle_t hBinding,
3494 LPWSTR pDeviceID,
3495 DWORD ulProblem,
3496 DWORD ulFlags)
3497 {
3498 ULONG ulOldStatus, ulOldProblem;
3499 CONFIGRET ret = CR_SUCCESS;
3500
3501 UNREFERENCED_PARAMETER(hBinding);
3502
3503 DPRINT1("PNP_SetDeviceProblem(%p %S %lu 0x%08lx)\n",
3504 hBinding, pDeviceID, ulProblem, ulFlags);
3505
3506 if (ulFlags & ~CM_SET_DEVNODE_PROBLEM_BITS)
3507 return CR_INVALID_FLAG;
3508
3509 if (!IsValidDeviceInstanceID(pDeviceID))
3510 return CR_INVALID_DEVINST;
3511
3512 ret = GetDeviceStatus(pDeviceID,
3513 &ulOldStatus,
3514 &ulOldProblem);
3515 if (ret != CR_SUCCESS)
3516 return ret;
3517
3518 if (((ulFlags & CM_SET_DEVNODE_PROBLEM_OVERRIDE) == 0) &&
3519 (ulOldProblem != 0) &&
3520 (ulOldProblem != ulProblem))
3521 {
3522 return CR_FAILURE;
3523 }
3524
3525 if (ulProblem == 0)
3526 {
3527 ret = ClearDeviceStatus(pDeviceID,
3528 DN_HAS_PROBLEM,
3529 ulOldProblem);
3530 }
3531 else
3532 {
3533 ret = SetDeviceStatus(pDeviceID,
3534 DN_HAS_PROBLEM,
3535 ulProblem);
3536 }
3537
3538 return ret;
3539 }
3540
3541
3542 /* Function 32 */
3543 DWORD
3544 WINAPI
PNP_DisableDevInst(handle_t hBinding,LPWSTR pDeviceID,PPNP_VETO_TYPE pVetoType,LPWSTR pszVetoName,DWORD ulNameLength,DWORD ulFlags)3545 PNP_DisableDevInst(
3546 handle_t hBinding,
3547 LPWSTR pDeviceID,
3548 PPNP_VETO_TYPE pVetoType,
3549 LPWSTR pszVetoName,
3550 DWORD ulNameLength,
3551 DWORD ulFlags)
3552 {
3553 UNREFERENCED_PARAMETER(hBinding);
3554
3555 DPRINT1("PNP_DisableDevInst(%p %S %p %p %lu 0x%08lx)\n",
3556 hBinding, pDeviceID, pVetoType, pszVetoName, ulNameLength, ulFlags);
3557
3558 if (ulFlags & ~CM_DISABLE_BITS)
3559 return CR_INVALID_FLAG;
3560
3561 if (!IsValidDeviceInstanceID(pDeviceID) ||
3562 IsRootDeviceInstanceID(pDeviceID))
3563 return CR_INVALID_DEVINST;
3564
3565 return DisableDeviceInstance(pDeviceID,
3566 pVetoType,
3567 pszVetoName,
3568 ulNameLength);
3569 }
3570
3571
3572 /* Function 33 */
3573 DWORD
3574 WINAPI
PNP_UninstallDevInst(handle_t hBinding,LPWSTR pDeviceID,DWORD ulFlags)3575 PNP_UninstallDevInst(
3576 handle_t hBinding,
3577 LPWSTR pDeviceID,
3578 DWORD ulFlags)
3579 {
3580 UNIMPLEMENTED;
3581 return CR_CALL_NOT_IMPLEMENTED;
3582 }
3583
3584
3585 static BOOL
CheckForDeviceId(LPWSTR lpDeviceIdList,LPWSTR lpDeviceId)3586 CheckForDeviceId(LPWSTR lpDeviceIdList,
3587 LPWSTR lpDeviceId)
3588 {
3589 LPWSTR lpPtr;
3590 DWORD dwLength;
3591
3592 lpPtr = lpDeviceIdList;
3593 while (*lpPtr != 0)
3594 {
3595 dwLength = wcslen(lpPtr);
3596 if (0 == _wcsicmp(lpPtr, lpDeviceId))
3597 return TRUE;
3598
3599 lpPtr += (dwLength + 1);
3600 }
3601
3602 return FALSE;
3603 }
3604
3605
3606 static VOID
AppendDeviceId(LPWSTR lpDeviceIdList,LPDWORD lpDeviceIdListSize,LPWSTR lpDeviceId)3607 AppendDeviceId(LPWSTR lpDeviceIdList,
3608 LPDWORD lpDeviceIdListSize,
3609 LPWSTR lpDeviceId)
3610 {
3611 DWORD dwLen;
3612 DWORD dwPos;
3613
3614 dwLen = wcslen(lpDeviceId);
3615 dwPos = (*lpDeviceIdListSize / sizeof(WCHAR)) - 1;
3616
3617 wcscpy(&lpDeviceIdList[dwPos], lpDeviceId);
3618
3619 dwPos += (dwLen + 1);
3620
3621 lpDeviceIdList[dwPos] = 0;
3622
3623 *lpDeviceIdListSize = dwPos * sizeof(WCHAR);
3624 }
3625
3626
3627 /* Function 34 */
3628 DWORD
3629 WINAPI
PNP_AddID(handle_t hBinding,LPWSTR pszDeviceID,LPWSTR pszID,DWORD ulFlags)3630 PNP_AddID(
3631 handle_t hBinding,
3632 LPWSTR pszDeviceID,
3633 LPWSTR pszID,
3634 DWORD ulFlags)
3635 {
3636 CONFIGRET ret = CR_SUCCESS;
3637 HKEY hDeviceKey;
3638 LPWSTR pszSubKey;
3639 DWORD dwDeviceIdListSize;
3640 DWORD dwNewDeviceIdSize;
3641 WCHAR * pszDeviceIdList = NULL;
3642
3643 UNREFERENCED_PARAMETER(hBinding);
3644
3645 DPRINT("PNP_AddID(%p %S %S 0x%08lx)\n",
3646 hBinding, pszDeviceID, pszID, ulFlags);
3647
3648 if (RegOpenKeyExW(hEnumKey,
3649 pszDeviceID,
3650 0,
3651 KEY_QUERY_VALUE | KEY_SET_VALUE,
3652 &hDeviceKey) != ERROR_SUCCESS)
3653 {
3654 DPRINT("Failed to open the device key!\n");
3655 return CR_INVALID_DEVNODE;
3656 }
3657
3658 pszSubKey = (ulFlags & CM_ADD_ID_COMPATIBLE) ? L"CompatibleIDs" : L"HardwareID";
3659
3660 if (RegQueryValueExW(hDeviceKey,
3661 pszSubKey,
3662 NULL,
3663 NULL,
3664 NULL,
3665 &dwDeviceIdListSize) != ERROR_SUCCESS)
3666 {
3667 DPRINT("Failed to query the desired ID string!\n");
3668 ret = CR_REGISTRY_ERROR;
3669 goto Done;
3670 }
3671
3672 dwNewDeviceIdSize = lstrlenW(pszDeviceID);
3673 if (!dwNewDeviceIdSize)
3674 {
3675 ret = CR_INVALID_POINTER;
3676 goto Done;
3677 }
3678
3679 dwDeviceIdListSize += (dwNewDeviceIdSize + 2) * sizeof(WCHAR);
3680
3681 pszDeviceIdList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeviceIdListSize);
3682 if (!pszDeviceIdList)
3683 {
3684 DPRINT("Failed to allocate memory for the desired ID string!\n");
3685 ret = CR_OUT_OF_MEMORY;
3686 goto Done;
3687 }
3688
3689 if (RegQueryValueExW(hDeviceKey,
3690 pszSubKey,
3691 NULL,
3692 NULL,
3693 (LPBYTE)pszDeviceIdList,
3694 &dwDeviceIdListSize) != ERROR_SUCCESS)
3695 {
3696 DPRINT("Failed to query the desired ID string!\n");
3697 ret = CR_REGISTRY_ERROR;
3698 goto Done;
3699 }
3700
3701 /* Check whether the device ID is already in use */
3702 if (CheckForDeviceId(pszDeviceIdList, pszDeviceID))
3703 {
3704 DPRINT("Device ID was found in the ID string!\n");
3705 ret = CR_SUCCESS;
3706 goto Done;
3707 }
3708
3709 /* Append the Device ID */
3710 AppendDeviceId(pszDeviceIdList, &dwDeviceIdListSize, pszID);
3711
3712 if (RegSetValueExW(hDeviceKey,
3713 pszSubKey,
3714 0,
3715 REG_MULTI_SZ,
3716 (LPBYTE)pszDeviceIdList,
3717 dwDeviceIdListSize) != ERROR_SUCCESS)
3718 {
3719 DPRINT("Failed to set the desired ID string!\n");
3720 ret = CR_REGISTRY_ERROR;
3721 }
3722
3723 Done:
3724 RegCloseKey(hDeviceKey);
3725 if (pszDeviceIdList)
3726 HeapFree(GetProcessHeap(), 0, pszDeviceIdList);
3727
3728 DPRINT("PNP_AddID() done (returns %lx)\n", ret);
3729
3730 return ret;
3731 }
3732
3733
3734 /* Function 35 */
3735 DWORD
3736 WINAPI
PNP_RegisterDriver(handle_t hBinding,LPWSTR pszDeviceID,DWORD ulFlags)3737 PNP_RegisterDriver(
3738 handle_t hBinding,
3739 LPWSTR pszDeviceID,
3740 DWORD ulFlags)
3741 {
3742 DPRINT("PNP_RegisterDriver(%p %S 0x%lx)\n",
3743 hBinding, pszDeviceID, ulFlags);
3744
3745 if (ulFlags & ~CM_REGISTER_DEVICE_DRIVER_BITS)
3746 return CR_INVALID_FLAG;
3747
3748 if (!IsValidDeviceInstanceID(pszDeviceID))
3749 return CR_INVALID_DEVINST;
3750
3751 SetDeviceStatus(pszDeviceID, 0, 0);
3752
3753 return CR_SUCCESS;
3754 }
3755
3756
3757 /* Function 36 */
3758 DWORD
3759 WINAPI
PNP_QueryRemove(handle_t hBinding,LPWSTR pszDeviceID,PPNP_VETO_TYPE pVetoType,LPWSTR pszVetoName,DWORD ulNameLength,DWORD ulFlags)3760 PNP_QueryRemove(
3761 handle_t hBinding,
3762 LPWSTR pszDeviceID,
3763 PPNP_VETO_TYPE pVetoType,
3764 LPWSTR pszVetoName,
3765 DWORD ulNameLength,
3766 DWORD ulFlags)
3767 {
3768 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData;
3769 NTSTATUS Status;
3770 DWORD ret = CR_SUCCESS;
3771
3772 DPRINT1("PNP_QueryRemove(%p %S %p %p %lu 0x%lx)\n",
3773 hBinding, pszDeviceID, pVetoType, pszVetoName,
3774 ulNameLength, ulFlags);
3775
3776 if (ulFlags & ~CM_REMOVE_BITS)
3777 return CR_INVALID_FLAG;
3778
3779 if (!IsValidDeviceInstanceID(pszDeviceID) ||
3780 IsRootDeviceInstanceID(pszDeviceID))
3781 return CR_INVALID_DEVINST;
3782
3783 if (pVetoType != NULL)
3784 *pVetoType = PNP_VetoTypeUnknown;
3785
3786 if (pszVetoName != NULL && ulNameLength > 0)
3787 *pszVetoName = UNICODE_NULL;
3788
3789 RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData));
3790 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
3791 pszDeviceID);
3792 PlugPlayData.VetoName = pszVetoName;
3793 PlugPlayData.NameLength = ulNameLength;
3794 // PlugPlayData.Flags =
3795
3796 Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice,
3797 &PlugPlayData,
3798 sizeof(PlugPlayData));
3799 if (!NT_SUCCESS(Status))
3800 ret = NtStatusToCrError(Status);
3801
3802 return ret;
3803 }
3804
3805
3806 /* Function 37 */
3807 DWORD
3808 WINAPI
PNP_RequestDeviceEject(handle_t hBinding,LPWSTR pszDeviceID,PPNP_VETO_TYPE pVetoType,LPWSTR pszVetoName,DWORD ulNameLength,DWORD ulFlags)3809 PNP_RequestDeviceEject(
3810 handle_t hBinding,
3811 LPWSTR pszDeviceID,
3812 PPNP_VETO_TYPE pVetoType,
3813 LPWSTR pszVetoName,
3814 DWORD ulNameLength,
3815 DWORD ulFlags)
3816 {
3817 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData;
3818 NTSTATUS Status;
3819 DWORD ret = CR_SUCCESS;
3820
3821 DPRINT1("PNP_RequestDeviceEject(%p %S %p %p %lu 0x%lx)\n",
3822 hBinding, pszDeviceID, pVetoType, pszVetoName,
3823 ulNameLength, ulFlags);
3824
3825 if (ulFlags != 0)
3826 return CR_INVALID_FLAG;
3827
3828 if (!IsValidDeviceInstanceID(pszDeviceID))
3829 return CR_INVALID_DEVINST;
3830
3831 if (pVetoType != NULL)
3832 *pVetoType = PNP_VetoTypeUnknown;
3833
3834 if (pszVetoName != NULL && ulNameLength > 0)
3835 *pszVetoName = UNICODE_NULL;
3836
3837 RtlZeroMemory(&PlugPlayData, sizeof(PlugPlayData));
3838 RtlInitUnicodeString(&PlugPlayData.DeviceInstance,
3839 pszDeviceID);
3840 PlugPlayData.VetoName = pszVetoName;
3841 PlugPlayData.NameLength = ulNameLength;
3842 // PlugPlayData.Flags =
3843
3844 Status = NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice,
3845 &PlugPlayData,
3846 sizeof(PlugPlayData));
3847 if (!NT_SUCCESS(Status))
3848 ret = NtStatusToCrError(Status);
3849
3850 return ret;
3851 }
3852
3853
3854 /* Function 38 */
3855 CONFIGRET
3856 WINAPI
PNP_IsDockStationPresent(handle_t hBinding,BOOL * Present)3857 PNP_IsDockStationPresent(
3858 handle_t hBinding,
3859 BOOL *Present)
3860 {
3861 HKEY hKey;
3862 DWORD dwType;
3863 DWORD dwValue;
3864 DWORD dwSize;
3865 CONFIGRET ret = CR_SUCCESS;
3866
3867 UNREFERENCED_PARAMETER(hBinding);
3868
3869 DPRINT1("PNP_IsDockStationPresent(%p %p)\n",
3870 hBinding, Present);
3871
3872 *Present = FALSE;
3873
3874 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG,
3875 L"CurrentDockInfo",
3876 0,
3877 KEY_READ,
3878 &hKey) != ERROR_SUCCESS)
3879 return CR_REGISTRY_ERROR;
3880
3881 dwSize = sizeof(DWORD);
3882 if (RegQueryValueExW(hKey,
3883 L"DockingState",
3884 NULL,
3885 &dwType,
3886 (LPBYTE)&dwValue,
3887 &dwSize) != ERROR_SUCCESS)
3888 ret = CR_REGISTRY_ERROR;
3889
3890 RegCloseKey(hKey);
3891
3892 if (ret == CR_SUCCESS)
3893 {
3894 if (dwType != REG_DWORD || dwSize != sizeof(DWORD))
3895 {
3896 ret = CR_REGISTRY_ERROR;
3897 }
3898 else if (dwValue != 0)
3899 {
3900 *Present = TRUE;
3901 }
3902 }
3903
3904 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret);
3905
3906 return ret;
3907 }
3908
3909
3910 /* Function 39 */
3911 DWORD
3912 WINAPI
PNP_RequestEjectPC(handle_t hBinding)3913 PNP_RequestEjectPC(
3914 handle_t hBinding)
3915 {
3916 WCHAR szDockDeviceInstance[MAX_DEVICE_ID_LEN];
3917 PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA DockData;
3918 NTSTATUS Status;
3919
3920 DPRINT("PNP_RequestEjectPC(%p)\n", hBinding);
3921
3922 /* Retrieve the dock device */
3923 DockData.DeviceInstanceLength = ARRAYSIZE(szDockDeviceInstance);
3924 DockData.DeviceInstance = szDockDeviceInstance;
3925
3926 Status = NtPlugPlayControl(PlugPlayControlRetrieveDock,
3927 &DockData,
3928 sizeof(DockData));
3929 if (!NT_SUCCESS(Status))
3930 return NtStatusToCrError(Status);
3931
3932 /* Eject the dock device */
3933 return PNP_RequestDeviceEject(hBinding,
3934 szDockDeviceInstance,
3935 NULL,
3936 NULL,
3937 0,
3938 0);
3939 }
3940
3941
3942 /* Function 40 */
3943 DWORD
3944 WINAPI
PNP_HwProfFlags(handle_t hBinding,DWORD ulAction,LPWSTR pDeviceID,DWORD ulConfig,DWORD * pulValue,PPNP_VETO_TYPE pVetoType,LPWSTR pszVetoName,DWORD ulNameLength,DWORD ulFlags)3945 PNP_HwProfFlags(
3946 handle_t hBinding,
3947 DWORD ulAction,
3948 LPWSTR pDeviceID,
3949 DWORD ulConfig,
3950 DWORD *pulValue,
3951 PPNP_VETO_TYPE pVetoType,
3952 LPWSTR pszVetoName,
3953 DWORD ulNameLength,
3954 DWORD ulFlags)
3955 {
3956 CONFIGRET ret = CR_SUCCESS;
3957 WCHAR szKeyName[MAX_PATH];
3958 HKEY hKey;
3959 HKEY hDeviceKey;
3960 DWORD dwSize;
3961
3962 UNREFERENCED_PARAMETER(hBinding);
3963
3964 DPRINT("PNP_HwProfFlags() called\n");
3965
3966 if (!IsValidDeviceInstanceID(pDeviceID))
3967 return CR_INVALID_DEVINST;
3968
3969 if (ulConfig == 0)
3970 {
3971 wcscpy(szKeyName,
3972 L"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
3973 }
3974 else
3975 {
3976 swprintf(szKeyName,
3977 L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
3978 ulConfig);
3979 }
3980
3981 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
3982 szKeyName,
3983 0,
3984 KEY_QUERY_VALUE,
3985 &hKey) != ERROR_SUCCESS)
3986 return CR_REGISTRY_ERROR;
3987
3988 if (ulAction == PNP_GET_HWPROFFLAGS)
3989 {
3990 if (RegOpenKeyExW(hKey,
3991 pDeviceID,
3992 0,
3993 KEY_QUERY_VALUE,
3994 &hDeviceKey) != ERROR_SUCCESS)
3995 {
3996 *pulValue = 0;
3997 }
3998 else
3999 {
4000 dwSize = sizeof(DWORD);
4001 if (RegQueryValueExW(hDeviceKey,
4002 L"CSConfigFlags",
4003 NULL,
4004 NULL,
4005 (LPBYTE)pulValue,
4006 &dwSize) != ERROR_SUCCESS)
4007 {
4008 *pulValue = 0;
4009 }
4010
4011 RegCloseKey(hDeviceKey);
4012 }
4013 }
4014 else if (ulAction == PNP_SET_HWPROFFLAGS)
4015 {
4016 /* FIXME: not implemented yet */
4017 ret = CR_CALL_NOT_IMPLEMENTED;
4018 }
4019
4020 RegCloseKey(hKey);
4021
4022 return ret;
4023 }
4024
4025
4026 /* Function 41 */
4027 DWORD
4028 WINAPI
PNP_GetHwProfInfo(handle_t hBinding,DWORD ulIndex,HWPROFILEINFO * pHWProfileInfo,DWORD ulProfileInfoSize,DWORD ulFlags)4029 PNP_GetHwProfInfo(
4030 handle_t hBinding,
4031 DWORD ulIndex,
4032 HWPROFILEINFO *pHWProfileInfo,
4033 DWORD ulProfileInfoSize,
4034 DWORD ulFlags)
4035 {
4036 WCHAR szProfileName[5];
4037 HKEY hKeyConfig = NULL;
4038 HKEY hKeyProfiles = NULL;
4039 HKEY hKeyProfile = NULL;
4040 DWORD dwDisposition;
4041 DWORD dwSize;
4042 LONG lError;
4043 CONFIGRET ret = CR_SUCCESS;
4044
4045 UNREFERENCED_PARAMETER(hBinding);
4046
4047 DPRINT("PNP_GetHwProfInfo() called\n");
4048
4049 if (ulProfileInfoSize == 0)
4050 {
4051 ret = CR_INVALID_DATA;
4052 goto done;
4053 }
4054
4055 if (ulFlags != 0)
4056 {
4057 ret = CR_INVALID_FLAG;
4058 goto done;
4059 }
4060
4061 /* Initialize the profile information */
4062 pHWProfileInfo->HWPI_ulHWProfile = 0;
4063 pHWProfileInfo->HWPI_szFriendlyName[0] = 0;
4064 pHWProfileInfo->HWPI_dwFlags = 0;
4065
4066 /* Open the 'IDConfigDB' key */
4067 lError = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
4068 L"System\\CurrentControlSet\\Control\\IDConfigDB",
4069 0,
4070 NULL,
4071 REG_OPTION_NON_VOLATILE,
4072 KEY_QUERY_VALUE,
4073 NULL,
4074 &hKeyConfig,
4075 &dwDisposition);
4076 if (lError != ERROR_SUCCESS)
4077 {
4078 ret = CR_REGISTRY_ERROR;
4079 goto done;
4080 }
4081
4082 /* Open the 'Hardware Profiles' subkey */
4083 lError = RegCreateKeyExW(hKeyConfig,
4084 L"Hardware Profiles",
4085 0,
4086 NULL,
4087 REG_OPTION_NON_VOLATILE,
4088 KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
4089 NULL,
4090 &hKeyProfiles,
4091 &dwDisposition);
4092 if (lError != ERROR_SUCCESS)
4093 {
4094 ret = CR_REGISTRY_ERROR;
4095 goto done;
4096 }
4097
4098 if (ulIndex == (ULONG)-1)
4099 {
4100 dwSize = sizeof(ULONG);
4101 lError = RegQueryValueExW(hKeyConfig,
4102 L"CurrentConfig",
4103 NULL,
4104 NULL,
4105 (LPBYTE)&pHWProfileInfo->HWPI_ulHWProfile,
4106 &dwSize);
4107 if (lError != ERROR_SUCCESS)
4108 {
4109 pHWProfileInfo->HWPI_ulHWProfile = 0;
4110 ret = CR_REGISTRY_ERROR;
4111 goto done;
4112 }
4113 }
4114 else
4115 {
4116 /* FIXME: not implemented yet */
4117 ret = CR_CALL_NOT_IMPLEMENTED;
4118 goto done;
4119 }
4120
4121 swprintf(szProfileName, L"%04lu", pHWProfileInfo->HWPI_ulHWProfile);
4122
4123 lError = RegOpenKeyExW(hKeyProfiles,
4124 szProfileName,
4125 0,
4126 KEY_QUERY_VALUE,
4127 &hKeyProfile);
4128 if (lError != ERROR_SUCCESS)
4129 {
4130 ret = CR_REGISTRY_ERROR;
4131 goto done;
4132 }
4133
4134 dwSize = sizeof(pHWProfileInfo->HWPI_szFriendlyName);
4135 lError = RegQueryValueExW(hKeyProfile,
4136 L"FriendlyName",
4137 NULL,
4138 NULL,
4139 (LPBYTE)&pHWProfileInfo->HWPI_szFriendlyName,
4140 &dwSize);
4141 if (lError != ERROR_SUCCESS)
4142 {
4143 ret = CR_REGISTRY_ERROR;
4144 goto done;
4145 }
4146
4147 done:
4148 if (hKeyProfile != NULL)
4149 RegCloseKey(hKeyProfile);
4150
4151 if (hKeyProfiles != NULL)
4152 RegCloseKey(hKeyProfiles);
4153
4154 if (hKeyConfig != NULL)
4155 RegCloseKey(hKeyConfig);
4156
4157 return ret;
4158 }
4159
4160
4161 /* Function 42 */
4162 DWORD
4163 WINAPI
PNP_AddEmptyLogConf(handle_t hBinding,LPWSTR pDeviceID,DWORD ulPriority,DWORD * pulLogConfTag,DWORD ulFlags)4164 PNP_AddEmptyLogConf(
4165 handle_t hBinding,
4166 LPWSTR pDeviceID,
4167 DWORD ulPriority,
4168 DWORD *pulLogConfTag,
4169 DWORD ulFlags)
4170 {
4171 UNIMPLEMENTED;
4172 return CR_CALL_NOT_IMPLEMENTED;
4173 }
4174
4175
4176 /* Function 43 */
4177 DWORD
4178 WINAPI
PNP_FreeLogConf(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfType,DWORD ulLogConfTag,DWORD ulFlags)4179 PNP_FreeLogConf(
4180 handle_t hBinding,
4181 LPWSTR pDeviceID,
4182 DWORD ulLogConfType,
4183 DWORD ulLogConfTag,
4184 DWORD ulFlags)
4185 {
4186 UNIMPLEMENTED;
4187 return CR_CALL_NOT_IMPLEMENTED;
4188 }
4189
4190
4191 /* Function 44 */
4192 DWORD
4193 WINAPI
PNP_GetFirstLogConf(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfType,DWORD * pulLogConfTag,DWORD ulFlags)4194 PNP_GetFirstLogConf(
4195 handle_t hBinding,
4196 LPWSTR pDeviceID,
4197 DWORD ulLogConfType,
4198 DWORD *pulLogConfTag,
4199 DWORD ulFlags)
4200 {
4201 HKEY hConfigKey = NULL;
4202 DWORD RegDataType = 0;
4203 ULONG ulDataSize = 0;
4204 LPBYTE lpData = NULL;
4205 CONFIGRET ret = CR_SUCCESS;
4206
4207 DPRINT("PNP_GetFirstLogConf(%p %S %lu %p 0x%08lx)\n",
4208 hBinding, pDeviceID, ulLogConfType, pulLogConfTag, ulFlags);
4209
4210 if (pulLogConfTag == NULL)
4211 return CR_INVALID_POINTER;
4212
4213 *pulLogConfTag = (DWORD)0;
4214
4215 if (ulFlags & ~LOG_CONF_BITS)
4216 return CR_INVALID_FLAG;
4217
4218 if (!IsValidDeviceInstanceID(pDeviceID))
4219 return CR_INVALID_DEVINST;
4220
4221 ret = OpenConfigurationKey(pDeviceID,
4222 ulLogConfType,
4223 &hConfigKey);
4224 if (ret != CR_SUCCESS)
4225 {
4226 DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4227 ret = CR_NO_MORE_LOG_CONF;
4228 goto done;
4229 }
4230
4231 ret = GetConfigurationData(hConfigKey,
4232 ulLogConfType,
4233 &RegDataType,
4234 &ulDataSize,
4235 &lpData);
4236 if (ret != CR_SUCCESS)
4237 {
4238 DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4239 ret = CR_NO_MORE_LOG_CONF;
4240 goto done;
4241 }
4242
4243 DPRINT1("Data size %lu\n", ulDataSize);
4244 if (ulDataSize == 0 || lpData == NULL)
4245 {
4246 DPRINT1("No config data available!\n");
4247 ret = CR_NO_MORE_LOG_CONF;
4248 goto done;
4249 }
4250
4251 /* Get the first tag */
4252 if (RegDataType == REG_RESOURCE_LIST)
4253 {
4254 DPRINT("REG_RESOURCE_LIST->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count);
4255
4256 /* Fail, if we do not have any resource */
4257 if (((PCM_RESOURCE_LIST)lpData)->Count == 0)
4258 {
4259 DPRINT1("No resource descriptors!\n");
4260 ret = CR_NO_MORE_LOG_CONF;
4261 goto done;
4262 }
4263 }
4264 else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4265 {
4266 DPRINT("REG_RESOURCE_REQUIREMENTS_LIST->AlternativeLists %lu\n",
4267 ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists);
4268
4269 /* Fail, if we do not have any requirements */
4270 if (((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists == 0)
4271 {
4272 ret = CR_NO_MORE_LOG_CONF;
4273 goto done;
4274 }
4275 }
4276
4277 done:
4278 if (lpData != NULL)
4279 HeapFree(GetProcessHeap(), 0, lpData);
4280
4281 if (hConfigKey != NULL)
4282 RegCloseKey(hConfigKey);
4283
4284 DPRINT("PNP_GetFirstLogConf() returns %lu\n", ret);
4285
4286 return ret;
4287 }
4288
4289
4290 /* Function 45 */
4291 DWORD
4292 WINAPI
PNP_GetNextLogConf(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfType,DWORD ulCurrentTag,DWORD * pulNextTag,DWORD ulFlags)4293 PNP_GetNextLogConf(
4294 handle_t hBinding,
4295 LPWSTR pDeviceID,
4296 DWORD ulLogConfType,
4297 DWORD ulCurrentTag,
4298 DWORD *pulNextTag,
4299 DWORD ulFlags)
4300 {
4301 HKEY hConfigKey = NULL;
4302 DWORD RegDataType = 0;
4303 ULONG ulDataSize = 0;
4304 LPBYTE lpData = NULL;
4305 CONFIGRET ret = CR_SUCCESS;
4306
4307 DPRINT("PNP_GetNextLogConf(%p %S %lu %ul %p 0x%08lx)\n",
4308 hBinding, pDeviceID, ulLogConfType, ulCurrentTag, pulNextTag, ulFlags);
4309
4310 if (pulNextTag == NULL)
4311 return CR_INVALID_POINTER;
4312
4313 *pulNextTag = (DWORD)0;
4314
4315 if (ulFlags != 0)
4316 return CR_INVALID_FLAG;
4317
4318 if (!IsValidDeviceInstanceID(pDeviceID))
4319 return CR_INVALID_DEVINST;
4320
4321 ret = OpenConfigurationKey(pDeviceID,
4322 ulLogConfType,
4323 &hConfigKey);
4324 if (ret != CR_SUCCESS)
4325 {
4326 DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4327 ret = CR_NO_MORE_LOG_CONF;
4328 goto done;
4329 }
4330
4331 ret = GetConfigurationData(hConfigKey,
4332 ulLogConfType,
4333 &RegDataType,
4334 &ulDataSize,
4335 &lpData);
4336 if (ret != CR_SUCCESS)
4337 {
4338 DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4339 ret = CR_NO_MORE_LOG_CONF;
4340 goto done;
4341 }
4342
4343 DPRINT("Data size %lu\n", ulDataSize);
4344
4345 if (ulDataSize == 0 || lpData == NULL)
4346 {
4347 DPRINT1("No config data available!\n");
4348 ret = CR_NO_MORE_LOG_CONF;
4349 goto done;
4350 }
4351
4352 /* Check if the next entry is available */
4353 if (RegDataType == REG_RESOURCE_LIST)
4354 {
4355 DPRINT("REG_RESOURCE_LIST->Count %lu\n", ((PCM_RESOURCE_LIST)lpData)->Count);
4356
4357 /* Fail, if we are beyond the end of the list */
4358 if (ulCurrentTag >= ((PCM_RESOURCE_LIST)lpData)->Count)
4359 {
4360 ret = CR_INVALID_LOG_CONF;
4361 goto done;
4362 }
4363
4364 /* Indicate that we reached the end of the list */
4365 if (ulCurrentTag == ((PCM_RESOURCE_LIST)lpData)->Count - 1)
4366 {
4367 ret = CR_NO_MORE_LOG_CONF;
4368 goto done;
4369 }
4370 }
4371 else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4372 {
4373 DPRINT("REG_RESOURCE_REQUIREMENTS_LIST->AlternativeLists %lu\n",
4374 ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists);
4375
4376 /* Fail, if we are beyond the end of the list */
4377 if (ulCurrentTag >= ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists)
4378 {
4379 ret = CR_INVALID_LOG_CONF;
4380 goto done;
4381 }
4382
4383 /* Indicate that we reached the end of the list */
4384 if (ulCurrentTag == ((PIO_RESOURCE_REQUIREMENTS_LIST)lpData)->AlternativeLists - 1)
4385 {
4386 ret = CR_NO_MORE_LOG_CONF;
4387 goto done;
4388 }
4389 }
4390
4391 /* Return the next tag value */
4392 *pulNextTag = ulCurrentTag + 1;
4393
4394 done:
4395 if (lpData != NULL)
4396 HeapFree(GetProcessHeap(), 0, lpData);
4397
4398 if (hConfigKey != NULL)
4399 RegCloseKey(hConfigKey);
4400
4401 DPRINT("PNP_GetNextLogConf() returns %lu\n", ret);
4402
4403 return ret;
4404 }
4405
4406
4407 /* Function 46 */
4408 DWORD
4409 WINAPI
PNP_GetLogConfPriority(handle_t hBinding,LPWSTR pDeviceID,DWORD ulType,DWORD ulTag,DWORD * pPriority,DWORD ulFlags)4410 PNP_GetLogConfPriority(
4411 handle_t hBinding,
4412 LPWSTR pDeviceID,
4413 DWORD ulType,
4414 DWORD ulTag,
4415 DWORD *pPriority,
4416 DWORD ulFlags)
4417 {
4418 UNIMPLEMENTED;
4419 return CR_CALL_NOT_IMPLEMENTED;
4420 }
4421
4422
4423 /* Function 47 */
4424 DWORD
4425 WINAPI
PNP_AddResDes(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfTag,DWORD ulLogConfType,RESOURCEID ResourceID,DWORD * pulResourceTag,BYTE * ResourceData,PNP_RPC_BUFFER_SIZE ResourceLen,DWORD ulFlags)4426 PNP_AddResDes(
4427 handle_t hBinding,
4428 LPWSTR pDeviceID,
4429 DWORD ulLogConfTag,
4430 DWORD ulLogConfType,
4431 RESOURCEID ResourceID,
4432 DWORD *pulResourceTag,
4433 BYTE *ResourceData,
4434 PNP_RPC_BUFFER_SIZE ResourceLen,
4435 DWORD ulFlags)
4436 {
4437 UNIMPLEMENTED;
4438 return CR_CALL_NOT_IMPLEMENTED;
4439 }
4440
4441
4442 /* Function 48 */
4443 DWORD
4444 WINAPI
PNP_FreeResDes(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfTag,DWORD ulLogConfType,RESOURCEID ResourceID,DWORD ulResourceTag,DWORD * pulPreviousResType,DWORD * pulPreviousResTag,DWORD ulFlags)4445 PNP_FreeResDes(
4446 handle_t hBinding,
4447 LPWSTR pDeviceID,
4448 DWORD ulLogConfTag,
4449 DWORD ulLogConfType,
4450 RESOURCEID ResourceID,
4451 DWORD ulResourceTag,
4452 DWORD *pulPreviousResType,
4453 DWORD *pulPreviousResTag,
4454 DWORD ulFlags)
4455 {
4456 UNIMPLEMENTED;
4457 return CR_CALL_NOT_IMPLEMENTED;
4458 }
4459
4460
4461 /* Function 49 */
4462 DWORD
4463 WINAPI
PNP_GetNextResDes(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfTag,DWORD ulLogConfType,RESOURCEID ResourceID,DWORD ulResourceTag,DWORD * pulNextResType,DWORD * pulNextResTag,DWORD ulFlags)4464 PNP_GetNextResDes(
4465 handle_t hBinding,
4466 LPWSTR pDeviceID,
4467 DWORD ulLogConfTag,
4468 DWORD ulLogConfType,
4469 RESOURCEID ResourceID,
4470 DWORD ulResourceTag,
4471 DWORD *pulNextResType,
4472 DWORD *pulNextResTag,
4473 DWORD ulFlags)
4474 {
4475 HKEY hConfigKey = NULL;
4476 DWORD RegDataType = 0;
4477 ULONG ulDataSize = 0;
4478 LPBYTE lpData = NULL;
4479 CONFIGRET ret = CR_SUCCESS;
4480
4481 DPRINT1("PNP_GetNextResDes(%p %S 0x%lx %lu %lu %ul %p %p 0x%08lx)\n",
4482 hBinding, pDeviceID, ulLogConfTag, ulLogConfType, ResourceID,
4483 ulResourceTag, pulNextResType, pulNextResTag, ulFlags);
4484
4485 if (pulNextResType == NULL)
4486 return CR_INVALID_POINTER;
4487
4488 *pulNextResType = 0;
4489
4490 if (ulFlags != 0)
4491 return CR_INVALID_FLAG;
4492
4493 if (!IsValidDeviceInstanceID(pDeviceID))
4494 return CR_INVALID_DEVINST;
4495
4496 ret = OpenConfigurationKey(pDeviceID,
4497 ulLogConfType,
4498 &hConfigKey);
4499 if (ret != CR_SUCCESS)
4500 {
4501 DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret);
4502 ret = CR_NO_MORE_LOG_CONF;
4503 goto done;
4504 }
4505
4506 ret = GetConfigurationData(hConfigKey,
4507 ulLogConfType,
4508 &RegDataType,
4509 &ulDataSize,
4510 &lpData);
4511 if (ret != CR_SUCCESS)
4512 {
4513 DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret);
4514 ret = CR_NO_MORE_LOG_CONF;
4515 goto done;
4516 }
4517
4518 DPRINT1("Data size %lu\n", ulDataSize);
4519
4520 if (ulDataSize == 0 || lpData == NULL)
4521 {
4522 DPRINT1("No config data available!\n");
4523 ret = CR_NO_MORE_LOG_CONF;
4524 goto done;
4525 }
4526
4527 /* Get the next resource descriptor */
4528 if (RegDataType == REG_RESOURCE_LIST)
4529 {
4530 DPRINT1("FIXME: REG_RESOURCE_LIST\n");
4531 /* FIXME */
4532 ret = CR_NO_MORE_LOG_CONF;
4533 goto done;
4534 }
4535 else if (RegDataType == REG_RESOURCE_REQUIREMENTS_LIST)
4536 {
4537 DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
4538 /* FIXME */
4539 ret = CR_NO_MORE_LOG_CONF;
4540 goto done;
4541 }
4542
4543 done:
4544 if (lpData != NULL)
4545 HeapFree(GetProcessHeap(), 0, lpData);
4546
4547 if (hConfigKey != NULL)
4548 RegCloseKey(hConfigKey);
4549
4550 DPRINT1("PNP_GetNextResDes() returns %lu\n", ret);
4551
4552 return ret;
4553 }
4554
4555
4556 /* Function 50 */
4557 DWORD
4558 WINAPI
PNP_GetResDesData(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfTag,DWORD ulLogConfType,RESOURCEID ResourceID,DWORD ulResourceTag,BYTE * Buffer,PNP_RPC_BUFFER_SIZE BufferLen,DWORD ulFlags)4559 PNP_GetResDesData(
4560 handle_t hBinding,
4561 LPWSTR pDeviceID,
4562 DWORD ulLogConfTag,
4563 DWORD ulLogConfType,
4564 RESOURCEID ResourceID,
4565 DWORD ulResourceTag,
4566 BYTE *Buffer,
4567 PNP_RPC_BUFFER_SIZE BufferLen,
4568 DWORD ulFlags)
4569 {
4570 UNIMPLEMENTED;
4571 return CR_CALL_NOT_IMPLEMENTED;
4572 }
4573
4574
4575 /* Function 51 */
4576 DWORD
4577 WINAPI
PNP_GetResDesDataSize(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfTag,DWORD ulLogConfType,RESOURCEID ResourceID,DWORD ulResourceTag,DWORD * pulSize,DWORD ulFlags)4578 PNP_GetResDesDataSize(
4579 handle_t hBinding,
4580 LPWSTR pDeviceID,
4581 DWORD ulLogConfTag,
4582 DWORD ulLogConfType,
4583 RESOURCEID ResourceID,
4584 DWORD ulResourceTag,
4585 DWORD *pulSize,
4586 DWORD ulFlags)
4587 {
4588 UNIMPLEMENTED;
4589 return CR_CALL_NOT_IMPLEMENTED;
4590 }
4591
4592
4593 /* Function 52 */
4594 DWORD
4595 WINAPI
PNP_ModifyResDes(handle_t hBinding,LPWSTR pDeviceID,DWORD ulLogConfTag,DWORD ulLogConfType,RESOURCEID CurrentResourceID,RESOURCEID NewResourceID,DWORD ulResourceTag,BYTE * ResourceData,PNP_RPC_BUFFER_SIZE ResourceLen,DWORD ulFlags)4596 PNP_ModifyResDes(
4597 handle_t hBinding,
4598 LPWSTR pDeviceID,
4599 DWORD ulLogConfTag,
4600 DWORD ulLogConfType,
4601 RESOURCEID CurrentResourceID,
4602 RESOURCEID NewResourceID,
4603 DWORD ulResourceTag,
4604 BYTE *ResourceData,
4605 PNP_RPC_BUFFER_SIZE ResourceLen,
4606 DWORD ulFlags)
4607 {
4608 UNIMPLEMENTED;
4609 return CR_CALL_NOT_IMPLEMENTED;
4610 }
4611
4612
4613 /* Function 53 */
4614 DWORD
4615 WINAPI
PNP_DetectResourceConflict(handle_t hBinding,LPWSTR pDeviceID,RESOURCEID ResourceID,BYTE * ResourceData,PNP_RPC_BUFFER_SIZE ResourceLen,BOOL * pbConflictDetected,DWORD ulFlags)4616 PNP_DetectResourceConflict(
4617 handle_t hBinding,
4618 LPWSTR pDeviceID,
4619 RESOURCEID ResourceID,
4620 BYTE *ResourceData,
4621 PNP_RPC_BUFFER_SIZE ResourceLen,
4622 BOOL *pbConflictDetected,
4623 DWORD ulFlags)
4624 {
4625 DPRINT("PNP_DetectResourceConflict()\n");
4626
4627 if (pbConflictDetected != NULL)
4628 *pbConflictDetected = FALSE;
4629
4630 return CR_CALL_NOT_IMPLEMENTED;
4631 }
4632
4633
4634 /* Function 54 */
4635 DWORD
4636 WINAPI
PNP_QueryResConfList(handle_t hBinding,LPWSTR pDeviceID,RESOURCEID ResourceID,BYTE * ResourceData,PNP_RPC_BUFFER_SIZE ResourceLen,BYTE * Buffer,PNP_RPC_BUFFER_SIZE BufferLen,DWORD ulFlags)4637 PNP_QueryResConfList(
4638 handle_t hBinding,
4639 LPWSTR pDeviceID,
4640 RESOURCEID ResourceID,
4641 BYTE *ResourceData,
4642 PNP_RPC_BUFFER_SIZE ResourceLen,
4643 BYTE *Buffer,
4644 PNP_RPC_BUFFER_SIZE BufferLen,
4645 DWORD ulFlags)
4646 {
4647 UNIMPLEMENTED;
4648 return CR_CALL_NOT_IMPLEMENTED;
4649 }
4650
4651
4652 /* Function 55 */
4653 DWORD
4654 WINAPI
PNP_SetHwProf(handle_t hBinding,DWORD ulHardwareProfile,DWORD ulFlags)4655 PNP_SetHwProf(
4656 handle_t hBinding,
4657 DWORD ulHardwareProfile,
4658 DWORD ulFlags)
4659 {
4660 return CR_CALL_NOT_IMPLEMENTED;
4661 }
4662
4663
4664 /* Function 56 */
4665 DWORD
4666 WINAPI
PNP_QueryArbitratorFreeData(handle_t hBinding,BYTE * pData,DWORD DataLen,LPWSTR pDeviceID,RESOURCEID ResourceID,DWORD ulFlags)4667 PNP_QueryArbitratorFreeData(
4668 handle_t hBinding,
4669 BYTE *pData,
4670 DWORD DataLen,
4671 LPWSTR pDeviceID,
4672 RESOURCEID ResourceID,
4673 DWORD ulFlags)
4674 {
4675 return CR_CALL_NOT_IMPLEMENTED;
4676 }
4677
4678
4679 /* Function 57 */
4680 DWORD
4681 WINAPI
PNP_QueryArbitratorFreeSize(handle_t hBinding,DWORD * pulSize,LPWSTR pDeviceID,RESOURCEID ResourceID,DWORD ulFlags)4682 PNP_QueryArbitratorFreeSize(
4683 handle_t hBinding,
4684 DWORD *pulSize,
4685 LPWSTR pDeviceID,
4686 RESOURCEID ResourceID,
4687 DWORD ulFlags)
4688 {
4689 if (pulSize != NULL)
4690 *pulSize = 0;
4691
4692 return CR_CALL_NOT_IMPLEMENTED;
4693 }
4694
4695
4696 /* Function 58 */
4697 CONFIGRET
4698 WINAPI
PNP_RunDetection(handle_t hBinding,DWORD ulFlags)4699 PNP_RunDetection(
4700 handle_t hBinding,
4701 DWORD ulFlags)
4702 {
4703 return CR_CALL_NOT_IMPLEMENTED;
4704 }
4705
4706
4707 /* Function 59 */
4708 DWORD
4709 WINAPI
PNP_RegisterNotification(handle_t hBinding,DWORD_PTR hRecipient,LPWSTR pszName,BYTE * pNotificationFilter,DWORD ulNotificationFilterSize,DWORD ulFlags,PNP_NOTIFY_HANDLE * pNotifyHandle,DWORD ulProcessId,DWORD * pulUnknown9)4710 PNP_RegisterNotification(
4711 handle_t hBinding,
4712 DWORD_PTR hRecipient,
4713 LPWSTR pszName,
4714 BYTE *pNotificationFilter,
4715 DWORD ulNotificationFilterSize,
4716 DWORD ulFlags,
4717 PNP_NOTIFY_HANDLE *pNotifyHandle,
4718 DWORD ulProcessId,
4719 DWORD *pulUnknown9)
4720 {
4721 PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface;
4722 PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle;
4723 PNOTIFY_ENTRY pNotifyData = NULL;
4724
4725 DPRINT1("PNP_RegisterNotification(%p %p '%S' %p %lu 0x%lx %p %lx %p)\n",
4726 hBinding, hRecipient, pszName, pNotificationFilter,
4727 ulNotificationFilterSize, ulFlags, pNotifyHandle, ulProcessId, pulUnknown9);
4728
4729 if (pNotifyHandle == NULL)
4730 return CR_INVALID_POINTER;
4731
4732 *pNotifyHandle = NULL;
4733
4734 if (pNotificationFilter == NULL ||
4735 pulUnknown9 == NULL)
4736 return CR_INVALID_POINTER;
4737
4738 if (ulFlags & ~0x7)
4739 return CR_INVALID_FLAG;
4740
4741 if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HDR)) ||
4742 (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_size < sizeof(DEV_BROADCAST_HDR)))
4743 return CR_INVALID_DATA;
4744
4745 if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
4746 {
4747 DPRINT1("DBT_DEVTYP_DEVICEINTERFACE\n");
4748 pBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE_W)pNotificationFilter;
4749
4750 if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)) ||
4751 (pBroadcastDeviceInterface->dbcc_size < sizeof(DEV_BROADCAST_DEVICEINTERFACE_W)))
4752 return CR_INVALID_DATA;
4753
4754 pNotifyData = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFY_ENTRY));
4755 if (pNotifyData == NULL)
4756 return CR_OUT_OF_MEMORY;
4757
4758 if (pszName != NULL)
4759 {
4760 pNotifyData->pszName = RtlAllocateHeap(GetProcessHeap(),
4761 HEAP_ZERO_MEMORY,
4762 (wcslen(pszName) + 1) * sizeof(WCHAR));
4763 if (pNotifyData->pszName == NULL)
4764 {
4765 RtlFreeHeap(GetProcessHeap(), 0, pNotifyData);
4766 return CR_OUT_OF_MEMORY;
4767 }
4768 }
4769
4770 /* Add the entry to the notification list */
4771 InsertTailList(&NotificationListHead, &pNotifyData->ListEntry);
4772
4773 DPRINT("pNotifyData: %p\n", pNotifyData);
4774 *pNotifyHandle = (PNP_NOTIFY_HANDLE)pNotifyData;
4775 }
4776 else if (((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype == DBT_DEVTYP_HANDLE)
4777 {
4778 DPRINT1("DBT_DEVTYP_HANDLE\n");
4779 pBroadcastDeviceHandle = (PDEV_BROADCAST_HANDLE)pNotificationFilter;
4780
4781 if ((ulNotificationFilterSize < sizeof(DEV_BROADCAST_HANDLE)) ||
4782 (pBroadcastDeviceHandle->dbch_size < sizeof(DEV_BROADCAST_HANDLE)))
4783 return CR_INVALID_DATA;
4784
4785 if (ulFlags & DEVICE_NOTIFY_ALL_INTERFACE_CLASSES)
4786 return CR_INVALID_FLAG;
4787 }
4788 else
4789 {
4790 DPRINT1("Invalid device type %lu\n", ((PDEV_BROADCAST_HDR)pNotificationFilter)->dbch_devicetype);
4791 return CR_INVALID_DATA;
4792 }
4793
4794 return CR_SUCCESS;
4795 }
4796
4797
4798 /* Function 60 */
4799 DWORD
4800 WINAPI
PNP_UnregisterNotification(handle_t hBinding,PNP_NOTIFY_HANDLE * pNotifyHandle)4801 PNP_UnregisterNotification(
4802 handle_t hBinding,
4803 PNP_NOTIFY_HANDLE *pNotifyHandle)
4804 {
4805 PNOTIFY_ENTRY pEntry;
4806
4807 DPRINT1("PNP_UnregisterNotification(%p %p)\n",
4808 hBinding, pNotifyHandle);
4809
4810 pEntry = (PNOTIFY_ENTRY)*pNotifyHandle;
4811 if (pEntry == NULL)
4812 return CR_INVALID_DATA;
4813
4814 RemoveEntryList(&pEntry->ListEntry);
4815 if (pEntry->pszName)
4816 RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry->pszName);
4817 RtlFreeHeap(RtlGetProcessHeap(), 0, pEntry);
4818 *pNotifyHandle = NULL;
4819
4820 return CR_SUCCESS;
4821 }
4822
4823
4824 /* Function 61 */
4825 DWORD
4826 WINAPI
PNP_GetCustomDevProp(handle_t hBinding,LPWSTR pDeviceID,LPWSTR CustomPropName,DWORD * pulRegDataType,BYTE * Buffer,PNP_RPC_STRING_LEN * pulTransferLen,PNP_RPC_STRING_LEN * pulLength,DWORD ulFlags)4827 PNP_GetCustomDevProp(
4828 handle_t hBinding,
4829 LPWSTR pDeviceID,
4830 LPWSTR CustomPropName,
4831 DWORD *pulRegDataType,
4832 BYTE *Buffer,
4833 PNP_RPC_STRING_LEN *pulTransferLen,
4834 PNP_RPC_STRING_LEN *pulLength,
4835 DWORD ulFlags)
4836 {
4837 HKEY hDeviceKey = NULL;
4838 HKEY hParamKey = NULL;
4839 LONG lError;
4840 CONFIGRET ret = CR_SUCCESS;
4841
4842 UNREFERENCED_PARAMETER(hBinding);
4843
4844 DPRINT("PNP_GetCustomDevProp() called\n");
4845
4846 if (pulTransferLen == NULL || pulLength == NULL)
4847 {
4848 ret = CR_INVALID_POINTER;
4849 goto done;
4850 }
4851
4852 if (ulFlags & ~CM_CUSTOMDEVPROP_BITS)
4853 {
4854 ret = CR_INVALID_FLAG;
4855 goto done;
4856 }
4857
4858 if (!IsValidDeviceInstanceID(pDeviceID))
4859 return CR_INVALID_DEVINST;
4860
4861 if (*pulLength < *pulTransferLen)
4862 *pulLength = *pulTransferLen;
4863
4864 *pulTransferLen = 0;
4865
4866 lError = RegOpenKeyExW(hEnumKey,
4867 pDeviceID,
4868 0,
4869 KEY_READ,
4870 &hDeviceKey);
4871 if (lError != ERROR_SUCCESS)
4872 {
4873 ret = CR_REGISTRY_ERROR;
4874 goto done;
4875 }
4876
4877 lError = RegOpenKeyExW(hDeviceKey,
4878 L"Device Parameters",
4879 0,
4880 KEY_READ,
4881 &hParamKey);
4882 if (lError != ERROR_SUCCESS)
4883 {
4884 ret = CR_REGISTRY_ERROR;
4885 goto done;
4886 }
4887
4888 lError = RegQueryValueExW(hParamKey,
4889 CustomPropName,
4890 NULL,
4891 pulRegDataType,
4892 Buffer,
4893 pulLength);
4894 if (lError != ERROR_SUCCESS)
4895 {
4896 if (lError == ERROR_MORE_DATA)
4897 {
4898 ret = CR_BUFFER_SMALL;
4899 }
4900 else
4901 {
4902 *pulLength = 0;
4903 ret = CR_NO_SUCH_VALUE;
4904 }
4905 }
4906
4907 done:
4908 if (ret == CR_SUCCESS)
4909 *pulTransferLen = *pulLength;
4910
4911 if (hParamKey != NULL)
4912 RegCloseKey(hParamKey);
4913
4914 if (hDeviceKey != NULL)
4915 RegCloseKey(hDeviceKey);
4916
4917 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret);
4918
4919 return ret;
4920 }
4921
4922
4923 /* Function 62 */
4924 DWORD
4925 WINAPI
PNP_GetVersionInternal(handle_t hBinding,WORD * pwVersion)4926 PNP_GetVersionInternal(
4927 handle_t hBinding,
4928 WORD *pwVersion)
4929 {
4930 UNREFERENCED_PARAMETER(hBinding);
4931
4932 *pwVersion = WINVER;
4933 return CR_SUCCESS;
4934 }
4935
4936
4937 /* Function 63 */
4938 DWORD
4939 WINAPI
PNP_GetBlockedDriverInfo(handle_t hBinding,BYTE * Buffer,PNP_RPC_BUFFER_SIZE * pulTransferLen,PNP_RPC_BUFFER_SIZE * pulLength,DWORD ulFlags)4940 PNP_GetBlockedDriverInfo(
4941 handle_t hBinding,
4942 BYTE *Buffer,
4943 PNP_RPC_BUFFER_SIZE *pulTransferLen,
4944 PNP_RPC_BUFFER_SIZE *pulLength,
4945 DWORD ulFlags)
4946 {
4947 UNIMPLEMENTED;
4948 return CR_CALL_NOT_IMPLEMENTED;
4949 }
4950
4951
4952 /* Function 64 */
4953 DWORD
4954 WINAPI
PNP_GetServerSideDeviceInstallFlags(handle_t hBinding,DWORD * pulSSDIFlags,DWORD ulFlags)4955 PNP_GetServerSideDeviceInstallFlags(
4956 handle_t hBinding,
4957 DWORD *pulSSDIFlags,
4958 DWORD ulFlags)
4959 {
4960 UNREFERENCED_PARAMETER(hBinding);
4961
4962 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
4963 hBinding, pulSSDIFlags, ulFlags);
4964
4965 if (pulSSDIFlags == NULL)
4966 return CR_INVALID_POINTER;
4967
4968 if (ulFlags != 0)
4969 return CR_INVALID_FLAG;
4970
4971 /* FIXME */
4972 *pulSSDIFlags = 0;
4973
4974 return CR_SUCCESS;
4975 }
4976
4977
4978 /* Function 65 */
4979 DWORD
4980 WINAPI
PNP_GetObjectPropKeys(handle_t hBinding,LPWSTR ObjectName,DWORD ObjectType,LPWSTR PropertyCultureName,PNP_PROP_COUNT * PropertyCount,PNP_PROP_COUNT * TransferLen,DEVPROPKEY * PropertyKeys,DWORD Flags)4981 PNP_GetObjectPropKeys(
4982 handle_t hBinding,
4983 LPWSTR ObjectName,
4984 DWORD ObjectType,
4985 LPWSTR PropertyCultureName,
4986 PNP_PROP_COUNT *PropertyCount,
4987 PNP_PROP_COUNT *TransferLen,
4988 DEVPROPKEY *PropertyKeys,
4989 DWORD Flags)
4990 {
4991 UNIMPLEMENTED;
4992 return CR_CALL_NOT_IMPLEMENTED;
4993 }
4994
4995
4996 /* Function 66 */
4997 DWORD
4998 WINAPI
PNP_GetObjectProp(handle_t hBinding,LPWSTR ObjectName,DWORD ObjectType,LPWSTR PropertyCultureName,const DEVPROPKEY * PropertyKey,DEVPROPTYPE * PropertyType,PNP_PROP_SIZE * PropertySize,PNP_PROP_SIZE * TransferLen,BYTE * PropertyBuffer,DWORD Flags)4999 PNP_GetObjectProp(
5000 handle_t hBinding,
5001 LPWSTR ObjectName,
5002 DWORD ObjectType,
5003 LPWSTR PropertyCultureName,
5004 const DEVPROPKEY *PropertyKey,
5005 DEVPROPTYPE *PropertyType,
5006 PNP_PROP_SIZE *PropertySize,
5007 PNP_PROP_SIZE *TransferLen,
5008 BYTE *PropertyBuffer,
5009 DWORD Flags)
5010 {
5011 UNIMPLEMENTED;
5012 return CR_CALL_NOT_IMPLEMENTED;
5013 }
5014
5015
5016 /* Function 67 */
5017 DWORD
5018 WINAPI
PNP_SetObjectProp(handle_t hBinding,LPWSTR ObjectName,DWORD ObjectType,LPWSTR PropertyCultureName,const DEVPROPKEY * PropertyKey,DEVPROPTYPE PropertyType,PNP_PROP_SIZE PropertySize,BYTE * PropertyBuffer,DWORD Flags)5019 PNP_SetObjectProp(
5020 handle_t hBinding,
5021 LPWSTR ObjectName,
5022 DWORD ObjectType,
5023 LPWSTR PropertyCultureName,
5024 const DEVPROPKEY *PropertyKey,
5025 DEVPROPTYPE PropertyType,
5026 PNP_PROP_SIZE PropertySize,
5027 BYTE *PropertyBuffer,
5028 DWORD Flags)
5029 {
5030 UNIMPLEMENTED;
5031 return CR_CALL_NOT_IMPLEMENTED;
5032 }
5033
5034
5035 /* Function 68 */
5036 DWORD
5037 WINAPI
PNP_InstallDevInst(handle_t hBinding)5038 PNP_InstallDevInst(
5039 handle_t hBinding)
5040 {
5041 UNIMPLEMENTED;
5042 return CR_CALL_NOT_IMPLEMENTED;
5043 }
5044
5045
5046 /* Function 69 */
5047 DWORD
5048 WINAPI
PNP_ApplyPowerSettings(handle_t hBinding)5049 PNP_ApplyPowerSettings(
5050 handle_t hBinding)
5051 {
5052 UNIMPLEMENTED;
5053 return CR_CALL_NOT_IMPLEMENTED;
5054 }
5055
5056
5057 /* Function 70 */
5058 DWORD
5059 WINAPI
PNP_DriverStoreAddDriverPackage(handle_t hBinding)5060 PNP_DriverStoreAddDriverPackage(
5061 handle_t hBinding)
5062 {
5063 UNIMPLEMENTED;
5064 return CR_CALL_NOT_IMPLEMENTED;
5065 }
5066
5067
5068 /* Function 71 */
5069 DWORD
5070 WINAPI
PNP_DriverStoreDeleteDriverPackage(handle_t hBinding)5071 PNP_DriverStoreDeleteDriverPackage(
5072 handle_t hBinding)
5073 {
5074 UNIMPLEMENTED;
5075 return CR_CALL_NOT_IMPLEMENTED;
5076 }
5077
5078
5079 /* Function 72 */
5080 DWORD
5081 WINAPI
PNP_RegisterServiceNotification(handle_t hBinding)5082 PNP_RegisterServiceNotification(
5083 handle_t hBinding)
5084 {
5085 UNIMPLEMENTED;
5086 return CR_CALL_NOT_IMPLEMENTED;
5087 }
5088
5089
5090 /* Function 73 */
5091 DWORD
5092 WINAPI
PNP_SetActiveService(handle_t hBinding,LPWSTR pszFilter,DWORD ulFlags)5093 PNP_SetActiveService(
5094 handle_t hBinding,
5095 LPWSTR pszFilter,
5096 DWORD ulFlags)
5097 {
5098 UNIMPLEMENTED;
5099 return CR_CALL_NOT_IMPLEMENTED;
5100 }
5101
5102
5103 /* Function 74 */
5104 DWORD
5105 WINAPI
PNP_DeleteServiceDevices(handle_t hBinding)5106 PNP_DeleteServiceDevices(
5107 handle_t hBinding)
5108 {
5109 UNIMPLEMENTED;
5110 return CR_CALL_NOT_IMPLEMENTED;
5111 }
5112