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