3 * Copyright (C) 2005 ReactOS Team
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.
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.
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.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * FILE: base/services/umpnpmgr/rpcserver.c
24 * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
25 * Hervé Poussineau (hpoussin@reactos.org)
26 * Colin Finck (colin@reactos.org)
29 /* INCLUDES *****************************************************************/
37 /* GLOBALS ******************************************************************/
39 static WCHAR szRootDeviceInstanceID
[] = L
"HTREE\\ROOT\\0";
42 /* FUNCTIONS *****************************************************************/
45 RpcServerThread(LPVOID lpParameter
)
48 BOOLEAN RegisteredProtSeq
= FALSE
;
50 UNREFERENCED_PARAMETER(lpParameter
);
52 DPRINT("RpcServerThread() called\n");
55 /* 2k/XP/2k3-compatible protocol sequence/endpoint */
56 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
59 NULL
); // Security descriptor
60 if (Status
== RPC_S_OK
)
61 RegisteredProtSeq
= TRUE
;
63 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
66 /* Vista/7-compatible protocol sequence/endpoint */
67 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
70 NULL
); // Security descriptor
71 if (Status
== RPC_S_OK
)
72 RegisteredProtSeq
= TRUE
;
74 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
76 /* Make sure there's a usable endpoint */
77 if (RegisteredProtSeq
== FALSE
)
80 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
83 if (Status
!= RPC_S_OK
)
85 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
89 Status
= RpcServerListen(1,
92 if (Status
!= RPC_S_OK
)
94 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
98 /* ROS HACK (this should never happen...) */
99 DPRINT1("*** Other devices won't be installed correctly. If something\n");
100 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
102 DPRINT("RpcServerThread() done\n");
108 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
110 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
114 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
116 HeapFree(GetProcessHeap(), 0, ptr
);
120 static CONFIGRET WINAPI
121 NtStatusToCrError(NTSTATUS Status
)
125 case STATUS_NOT_IMPLEMENTED
:
126 return CR_CALL_NOT_IMPLEMENTED
;
128 case STATUS_INVALID_PARAMETER
:
129 return CR_INVALID_DATA
;
131 case STATUS_NO_SUCH_DEVICE
:
132 return CR_NO_SUCH_DEVINST
;
134 case STATUS_ACCESS_DENIED
:
135 return CR_ACCESS_DENIED
;
137 case STATUS_BUFFER_TOO_SMALL
:
138 return CR_BUFFER_SMALL
;
140 case STATUS_OBJECT_NAME_NOT_FOUND
:
141 return CR_NO_SUCH_VALUE
;
150 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
151 OUT LPWSTR pszEnumerator
,
152 OUT LPWSTR pszDevice
,
153 OUT LPWSTR pszInstance
)
155 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
156 LPWSTR lpEnumerator
= NULL
;
157 LPWSTR lpDevice
= NULL
;
158 LPWSTR lpInstance
= NULL
;
161 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
167 lpEnumerator
= szLocalDeviceInstanceID
;
169 ptr
= wcschr(lpEnumerator
, L
'\\');
175 ptr
= wcschr(lpDevice
, L
'\\');
183 if (lpEnumerator
!= NULL
)
184 wcscpy(pszEnumerator
, lpEnumerator
);
186 if (lpDevice
!= NULL
)
187 wcscpy(pszDevice
, lpDevice
);
189 if (lpInstance
!= NULL
)
190 wcscpy(pszInstance
, lpInstance
);
197 _In_ LPWSTR pszDeviceID
,
199 _In_ DWORD ulProblem
)
201 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
202 CONFIGRET ret
= CR_SUCCESS
;
205 DPRINT1("ClearDeviceStatus(%S 0x%lx 0x%lx)\n",
206 pszDeviceID
, ulStatus
, ulProblem
);
208 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
210 PlugPlayData
.Operation
= PNP_CLEAR_DEVICE_STATUS
;
211 PlugPlayData
.DeviceStatus
= ulStatus
;
212 PlugPlayData
.DeviceProblem
= ulProblem
;
214 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
215 (PVOID
)&PlugPlayData
,
216 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
217 if (!NT_SUCCESS(Status
))
218 ret
= NtStatusToCrError(Status
);
227 _In_ LPWSTR pszDeviceID
,
228 _Out_ DWORD
*pulStatus
,
229 _Out_ DWORD
*pulProblem
)
231 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
232 CONFIGRET ret
= CR_SUCCESS
;
235 DPRINT("GetDeviceStatus(%S %p %p)\n",
236 pszDeviceID
, pulStatus
, pulProblem
);
238 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
240 PlugPlayData
.Operation
= PNP_GET_DEVICE_STATUS
;
242 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
243 (PVOID
)&PlugPlayData
,
244 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
245 if (NT_SUCCESS(Status
))
247 *pulStatus
= PlugPlayData
.DeviceStatus
;
248 *pulProblem
= PlugPlayData
.DeviceProblem
;
252 ret
= NtStatusToCrError(Status
);
262 _In_ LPWSTR pszDeviceID
,
264 _In_ DWORD ulProblem
)
266 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
267 CONFIGRET ret
= CR_SUCCESS
;
270 DPRINT1("SetDeviceStatus(%S 0x%lx 0x%lx)\n",
271 pszDeviceID
, ulStatus
, ulProblem
);
273 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
275 PlugPlayData
.Operation
= PNP_SET_DEVICE_STATUS
;
276 PlugPlayData
.DeviceStatus
= ulStatus
;
277 PlugPlayData
.DeviceProblem
= ulProblem
;
279 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
280 (PVOID
)&PlugPlayData
,
281 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
282 if (!NT_SUCCESS(Status
))
283 ret
= NtStatusToCrError(Status
);
291 DisableDeviceInstance(
292 _In_ LPWSTR pszDeviceInstance
,
293 _Inout_opt_ PPNP_VETO_TYPE pVetoType
,
294 _Inout_opt_ LPWSTR pszVetoName
,
295 _In_ DWORD ulNameLength
)
297 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA QueryRemoveData
;
298 CONFIGRET ret
= CR_SUCCESS
;
301 DPRINT1("DisableDeviceInstance(%S %p %p %lu)\n",
302 pszDeviceInstance
, pVetoType
, pszVetoName
, ulNameLength
);
304 RtlInitUnicodeString(&QueryRemoveData
.DeviceInstance
,
307 QueryRemoveData
.Flags
= 0;
308 QueryRemoveData
.VetoType
= 0;
309 QueryRemoveData
.VetoName
= pszVetoName
;
310 QueryRemoveData
.NameLength
= ulNameLength
;
312 Status
= NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice
,
314 sizeof(PLUGPLAY_CONTROL_QUERY_REMOVE_DATA
));
315 if (Status
== STATUS_NO_SUCH_DEVICE
)
317 ret
= CR_INVALID_DEVNODE
;
319 else if (Status
== STATUS_PLUGPLAY_QUERY_VETOED
)
321 if (pVetoType
!= NULL
)
322 *pVetoType
= QueryRemoveData
.VetoType
;
324 ret
= CR_REMOVE_VETOED
;
326 else if (!NT_SUCCESS(Status
))
328 ret
= NtStatusToCrError(Status
);
337 IsValidDeviceInstanceID(
338 _In_ PWSTR pszDeviceInstanceID
)
340 INT nPartLength
[3] = {0, 0, 0};
341 INT nLength
= 0, nParts
= 0;
344 DPRINT("IsValidDeviceInstanceID(%S)\n",
345 pszDeviceInstanceID
);
347 if (pszDeviceInstanceID
== NULL
)
349 DPRINT("Device instance ID is NULL!\n");
353 p
= pszDeviceInstanceID
;
354 while (*p
!= UNICODE_NULL
)
361 DPRINT("Too many separators: %d\n", nParts
);
367 nPartLength
[nParts
]++;
371 if (nLength
>= MAX_DEVICE_ID_LEN
)
373 DPRINT("Too long: %d\n", nLength
);
382 DPRINT("Invalid number of separtors: %d\n", nParts
);
386 if ((nPartLength
[0] == 0) ||
387 (nPartLength
[1] == 0) ||
388 (nPartLength
[2] == 0))
390 DPRINT("Invalid part lengths: %d %d %d\n",
391 nPartLength
[0], nPartLength
[1], nPartLength
[2]);
395 DPRINT("Valid device instance ID!\n");
403 IsRootDeviceInstanceID(
404 _In_ PWSTR pszDeviceInstanceID
)
406 if (_wcsicmp(pszDeviceInstanceID
, szRootDeviceInstanceID
) == 0)
415 OpenConfigurationKey(
416 _In_ LPCWSTR pszDeviceID
,
419 WCHAR szKeyName
[MAX_PATH
];
423 /* Build the full device instance key name */
424 wcscpy(szKeyName
, L
"System\\CurrentControlSet\\Enum\\");
425 wcscat(szKeyName
, pszDeviceID
);
427 /* Open the device instance key */
428 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
431 KEY_QUERY_VALUE
| KEY_SET_VALUE
| KEY_CREATE_SUB_KEY
,
433 if (dwError
!= ERROR_SUCCESS
)
434 return CR_INVALID_DEVINST
;
436 /* Create or open the LogConf key */
437 dwError
= RegCreateKeyExW(hInstanceKey
,
441 REG_OPTION_NON_VOLATILE
,
447 /* Close the device instance key */
448 RegCloseKey(hInstanceKey
);
450 if (dwError
!= ERROR_SUCCESS
)
451 return CR_REGISTRY_ERROR
;
459 GetConfigurationData(
461 _In_ ULONG ulLogConfType
,
462 _Out_ PULONG pulRegDataType
,
463 _Out_ PULONG pulDataSize
,
464 _Out_ LPBYTE
*ppBuffer
)
466 LPCWSTR pszValueName
;
468 switch (ulLogConfType
)
471 pszValueName
= L
"BootConfig";
472 *pulRegDataType
= REG_RESOURCE_LIST
;
476 pszValueName
= L
"AllocConfig";
477 *pulRegDataType
= REG_RESOURCE_LIST
;
480 case FORCED_LOG_CONF
:
481 pszValueName
= L
"ForcedConfig";
482 *pulRegDataType
= REG_RESOURCE_LIST
;
485 case FILTERED_LOG_CONF
:
486 pszValueName
= L
"FilteredConfigVector";
487 *pulRegDataType
= REG_RESOURCE_REQUIREMENTS_LIST
;
491 pszValueName
= L
"BasicConfigVector";
492 *pulRegDataType
= REG_RESOURCE_REQUIREMENTS_LIST
;
495 case OVERRIDE_LOG_CONF
:
496 pszValueName
= L
"OverrideConfigVector";
497 *pulRegDataType
= REG_RESOURCE_REQUIREMENTS_LIST
;
501 DPRINT1("Unsupported configuration type!\n");
505 /* Get the configuration data size */
506 if (RegQueryValueExW(hKey
,
511 pulDataSize
) != ERROR_SUCCESS
)
513 return CR_INVALID_LOG_CONF
;
516 /* Allocate the buffer */
517 *ppBuffer
= HeapAlloc(GetProcessHeap(), 0, *pulDataSize
);
518 if (*ppBuffer
== NULL
)
520 return CR_OUT_OF_MEMORY
;
523 /* Retrieve the configuration data */
524 if (RegQueryValueExW(hKey
,
529 pulDataSize
) != ERROR_SUCCESS
)
531 return CR_INVALID_LOG_CONF
;
538 /* PUBLIC FUNCTIONS **********************************************************/
546 UNREFERENCED_PARAMETER(hBinding
);
557 UNREFERENCED_PARAMETER(hBinding
);
569 UNREFERENCED_PARAMETER(hBinding
);
571 DPRINT("PNP_GetVersion(%p %p)\n",
588 UNREFERENCED_PARAMETER(hBinding
);
589 UNREFERENCED_PARAMETER(ulFlags
);
591 DPRINT("PNP_GetGlobalState(%p %p 0x%08lx)\n",
592 hBinding
, pulState
, ulFlags
);
594 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
606 UNREFERENCED_PARAMETER(hBinding
);
608 DPRINT("PNP_InitDetection(%p)\n",
623 DWORD ReturnValue
= CR_FAILURE
;
626 UNREFERENCED_PARAMETER(hBinding
);
627 UNREFERENCED_PARAMETER(Admin
);
629 DPRINT("PNP_ReportLogOn(%p %u, %u)\n",
630 hBinding
, Admin
, ProcessId
);
632 /* Get the users token */
633 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
637 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
643 CloseHandle(hUserToken
);
647 if (!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
649 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
653 /* Trigger the installer thread */
655 SetEvent(hInstallEvent
);
657 ReturnValue
= CR_SUCCESS
;
661 CloseHandle(hProcess
);
670 PNP_ValidateDeviceInstance(
675 CONFIGRET ret
= CR_SUCCESS
;
676 HKEY hDeviceKey
= NULL
;
678 UNREFERENCED_PARAMETER(hBinding
);
679 UNREFERENCED_PARAMETER(ulFlags
);
681 DPRINT("PNP_ValidateDeviceInstance(%p %S 0x%08lx)\n",
682 hBinding
, pDeviceID
, ulFlags
);
684 if (!IsValidDeviceInstanceID(pDeviceID
))
685 return CR_INVALID_DEVINST
;
687 if (RegOpenKeyExW(hEnumKey
,
693 DPRINT("Could not open the Device Key!\n");
694 ret
= CR_NO_SUCH_DEVNODE
;
698 /* FIXME: add more tests */
701 if (hDeviceKey
!= NULL
)
702 RegCloseKey(hDeviceKey
);
704 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
713 PNP_GetRootDeviceInstance(
716 PNP_RPC_STRING_LEN ulLength
)
718 CONFIGRET ret
= CR_SUCCESS
;
720 UNREFERENCED_PARAMETER(hBinding
);
722 DPRINT("PNP_GetRootDeviceInstance(%p %S %lu)\n",
723 hBinding
, pDeviceID
, ulLength
);
727 ret
= CR_INVALID_POINTER
;
731 if (ulLength
< lstrlenW(szRootDeviceInstanceID
) + 1)
733 ret
= CR_BUFFER_SMALL
;
738 szRootDeviceInstanceID
);
741 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
750 PNP_GetRelatedDeviceInstance(
752 DWORD ulRelationship
,
754 LPWSTR pRelatedDeviceId
,
755 PNP_RPC_STRING_LEN
*pulLength
,
758 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
759 CONFIGRET ret
= CR_SUCCESS
;
762 UNREFERENCED_PARAMETER(hBinding
);
763 UNREFERENCED_PARAMETER(ulFlags
);
765 DPRINT("PNP_GetRelatedDeviceInstance(%p %lu %S %p %p 0x%lx)\n",
766 hBinding
, ulRelationship
, pDeviceID
, pRelatedDeviceId
,
769 if (!IsValidDeviceInstanceID(pDeviceID
))
770 return CR_INVALID_DEVINST
;
772 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
775 PlugPlayData
.Relation
= ulRelationship
;
777 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
778 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
780 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
781 (PVOID
)&PlugPlayData
,
782 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
783 if (!NT_SUCCESS(Status
))
785 ret
= NtStatusToCrError(Status
);
788 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
789 if (ret
== CR_SUCCESS
)
791 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
801 PNP_EnumerateSubKeys(
806 PNP_RPC_STRING_LEN ulLength
,
807 PNP_RPC_STRING_LEN
*pulRequiredLen
,
810 CONFIGRET ret
= CR_SUCCESS
;
814 UNREFERENCED_PARAMETER(hBinding
);
815 UNREFERENCED_PARAMETER(ulFlags
);
817 DPRINT("PNP_EnumerateSubKeys(%p %lu %lu %p %lu %p 0x%08lx)\n",
818 hBinding
, ulBranch
, ulIndex
, Buffer
, ulLength
,
819 pulRequiredLen
, ulFlags
);
823 case PNP_ENUMERATOR_SUBKEYS
:
827 case PNP_CLASS_SUBKEYS
:
835 *pulRequiredLen
= ulLength
;
836 dwError
= RegEnumKeyExW(hKey
,
844 if (dwError
!= ERROR_SUCCESS
)
846 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
853 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
861 GetRelationsInstanceList(
862 _In_ PWSTR pszDevice
,
864 _Inout_ PWSTR pszBuffer
,
865 _Inout_ PDWORD pulLength
)
867 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
869 CONFIGRET ret
= CR_SUCCESS
;
871 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
874 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
876 PlugPlayData
.Relations
= 3;
878 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
880 PlugPlayData
.Relations
= 2;
882 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
884 PlugPlayData
.Relations
= 1;
886 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
888 PlugPlayData
.Relations
= 0;
891 PlugPlayData
.BufferSize
= *pulLength
* sizeof(WCHAR
);
892 PlugPlayData
.Buffer
= pszBuffer
;
894 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
895 (PVOID
)&PlugPlayData
,
896 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
897 if (NT_SUCCESS(Status
))
899 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
903 ret
= NtStatusToCrError(Status
);
912 GetServiceInstanceList(
913 _In_ PWSTR pszService
,
914 _Inout_ PWSTR pszBuffer
,
915 _Inout_ PDWORD pulLength
)
917 WCHAR szPathBuffer
[512];
919 HKEY hServicesKey
= NULL
, hServiceKey
= NULL
, hEnumKey
= NULL
;
920 DWORD dwValues
, dwSize
, dwIndex
, dwUsedLength
, dwPathLength
;
923 CONFIGRET ret
= CR_SUCCESS
;
925 /* Open the device key */
926 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
927 L
"System\\CurrentControlSet\\Services",
931 if (dwError
!= ERROR_SUCCESS
)
933 DPRINT("Failed to open the services key (Error %lu)\n", dwError
);
934 return CR_REGISTRY_ERROR
;
937 dwError
= RegOpenKeyExW(hServicesKey
,
942 if (dwError
!= ERROR_SUCCESS
)
944 DPRINT("Failed to open the service key (Error %lu)\n", dwError
);
945 ret
= CR_REGISTRY_ERROR
;
949 dwError
= RegOpenKeyExW(hServiceKey
,
954 if (dwError
!= ERROR_SUCCESS
)
956 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError
);
957 ret
= CR_REGISTRY_ERROR
;
961 /* Retrieve the number of device instances */
962 dwSize
= sizeof(DWORD
);
963 dwError
= RegQueryValueExW(hEnumKey
,
969 if (dwError
!= ERROR_SUCCESS
)
971 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError
);
975 DPRINT("dwValues %lu\n", dwValues
);
980 for (dwIndex
= 0; dwIndex
< dwValues
; dwIndex
++)
982 wsprintf(szName
, L
"%lu", dwIndex
);
984 dwSize
= sizeof(szPathBuffer
);
985 dwError
= RegQueryValueExW(hEnumKey
,
989 (LPBYTE
)szPathBuffer
,
991 if (dwError
!= ERROR_SUCCESS
)
994 DPRINT("Path: %S\n", szPathBuffer
);
996 dwPathLength
= wcslen(szPathBuffer
) + 1;
997 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
999 ret
= CR_BUFFER_SMALL
;
1003 wcscpy(pPtr
, szPathBuffer
);
1004 dwUsedLength
+= dwPathLength
;
1005 pPtr
+= dwPathLength
;
1007 *pPtr
= UNICODE_NULL
;
1011 if (hEnumKey
!= NULL
)
1012 RegCloseKey(hEnumKey
);
1014 if (hServiceKey
!= NULL
)
1015 RegCloseKey(hServiceKey
);
1017 if (hServicesKey
!= NULL
)
1018 RegCloseKey(hServicesKey
);
1020 if (ret
== CR_SUCCESS
)
1021 *pulLength
= dwUsedLength
+ 1;
1031 GetDeviceInstanceList(
1032 _In_ PWSTR pszDevice
,
1033 _Inout_ PWSTR pszBuffer
,
1034 _Inout_ PDWORD pulLength
)
1036 WCHAR szInstanceBuffer
[MAX_DEVICE_ID_LEN
];
1037 WCHAR szPathBuffer
[512];
1039 DWORD dwInstanceLength
, dwPathLength
, dwUsedLength
;
1040 DWORD dwIndex
, dwError
;
1042 CONFIGRET ret
= CR_SUCCESS
;
1044 /* Open the device key */
1045 dwError
= RegOpenKeyExW(hEnumKey
,
1048 KEY_ENUMERATE_SUB_KEYS
,
1050 if (dwError
!= ERROR_SUCCESS
)
1052 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
1053 return CR_REGISTRY_ERROR
;
1059 for (dwIndex
= 0; ; dwIndex
++)
1061 dwInstanceLength
= MAX_DEVICE_ID_LEN
;
1062 dwError
= RegEnumKeyExW(hDeviceKey
,
1070 if (dwError
!= ERROR_SUCCESS
)
1073 wsprintf(szPathBuffer
, L
"%s\\%s", pszDevice
, szInstanceBuffer
);
1074 DPRINT("Path: %S\n", szPathBuffer
);
1076 dwPathLength
= wcslen(szPathBuffer
) + 1;
1077 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
1079 ret
= CR_BUFFER_SMALL
;
1083 wcscpy(pPtr
, szPathBuffer
);
1084 dwUsedLength
+= dwPathLength
;
1085 pPtr
+= dwPathLength
;
1087 *pPtr
= UNICODE_NULL
;
1090 RegCloseKey(hDeviceKey
);
1092 if (ret
== CR_SUCCESS
)
1093 *pulLength
= dwUsedLength
+ 1;
1102 GetEnumeratorInstanceList(
1103 _In_ PWSTR pszEnumerator
,
1104 _Inout_ PWSTR pszBuffer
,
1105 _Inout_ PDWORD pulLength
)
1107 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
1108 WCHAR szPathBuffer
[512];
1109 HKEY hEnumeratorKey
;
1111 DWORD dwIndex
, dwDeviceLength
, dwUsedLength
, dwRemainingLength
, dwPathLength
;
1113 CONFIGRET ret
= CR_SUCCESS
;
1115 /* Open the enumerator key */
1116 dwError
= RegOpenKeyExW(hEnumKey
,
1119 KEY_ENUMERATE_SUB_KEYS
,
1121 if (dwError
!= ERROR_SUCCESS
)
1123 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
1124 return CR_REGISTRY_ERROR
;
1128 dwRemainingLength
= *pulLength
;
1131 for (dwIndex
= 0; ; dwIndex
++)
1133 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
1134 dwError
= RegEnumKeyExW(hEnumeratorKey
,
1142 if (dwError
!= ERROR_SUCCESS
)
1145 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
1146 DPRINT("Path: %S\n", szPathBuffer
);
1148 dwPathLength
= dwRemainingLength
;
1149 ret
= GetDeviceInstanceList(szPathBuffer
,
1152 if (ret
!= CR_SUCCESS
)
1155 dwUsedLength
+= dwPathLength
- 1;
1156 dwRemainingLength
+= dwPathLength
- 1;
1157 pPtr
+= dwPathLength
- 1;
1160 RegCloseKey(hEnumeratorKey
);
1162 if (ret
== CR_SUCCESS
)
1163 *pulLength
= dwUsedLength
+ 1;
1174 _Inout_ PWSTR pszBuffer
,
1175 _Inout_ PDWORD pulLength
)
1177 WCHAR szEnumeratorBuffer
[MAX_DEVICE_ID_LEN
];
1179 DWORD dwIndex
, dwEnumeratorLength
, dwUsedLength
, dwRemainingLength
, dwPathLength
;
1181 CONFIGRET ret
= CR_SUCCESS
;
1184 dwRemainingLength
= *pulLength
;
1187 for (dwIndex
= 0; ; dwIndex
++)
1189 dwEnumeratorLength
= MAX_DEVICE_ID_LEN
;
1190 dwError
= RegEnumKeyExW(hEnumKey
,
1193 &dwEnumeratorLength
,
1194 NULL
, NULL
, NULL
, NULL
);
1195 if (dwError
!= ERROR_SUCCESS
)
1198 dwPathLength
= dwRemainingLength
;
1199 ret
= GetEnumeratorInstanceList(szEnumeratorBuffer
,
1202 if (ret
!= CR_SUCCESS
)
1205 dwUsedLength
+= dwPathLength
- 1;
1206 dwRemainingLength
+= dwPathLength
- 1;
1207 pPtr
+= dwPathLength
- 1;
1210 if (ret
== CR_SUCCESS
)
1211 *pulLength
= dwUsedLength
+ 1;
1226 PNP_RPC_STRING_LEN
*pulLength
,
1229 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1230 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1231 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1232 CONFIGRET ret
= CR_SUCCESS
;
1234 DPRINT("PNP_GetDeviceList(%p %S %p %p 0x%08lx)\n",
1235 hBinding
, pszFilter
, Buffer
, pulLength
, ulFlags
);
1237 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
1238 return CR_INVALID_FLAG
;
1240 if (pulLength
== NULL
)
1241 return CR_INVALID_POINTER
;
1243 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
1244 (pszFilter
== NULL
))
1245 return CR_INVALID_POINTER
;
1248 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
1249 CM_GETIDLIST_FILTER_POWERRELATIONS
|
1250 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
1251 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
1253 ret
= GetRelationsInstanceList(pszFilter
,
1258 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
1260 ret
= GetServiceInstanceList(pszFilter
,
1264 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
1266 SplitDeviceInstanceID(pszFilter
,
1271 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
1273 ret
= GetDeviceInstanceList(pszFilter
,
1279 ret
= GetEnumeratorInstanceList(pszFilter
,
1284 else /* CM_GETIDLIST_FILTER_NONE */
1286 ret
= GetAllInstanceList(Buffer
,
1296 GetRelationsInstanceListSize(
1297 _In_ PWSTR pszDevice
,
1299 _Inout_ PDWORD pulLength
)
1301 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
1303 CONFIGRET ret
= CR_SUCCESS
;
1305 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1308 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
1310 PlugPlayData
.Relations
= 3;
1312 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
1314 PlugPlayData
.Relations
= 2;
1316 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
1318 PlugPlayData
.Relations
= 1;
1320 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
1322 PlugPlayData
.Relations
= 0;
1325 PlugPlayData
.BufferSize
= 0;
1326 PlugPlayData
.Buffer
= NULL
;
1328 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
1329 (PVOID
)&PlugPlayData
,
1330 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
1331 if (NT_SUCCESS(Status
))
1333 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
1337 ret
= NtStatusToCrError(Status
);
1346 GetServiceInstanceListSize(
1347 _In_ PWSTR pszService
,
1348 _Out_ PDWORD pulLength
)
1350 HKEY hServicesKey
= NULL
, hServiceKey
= NULL
, hEnumKey
= NULL
;
1351 DWORD dwValues
, dwMaxValueLength
, dwSize
;
1353 CONFIGRET ret
= CR_SUCCESS
;
1355 /* Open the device key */
1356 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1357 L
"System\\CurrentControlSet\\Services",
1361 if (dwError
!= ERROR_SUCCESS
)
1363 DPRINT("Failed to open the services key (Error %lu)\n", dwError
);
1364 return CR_REGISTRY_ERROR
;
1367 dwError
= RegOpenKeyExW(hServicesKey
,
1372 if (dwError
!= ERROR_SUCCESS
)
1374 DPRINT("Failed to open the service key (Error %lu)\n", dwError
);
1375 ret
= CR_REGISTRY_ERROR
;
1379 dwError
= RegOpenKeyExW(hServiceKey
,
1384 if (dwError
!= ERROR_SUCCESS
)
1386 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError
);
1387 ret
= CR_REGISTRY_ERROR
;
1391 /* Retrieve the number of device instances */
1392 dwSize
= sizeof(DWORD
);
1393 dwError
= RegQueryValueExW(hEnumKey
,
1399 if (dwError
!= ERROR_SUCCESS
)
1401 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError
);
1405 /* Retrieve the maximum instance name length */
1406 dwError
= RegQueryInfoKeyW(hEnumKey
,
1418 if (dwError
!= ERROR_SUCCESS
)
1420 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
1421 dwMaxValueLength
= MAX_DEVICE_ID_LEN
;
1424 DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues
, dwMaxValueLength
/ sizeof(WCHAR
));
1426 /* Return the largest possible buffer size */
1427 *pulLength
= dwValues
* dwMaxValueLength
/ sizeof(WCHAR
) + 2;
1430 if (hEnumKey
!= NULL
)
1431 RegCloseKey(hEnumKey
);
1433 if (hServiceKey
!= NULL
)
1434 RegCloseKey(hServiceKey
);
1436 if (hServicesKey
!= NULL
)
1437 RegCloseKey(hServicesKey
);
1445 GetDeviceInstanceListSize(
1446 _In_ LPCWSTR pszDevice
,
1447 _Out_ PULONG pulLength
)
1450 DWORD dwSubKeys
, dwMaxSubKeyLength
;
1453 /* Open the device key */
1454 dwError
= RegOpenKeyExW(hEnumKey
,
1459 if (dwError
!= ERROR_SUCCESS
)
1461 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
1462 return CR_REGISTRY_ERROR
;
1465 /* Retrieve the number of device instances and the maximum name length */
1466 dwError
= RegQueryInfoKeyW(hDeviceKey
,
1478 if (dwError
!= ERROR_SUCCESS
)
1480 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
1482 dwMaxSubKeyLength
= 0;
1485 /* Close the device key */
1486 RegCloseKey(hDeviceKey
);
1488 /* Return the largest possible buffer size */
1489 *pulLength
= dwSubKeys
* (wcslen(pszDevice
) + 1 + dwMaxSubKeyLength
+ 1);
1497 GetEnumeratorInstanceListSize(
1498 _In_ LPCWSTR pszEnumerator
,
1499 _Out_ PULONG pulLength
)
1501 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
1502 WCHAR szPathBuffer
[512];
1503 HKEY hEnumeratorKey
;
1504 DWORD dwIndex
, dwDeviceLength
, dwBufferLength
;
1506 CONFIGRET ret
= CR_SUCCESS
;
1510 /* Open the enumerator key */
1511 dwError
= RegOpenKeyExW(hEnumKey
,
1514 KEY_ENUMERATE_SUB_KEYS
,
1516 if (dwError
!= ERROR_SUCCESS
)
1518 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
1519 return CR_REGISTRY_ERROR
;
1522 for (dwIndex
= 0; ; dwIndex
++)
1524 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
1525 dwError
= RegEnumKeyExW(hEnumeratorKey
,
1533 if (dwError
!= ERROR_SUCCESS
)
1536 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
1537 DPRINT("Path: %S\n", szPathBuffer
);
1539 ret
= GetDeviceInstanceListSize(szPathBuffer
, &dwBufferLength
);
1540 if (ret
!= CR_SUCCESS
)
1546 *pulLength
+= dwBufferLength
;
1549 /* Close the enumerator key */
1550 RegCloseKey(hEnumeratorKey
);
1558 GetAllInstanceListSize(
1559 _Out_ PULONG pulLength
)
1561 WCHAR szEnumeratorBuffer
[MAX_DEVICE_ID_LEN
];
1562 DWORD dwIndex
, dwEnumeratorLength
, dwBufferLength
;
1564 CONFIGRET ret
= CR_SUCCESS
;
1566 for (dwIndex
= 0; ; dwIndex
++)
1568 dwEnumeratorLength
= MAX_DEVICE_ID_LEN
;
1569 dwError
= RegEnumKeyExW(hEnumKey
,
1572 &dwEnumeratorLength
,
1573 NULL
, NULL
, NULL
, NULL
);
1574 if (dwError
!= ERROR_SUCCESS
)
1577 /* Get the size of all device instances for the enumerator */
1578 ret
= GetEnumeratorInstanceListSize(szEnumeratorBuffer
,
1580 if (ret
!= CR_SUCCESS
)
1583 *pulLength
+= dwBufferLength
;
1593 PNP_GetDeviceListSize(
1596 PNP_RPC_BUFFER_SIZE
*pulLength
,
1599 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1600 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1601 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1602 CONFIGRET ret
= CR_SUCCESS
;
1604 DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%08lx)\n",
1605 hBinding
, pszFilter
, pulLength
, ulFlags
);
1607 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
1608 return CR_INVALID_FLAG
;
1610 if (pulLength
== NULL
)
1611 return CR_INVALID_POINTER
;
1613 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
1614 (pszFilter
== NULL
))
1615 return CR_INVALID_POINTER
;
1620 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
1621 CM_GETIDLIST_FILTER_POWERRELATIONS
|
1622 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
1623 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
1625 ret
= GetRelationsInstanceListSize(pszFilter
,
1629 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
1631 ret
= GetServiceInstanceListSize(pszFilter
,
1634 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
1636 SplitDeviceInstanceID(pszFilter
,
1641 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
1643 ret
= GetDeviceInstanceListSize(pszFilter
,
1648 ret
= GetEnumeratorInstanceListSize(pszFilter
,
1652 else /* CM_GETIDLIST_FILTER_NONE */
1654 ret
= GetAllInstanceListSize(pulLength
);
1657 /* Add one character for the terminating double UNICODE_NULL */
1658 if (ret
== CR_SUCCESS
)
1674 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
1675 CONFIGRET ret
= CR_SUCCESS
;
1678 UNREFERENCED_PARAMETER(hBinding
);
1679 UNREFERENCED_PARAMETER(ulFlags
);
1681 DPRINT("PNP_GetDepth(%p %S %p 0x%08lx)\n",
1682 hBinding
, pszDeviceID
, pulDepth
, ulFlags
);
1684 if (!IsValidDeviceInstanceID(pszDeviceID
))
1685 return CR_INVALID_DEVINST
;
1687 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1690 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
1691 (PVOID
)&PlugPlayData
,
1692 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
1693 if (NT_SUCCESS(Status
))
1695 *pulDepth
= PlugPlayData
.Depth
;
1699 ret
= NtStatusToCrError(Status
);
1702 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
1711 PNP_GetDeviceRegProp(
1715 DWORD
*pulRegDataType
,
1717 PNP_PROP_SIZE
*pulTransferLen
,
1718 PNP_PROP_SIZE
*pulLength
,
1721 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
1722 CONFIGRET ret
= CR_SUCCESS
;
1723 LPWSTR lpValueName
= NULL
;
1728 UNREFERENCED_PARAMETER(hBinding
);
1730 DPRINT("PNP_GetDeviceRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
1731 hBinding
, pDeviceID
, ulProperty
, pulRegDataType
, Buffer
,
1732 pulTransferLen
, pulLength
, ulFlags
);
1734 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1736 ret
= CR_INVALID_POINTER
;
1742 ret
= CR_INVALID_FLAG
;
1746 /* Check pDeviceID */
1747 if (!IsValidDeviceInstanceID(pDeviceID
))
1749 ret
= CR_INVALID_DEVINST
;
1753 if (*pulLength
< *pulTransferLen
)
1754 *pulLength
= *pulTransferLen
;
1756 *pulTransferLen
= 0;
1760 case CM_DRP_DEVICEDESC
:
1761 lpValueName
= L
"DeviceDesc";
1764 case CM_DRP_HARDWAREID
:
1765 lpValueName
= L
"HardwareID";
1768 case CM_DRP_COMPATIBLEIDS
:
1769 lpValueName
= L
"CompatibleIDs";
1772 case CM_DRP_SERVICE
:
1773 lpValueName
= L
"Service";
1777 lpValueName
= L
"Class";
1780 case CM_DRP_CLASSGUID
:
1781 lpValueName
= L
"ClassGUID";
1785 lpValueName
= L
"Driver";
1788 case CM_DRP_CONFIGFLAGS
:
1789 lpValueName
= L
"ConfigFlags";
1793 lpValueName
= L
"Mfg";
1796 case CM_DRP_FRIENDLYNAME
:
1797 lpValueName
= L
"FriendlyName";
1800 case CM_DRP_LOCATION_INFORMATION
:
1801 lpValueName
= L
"LocationInformation";
1804 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
1805 PlugPlayData
.Property
= PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME
;
1806 *pulRegDataType
= REG_SZ
;
1809 case CM_DRP_CAPABILITIES
:
1810 lpValueName
= L
"Capabilities";
1813 case CM_DRP_UI_NUMBER
:
1814 PlugPlayData
.Property
= PNP_PROPERTY_UI_NUMBER
;
1817 case CM_DRP_UPPERFILTERS
:
1818 lpValueName
= L
"UpperFilters";
1821 case CM_DRP_LOWERFILTERS
:
1822 lpValueName
= L
"LowerFilters";
1825 case CM_DRP_BUSTYPEGUID
:
1826 PlugPlayData
.Property
= PNP_PROPERTY_BUSTYPEGUID
;
1827 *pulRegDataType
= REG_BINARY
;
1830 case CM_DRP_LEGACYBUSTYPE
:
1831 PlugPlayData
.Property
= PNP_PROPERTY_LEGACYBUSTYPE
;
1832 *pulRegDataType
= REG_DWORD
;
1835 case CM_DRP_BUSNUMBER
:
1836 PlugPlayData
.Property
= PNP_PROPERTY_BUSNUMBER
;
1837 *pulRegDataType
= REG_DWORD
;
1840 case CM_DRP_ENUMERATOR_NAME
:
1841 PlugPlayData
.Property
= PNP_PROPERTY_ENUMERATOR_NAME
;
1842 *pulRegDataType
= REG_SZ
;
1845 case CM_DRP_SECURITY
:
1846 lpValueName
= L
"Security";
1849 case CM_DRP_DEVTYPE
:
1850 lpValueName
= L
"DeviceType";
1853 case CM_DRP_EXCLUSIVE
:
1854 lpValueName
= L
"Exclusive";
1857 case CM_DRP_CHARACTERISTICS
:
1858 lpValueName
= L
"DeviceCharacteristics";
1861 case CM_DRP_ADDRESS
:
1862 PlugPlayData
.Property
= PNP_PROPERTY_ADDRESS
;
1863 *pulRegDataType
= REG_DWORD
;
1866 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1867 lpValueName
= L
"UINumberDescFormat";
1870 case CM_DRP_DEVICE_POWER_DATA
:
1871 PlugPlayData
.Property
= PNP_PROPERTY_POWER_DATA
;
1872 *pulRegDataType
= REG_BINARY
;
1875 case CM_DRP_REMOVAL_POLICY
:
1876 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY
;
1877 *pulRegDataType
= REG_DWORD
;
1880 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
1881 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
;
1882 *pulRegDataType
= REG_DWORD
;
1885 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1886 lpValueName
= L
"RemovalPolicy";
1887 *pulRegDataType
= REG_DWORD
;
1890 case CM_DRP_INSTALL_STATE
:
1891 PlugPlayData
.Property
= PNP_PROPERTY_INSTALL_STATE
;
1892 *pulRegDataType
= REG_DWORD
;
1895 #if (WINVER >= _WIN32_WINNT_WS03)
1896 case CM_DRP_LOCATION_PATHS
:
1897 PlugPlayData
.Property
= PNP_PROPERTY_LOCATION_PATHS
;
1898 *pulRegDataType
= REG_MULTI_SZ
;
1902 #if (WINVER >= _WIN32_WINNT_WIN7)
1903 case CM_DRP_BASE_CONTAINERID
:
1904 PlugPlayData
.Property
= PNP_PROPERTY_CONTAINERID
;
1905 *pulRegDataType
= REG_SZ
;
1910 ret
= CR_INVALID_PROPERTY
;
1914 DPRINT("Value name: %S\n", lpValueName
);
1918 /* Retrieve information from the Registry */
1919 lError
= RegOpenKeyExW(hEnumKey
,
1924 if (lError
!= ERROR_SUCCESS
)
1928 ret
= CR_INVALID_DEVNODE
;
1932 lError
= RegQueryValueExW(hKey
,
1938 if (lError
!= ERROR_SUCCESS
)
1940 if (lError
== ERROR_MORE_DATA
)
1942 ret
= CR_BUFFER_SMALL
;
1947 ret
= CR_NO_SUCH_VALUE
;
1953 /* Retrieve information from the Device Node */
1954 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1956 PlugPlayData
.Buffer
= Buffer
;
1957 PlugPlayData
.BufferSize
= *pulLength
;
1959 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
1960 (PVOID
)&PlugPlayData
,
1961 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
1962 if (NT_SUCCESS(Status
))
1964 *pulLength
= PlugPlayData
.BufferSize
;
1968 ret
= NtStatusToCrError(Status
);
1974 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1979 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1988 PNP_SetDeviceRegProp(
1994 PNP_PROP_SIZE ulLength
,
1997 CONFIGRET ret
= CR_SUCCESS
;
1998 LPWSTR lpValueName
= NULL
;
2001 UNREFERENCED_PARAMETER(hBinding
);
2002 UNREFERENCED_PARAMETER(ulFlags
);
2004 DPRINT("PNP_SetDeviceRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2005 hBinding
, pDeviceId
, ulProperty
, ulDataType
, Buffer
,
2008 if (!IsValidDeviceInstanceID(pDeviceId
))
2009 return CR_INVALID_DEVINST
;
2013 case CM_DRP_DEVICEDESC
:
2014 lpValueName
= L
"DeviceDesc";
2017 case CM_DRP_HARDWAREID
:
2018 lpValueName
= L
"HardwareID";
2021 case CM_DRP_COMPATIBLEIDS
:
2022 lpValueName
= L
"CompatibleIDs";
2025 case CM_DRP_SERVICE
:
2026 lpValueName
= L
"Service";
2030 lpValueName
= L
"Class";
2033 case CM_DRP_CLASSGUID
:
2034 lpValueName
= L
"ClassGUID";
2038 lpValueName
= L
"Driver";
2041 case CM_DRP_CONFIGFLAGS
:
2042 lpValueName
= L
"ConfigFlags";
2046 lpValueName
= L
"Mfg";
2049 case CM_DRP_FRIENDLYNAME
:
2050 lpValueName
= L
"FriendlyName";
2053 case CM_DRP_LOCATION_INFORMATION
:
2054 lpValueName
= L
"LocationInformation";
2057 case CM_DRP_UPPERFILTERS
:
2058 lpValueName
= L
"UpperFilters";
2061 case CM_DRP_LOWERFILTERS
:
2062 lpValueName
= L
"LowerFilters";
2065 case CM_DRP_SECURITY
:
2066 lpValueName
= L
"Security";
2069 case CM_DRP_DEVTYPE
:
2070 lpValueName
= L
"DeviceType";
2073 case CM_DRP_EXCLUSIVE
:
2074 lpValueName
= L
"Exclusive";
2077 case CM_DRP_CHARACTERISTICS
:
2078 lpValueName
= L
"DeviceCharacteristics";
2081 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
2082 lpValueName
= L
"UINumberDescFormat";
2085 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
2086 lpValueName
= L
"RemovalPolicy";
2090 return CR_INVALID_PROPERTY
;
2093 DPRINT("Value name: %S\n", lpValueName
);
2095 if (RegOpenKeyExW(hEnumKey
,
2100 return CR_INVALID_DEVNODE
;
2104 if (RegDeleteValueW(hKey
,
2106 ret
= CR_REGISTRY_ERROR
;
2110 if (RegSetValueExW(hKey
,
2116 ret
= CR_REGISTRY_ERROR
;
2121 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
2130 PNP_GetClassInstance(
2133 LPWSTR pszClassInstance
,
2134 PNP_RPC_STRING_LEN ulLength
)
2136 WCHAR szClassGuid
[40];
2137 WCHAR szClassInstance
[5];
2138 HKEY hDeviceClassKey
= NULL
;
2139 HKEY hClassInstanceKey
;
2140 ULONG ulTransferLength
, ulDataLength
;
2141 DWORD dwDataType
, dwDisposition
, i
;
2143 CONFIGRET ret
= CR_SUCCESS
;
2145 DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n",
2146 hBinding
, pDeviceId
, pszClassInstance
, ulLength
);
2148 if (!IsValidDeviceInstanceID(pDeviceId
))
2149 return CR_INVALID_DEVINST
;
2151 ulTransferLength
= ulLength
;
2152 ret
= PNP_GetDeviceRegProp(hBinding
,
2156 (BYTE
*)pszClassInstance
,
2160 if (ret
== CR_SUCCESS
)
2163 ulTransferLength
= sizeof(szClassGuid
);
2164 ulDataLength
= sizeof(szClassGuid
);
2165 ret
= PNP_GetDeviceRegProp(hBinding
,
2169 (BYTE
*)szClassGuid
,
2173 if (ret
!= CR_SUCCESS
)
2175 DPRINT1("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret
);
2179 dwError
= RegOpenKeyExW(hClassKey
,
2184 if (dwError
!= ERROR_SUCCESS
)
2186 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError
);
2191 for (i
= 0; i
< 10000; i
++)
2193 wsprintf(szClassInstance
, L
"%04lu", i
);
2195 dwError
= RegCreateKeyExW(hDeviceClassKey
,
2199 REG_OPTION_NON_VOLATILE
,
2204 if (dwError
== ERROR_SUCCESS
)
2206 RegCloseKey(hClassInstanceKey
);
2208 if (dwDisposition
== REG_CREATED_NEW_KEY
)
2210 wsprintf(pszClassInstance
,
2215 ulDataLength
= (wcslen(pszClassInstance
) + 1) * sizeof(WCHAR
);
2216 ret
= PNP_SetDeviceRegProp(hBinding
,
2220 (BYTE
*)pszClassInstance
,
2223 if (ret
!= CR_SUCCESS
)
2225 DPRINT1("PNP_SetDeviceRegProp() failed (Error %lu)\n", ret
);
2226 RegDeleteKeyW(hDeviceClassKey
,
2236 if (hDeviceClassKey
!= NULL
)
2237 RegCloseKey(hDeviceClassKey
);
2252 HKEY hDeviceKey
= NULL
, hParametersKey
= NULL
;
2254 CONFIGRET ret
= CR_SUCCESS
;
2256 UNREFERENCED_PARAMETER(hBinding
);
2257 UNREFERENCED_PARAMETER(samDesired
);
2259 DPRINT("PNP_CreateKey(%p %S 0x%lx 0x%08lx)\n",
2260 hBinding
, pszSubKey
, samDesired
, ulFlags
);
2263 return CR_INVALID_FLAG
;
2265 if (!IsValidDeviceInstanceID(pszSubKey
))
2266 return CR_INVALID_DEVINST
;
2268 dwError
= RegOpenKeyExW(hEnumKey
,
2273 if (dwError
!= ERROR_SUCCESS
)
2275 ret
= CR_INVALID_DEVNODE
;
2279 dwError
= RegCreateKeyExW(hDeviceKey
,
2280 L
"Device Parameters",
2283 REG_OPTION_NON_VOLATILE
,
2288 if (dwError
!= ERROR_SUCCESS
)
2290 ret
= CR_REGISTRY_ERROR
;
2294 /* FIXME: Set key security */
2297 if (hParametersKey
!= NULL
)
2298 RegCloseKey(hParametersKey
);
2300 if (hDeviceKey
!= NULL
)
2301 RegCloseKey(hDeviceKey
);
2310 PNP_DeleteRegistryKey(
2313 LPWSTR pszParentKey
,
2318 return CR_CALL_NOT_IMPLEMENTED
;
2327 DWORD
*pulClassCount
,
2333 UNREFERENCED_PARAMETER(hBinding
);
2334 UNREFERENCED_PARAMETER(ulFlags
);
2336 DPRINT("PNP_GetClassCount(%p %p 0x%08lx)\n",
2337 hBinding
, pulClassCount
, ulFlags
);
2339 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2344 if (dwError
!= ERROR_SUCCESS
)
2345 return CR_INVALID_DATA
;
2347 dwError
= RegQueryInfoKeyW(hKey
,
2360 if (dwError
!= ERROR_SUCCESS
)
2361 return CR_INVALID_DATA
;
2372 LPWSTR pszClassGuid
,
2374 PNP_RPC_STRING_LEN
*pulLength
,
2377 WCHAR szKeyName
[MAX_PATH
];
2378 CONFIGRET ret
= CR_SUCCESS
;
2382 UNREFERENCED_PARAMETER(hBinding
);
2383 UNREFERENCED_PARAMETER(ulFlags
);
2385 DPRINT("PNP_GetClassName(%p %S %p %p 0x%08lx)\n",
2386 hBinding
, pszClassGuid
, Buffer
, pulLength
, ulFlags
);
2388 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
2389 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
2390 lstrcatW(szKeyName
, pszClassGuid
);
2392 return CR_INVALID_DATA
;
2394 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2399 return CR_REGISTRY_ERROR
;
2401 dwSize
= *pulLength
* sizeof(WCHAR
);
2402 if (RegQueryValueExW(hKey
,
2410 ret
= CR_REGISTRY_ERROR
;
2414 *pulLength
= dwSize
/ sizeof(WCHAR
);
2419 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
2430 LPWSTR pszClassGuid
,
2433 CONFIGRET ret
= CR_SUCCESS
;
2435 UNREFERENCED_PARAMETER(hBinding
);
2437 DPRINT("PNP_DeleteClassKey(%p %S 0x%08lx)\n",
2438 hBinding
, pszClassGuid
, ulFlags
);
2440 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
2442 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
2443 ret
= CR_REGISTRY_ERROR
;
2447 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
2448 ret
= CR_REGISTRY_ERROR
;
2451 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
2460 PNP_GetInterfaceDeviceAlias(
2462 LPWSTR pszInterfaceDevice
,
2463 GUID
*AliasInterfaceGuid
,
2464 LPWSTR pszAliasInterfaceDevice
,
2465 PNP_RPC_STRING_LEN
*pulLength
,
2466 PNP_RPC_STRING_LEN
*pulTransferLen
,
2470 return CR_CALL_NOT_IMPLEMENTED
;
2477 PNP_GetInterfaceDeviceList(
2479 GUID
*InterfaceGuid
,
2482 PNP_RPC_BUFFER_SIZE
*pulLength
,
2486 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
2487 DWORD ret
= CR_SUCCESS
;
2489 UNREFERENCED_PARAMETER(hBinding
);
2491 DPRINT("PNP_GetInterfaceDeviceList(%p %p %S %p %p 0x%08lx)\n",
2492 hBinding
, InterfaceGuid
, pszDeviceID
, Buffer
, pulLength
, ulFlags
);
2494 if (!IsValidDeviceInstanceID(pszDeviceID
))
2495 return CR_INVALID_DEVINST
;
2497 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2500 PlugPlayData
.Flags
= ulFlags
;
2501 PlugPlayData
.FilterGuid
= InterfaceGuid
;
2502 PlugPlayData
.Buffer
= Buffer
;
2503 PlugPlayData
.BufferSize
= *pulLength
;
2505 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
2506 (PVOID
)&PlugPlayData
,
2507 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
2508 if (NT_SUCCESS(Status
))
2510 *pulLength
= PlugPlayData
.BufferSize
;
2514 ret
= NtStatusToCrError(Status
);
2517 DPRINT("PNP_GetInterfaceDeviceList() done (returns %lx)\n", ret
);
2525 PNP_GetInterfaceDeviceListSize(
2527 PNP_RPC_BUFFER_SIZE
*pulLen
,
2528 GUID
*InterfaceGuid
,
2533 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
2534 DWORD ret
= CR_SUCCESS
;
2536 UNREFERENCED_PARAMETER(hBinding
);
2538 DPRINT("PNP_GetInterfaceDeviceListSize(%p %p %p %S 0x%08lx)\n",
2539 hBinding
, pulLen
, InterfaceGuid
, pszDeviceID
, ulFlags
);
2541 if (!IsValidDeviceInstanceID(pszDeviceID
))
2542 return CR_INVALID_DEVINST
;
2544 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2547 PlugPlayData
.FilterGuid
= InterfaceGuid
;
2548 PlugPlayData
.Buffer
= NULL
;
2549 PlugPlayData
.BufferSize
= 0;
2550 PlugPlayData
.Flags
= ulFlags
;
2552 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
2553 (PVOID
)&PlugPlayData
,
2554 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
2555 if (NT_SUCCESS(Status
))
2557 *pulLen
= PlugPlayData
.BufferSize
;
2561 ret
= NtStatusToCrError(Status
);
2564 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
2572 PNP_RegisterDeviceClassAssociation(
2575 GUID
*InterfaceGuid
,
2576 LPWSTR pszReference
,
2578 PNP_RPC_STRING_LEN
*pulLength
,
2579 PNP_RPC_STRING_LEN
*pulTransferLen
,
2583 return CR_CALL_NOT_IMPLEMENTED
;
2590 PNP_UnregisterDeviceClassAssociation(
2592 LPWSTR pszInterfaceDevice
,
2596 return CR_CALL_NOT_IMPLEMENTED
;
2603 PNP_GetClassRegProp(
2605 LPWSTR pszClassGuid
,
2607 DWORD
*pulRegDataType
,
2609 PNP_RPC_STRING_LEN
*pulTransferLen
,
2610 PNP_RPC_STRING_LEN
*pulLength
,
2613 CONFIGRET ret
= CR_SUCCESS
;
2614 LPWSTR lpValueName
= NULL
;
2615 HKEY hInstKey
= NULL
;
2616 HKEY hPropKey
= NULL
;
2619 UNREFERENCED_PARAMETER(hBinding
);
2621 DPRINT("PNP_GetClassRegProp(%p %S %lu %p %p %p %p 0x%08lx)\n",
2622 hBinding
, pszClassGuid
, ulProperty
, pulRegDataType
,
2623 Buffer
, pulTransferLen
, pulLength
, ulFlags
);
2625 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2627 ret
= CR_INVALID_POINTER
;
2633 ret
= CR_INVALID_FLAG
;
2637 if (*pulLength
< *pulTransferLen
)
2638 *pulLength
= *pulTransferLen
;
2640 *pulTransferLen
= 0;
2644 case CM_CRP_SECURITY
:
2645 lpValueName
= L
"Security";
2648 case CM_CRP_DEVTYPE
:
2649 lpValueName
= L
"DeviceType";
2652 case CM_CRP_EXCLUSIVE
:
2653 lpValueName
= L
"Exclusive";
2656 case CM_CRP_CHARACTERISTICS
:
2657 lpValueName
= L
"DeviceCharacteristics";
2661 ret
= CR_INVALID_PROPERTY
;
2665 DPRINT("Value name: %S\n", lpValueName
);
2667 lError
= RegOpenKeyExW(hClassKey
,
2672 if (lError
!= ERROR_SUCCESS
)
2675 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2679 lError
= RegOpenKeyExW(hInstKey
,
2684 if (lError
!= ERROR_SUCCESS
)
2687 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2691 lError
= RegQueryValueExW(hPropKey
,
2697 if (lError
!= ERROR_SUCCESS
)
2699 if (lError
== ERROR_MORE_DATA
)
2701 ret
= CR_BUFFER_SMALL
;
2706 ret
= CR_NO_SUCH_VALUE
;
2711 if (ret
== CR_SUCCESS
)
2712 *pulTransferLen
= *pulLength
;
2714 if (hPropKey
!= NULL
)
2715 RegCloseKey(hPropKey
);
2717 if (hInstKey
!= NULL
)
2718 RegCloseKey(hInstKey
);
2720 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
2729 PNP_SetClassRegProp(
2731 LPWSTR pszClassGuid
,
2735 PNP_PROP_SIZE ulLength
,
2738 CONFIGRET ret
= CR_SUCCESS
;
2739 LPWSTR lpValueName
= NULL
;
2744 UNREFERENCED_PARAMETER(hBinding
);
2746 DPRINT("PNP_SetClassRegProp(%p %S %lu %lu %p %lu 0x%08lx)\n",
2747 hBinding
, pszClassGuid
, ulProperty
, ulDataType
,
2748 Buffer
, ulLength
, ulFlags
);
2751 return CR_INVALID_FLAG
;
2755 case CM_CRP_SECURITY
:
2756 lpValueName
= L
"Security";
2759 case CM_CRP_DEVTYPE
:
2760 lpValueName
= L
"DeviceType";
2763 case CM_CRP_EXCLUSIVE
:
2764 lpValueName
= L
"Exclusive";
2767 case CM_CRP_CHARACTERISTICS
:
2768 lpValueName
= L
"DeviceCharacteristics";
2772 return CR_INVALID_PROPERTY
;
2775 lError
= RegOpenKeyExW(hClassKey
,
2780 if (lError
!= ERROR_SUCCESS
)
2782 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2786 /* FIXME: Set security descriptor */
2787 lError
= RegCreateKeyExW(hInstKey
,
2791 REG_OPTION_NON_VOLATILE
,
2796 if (lError
!= ERROR_SUCCESS
)
2798 ret
= CR_REGISTRY_ERROR
;
2804 if (RegDeleteValueW(hPropKey
,
2806 ret
= CR_REGISTRY_ERROR
;
2810 if (RegSetValueExW(hPropKey
,
2816 ret
= CR_REGISTRY_ERROR
;
2820 if (hPropKey
!= NULL
)
2821 RegCloseKey(hPropKey
);
2823 if (hInstKey
!= NULL
)
2824 RegCloseKey(hInstKey
);
2831 CreateDeviceInstance(LPWSTR pszDeviceID
)
2833 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
2834 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
2835 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
2836 HKEY hKeyEnumerator
;
2842 /* Split the instance ID */
2843 SplitDeviceInstanceID(pszDeviceID
,
2848 /* Open or create the enumerator key */
2849 lError
= RegCreateKeyExW(hEnumKey
,
2853 REG_OPTION_NON_VOLATILE
,
2858 if (lError
!= ERROR_SUCCESS
)
2860 return CR_REGISTRY_ERROR
;
2863 /* Open or create the device key */
2864 lError
= RegCreateKeyExW(hKeyEnumerator
,
2868 REG_OPTION_NON_VOLATILE
,
2874 /* Close the enumerator key */
2875 RegCloseKey(hKeyEnumerator
);
2877 if (lError
!= ERROR_SUCCESS
)
2879 return CR_REGISTRY_ERROR
;
2882 /* Try to open the instance key and fail if it exists */
2883 lError
= RegOpenKeyExW(hKeyDevice
,
2888 if (lError
== ERROR_SUCCESS
)
2890 DPRINT1("Instance %S already exists!\n", szInstance
);
2891 RegCloseKey(hKeyInstance
);
2892 RegCloseKey(hKeyDevice
);
2893 return CR_ALREADY_SUCH_DEVINST
;
2896 /* Create a new instance key */
2897 lError
= RegCreateKeyExW(hKeyDevice
,
2901 REG_OPTION_NON_VOLATILE
,
2907 /* Close the device key */
2908 RegCloseKey(hKeyDevice
);
2910 if (lError
!= ERROR_SUCCESS
)
2912 return CR_REGISTRY_ERROR
;
2915 /* Create the 'Control' sub key */
2916 lError
= RegCreateKeyExW(hKeyInstance
,
2920 REG_OPTION_NON_VOLATILE
,
2925 if (lError
== ERROR_SUCCESS
)
2927 RegCloseKey(hKeyControl
);
2930 RegCloseKey(hKeyInstance
);
2932 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
2942 LPWSTR pszParentDeviceID
,
2943 PNP_RPC_STRING_LEN ulLength
,
2946 CONFIGRET ret
= CR_SUCCESS
;
2948 DPRINT("PNP_CreateDevInst(%p %S %S %lu 0x%08lx)\n",
2949 hBinding
, pszParentDeviceID
, pszDeviceID
, ulLength
, ulFlags
);
2951 if (ulFlags
& ~CM_CREATE_DEVNODE_BITS
)
2952 return CR_INVALID_FLAG
;
2954 if (pszDeviceID
== NULL
|| pszParentDeviceID
== NULL
)
2955 return CR_INVALID_POINTER
;
2957 /* Fail, if the parent device is not the root device */
2958 if (!IsRootDeviceInstanceID(pszParentDeviceID
))
2959 return CR_INVALID_DEVINST
;
2961 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
2963 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
2964 DWORD dwInstanceNumber
;
2966 /* Generated ID is: Root\<Device ID>\<Instance number> */
2967 dwInstanceNumber
= 0;
2970 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
2971 pszDeviceID
, dwInstanceNumber
);
2973 /* Try to create a device instance with this ID */
2974 ret
= CreateDeviceInstance(szGeneratedInstance
);
2978 while (ret
== CR_ALREADY_SUCH_DEVINST
);
2980 if (ret
== CR_SUCCESS
)
2982 /* pszDeviceID is an out parameter too for generated IDs */
2983 if (wcslen(szGeneratedInstance
) > ulLength
)
2985 ret
= CR_BUFFER_SMALL
;
2989 wcscpy(pszDeviceID
, szGeneratedInstance
);
2995 /* Create the device instance */
2996 ret
= CreateDeviceInstance(pszDeviceID
);
2999 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
3006 SetupDeviceInstance(
3007 _In_ LPWSTR pszDeviceInstance
,
3008 _In_ DWORD ulMinorAction
)
3010 HKEY hDeviceKey
= NULL
;
3011 DWORD dwDisableCount
, dwSize
;
3012 DWORD ulStatus
, ulProblem
;
3014 CONFIGRET ret
= CR_SUCCESS
;
3016 DPRINT1("SetupDeviceInstance(%S 0x%08lx)\n",
3017 pszDeviceInstance
, ulMinorAction
);
3019 if (IsRootDeviceInstanceID(pszDeviceInstance
))
3020 return CR_INVALID_DEVINST
;
3022 if (ulMinorAction
& ~CM_SETUP_BITS
)
3023 return CR_INVALID_FLAG
;
3025 if ((ulMinorAction
== CM_SETUP_DOWNLOAD
) ||
3026 (ulMinorAction
== CM_SETUP_WRITE_LOG_CONFS
))
3029 dwError
= RegOpenKeyExW(hEnumKey
,
3034 if (dwError
!= ERROR_SUCCESS
)
3035 return CR_INVALID_DEVNODE
;
3037 dwSize
= sizeof(dwDisableCount
);
3038 dwError
= RegQueryValueExW(hDeviceKey
,
3042 (LPBYTE
)&dwDisableCount
,
3044 if ((dwError
== ERROR_SUCCESS
) &&
3045 (dwDisableCount
> 0))
3050 GetDeviceStatus(pszDeviceInstance
,
3054 if (ulStatus
& DN_STARTED
)
3059 if (ulStatus
& DN_HAS_PROBLEM
)
3061 ret
= ClearDeviceStatus(pszDeviceInstance
,
3066 if (ret
!= CR_SUCCESS
)
3070 /* FIXME: Start the device */
3073 if (hDeviceKey
!= NULL
)
3074 RegCloseKey(hDeviceKey
);
3081 EnableDeviceInstance(
3082 _In_ LPWSTR pszDeviceInstance
)
3084 PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ResetDeviceData
;
3085 CONFIGRET ret
= CR_SUCCESS
;
3088 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
3090 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
,
3092 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
,
3094 sizeof(PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA
));
3095 if (!NT_SUCCESS(Status
))
3096 ret
= NtStatusToCrError(Status
);
3103 ReenumerateDeviceInstance(
3104 _In_ LPWSTR pszDeviceInstance
,
3105 _In_ ULONG ulMinorAction
)
3107 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData
;
3108 CONFIGRET ret
= CR_SUCCESS
;
3111 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
3112 pszDeviceInstance
, ulMinorAction
);
3114 if (ulMinorAction
& ~CM_REENUMERATE_BITS
)
3115 return CR_INVALID_FLAG
;
3117 if (ulMinorAction
& CM_REENUMERATE_RETRY_INSTALLATION
)
3119 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
3122 RtlInitUnicodeString(&EnumerateDeviceData
.DeviceInstance
,
3124 EnumerateDeviceData
.Flags
= 0;
3126 Status
= NtPlugPlayControl(PlugPlayControlEnumerateDevice
,
3127 &EnumerateDeviceData
,
3128 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA
));
3129 if (!NT_SUCCESS(Status
))
3130 ret
= NtStatusToCrError(Status
);
3139 PNP_DeviceInstanceAction(
3141 DWORD ulMajorAction
,
3142 DWORD ulMinorAction
,
3143 LPWSTR pszDeviceInstance1
,
3144 LPWSTR pszDeviceInstance2
)
3146 CONFIGRET ret
= CR_SUCCESS
;
3148 UNREFERENCED_PARAMETER(hBinding
);
3150 DPRINT("PNP_DeviceInstanceAction(%p %lu 0x%08lx %S %S)\n",
3151 hBinding
, ulMajorAction
, ulMinorAction
,
3152 pszDeviceInstance1
, pszDeviceInstance2
);
3154 switch (ulMajorAction
)
3156 case PNP_DEVINST_SETUP
:
3157 ret
= SetupDeviceInstance(pszDeviceInstance1
,
3161 case PNP_DEVINST_ENABLE
:
3162 ret
= EnableDeviceInstance(pszDeviceInstance1
);
3165 case PNP_DEVINST_REENUMERATE
:
3166 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
,
3171 DPRINT1("Unknown device action %lu: not implemented\n", ulMajorAction
);
3172 ret
= CR_CALL_NOT_IMPLEMENTED
;
3175 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
3184 PNP_GetDeviceStatus(
3191 UNREFERENCED_PARAMETER(hBinding
);
3192 UNREFERENCED_PARAMETER(ulFlags
);
3194 DPRINT("PNP_GetDeviceStatus(%p %S %p %p)\n",
3195 hBinding
, pDeviceID
, pulStatus
, pulProblem
, ulFlags
);
3197 if (!IsValidDeviceInstanceID(pDeviceID
))
3198 return CR_INVALID_DEVINST
;
3200 return GetDeviceStatus(pDeviceID
, pulStatus
, pulProblem
);
3207 PNP_SetDeviceProblem(
3214 return CR_CALL_NOT_IMPLEMENTED
;
3224 PPNP_VETO_TYPE pVetoType
,
3229 UNREFERENCED_PARAMETER(hBinding
);
3231 DPRINT1("PNP_DisableDevInst(%p %S %p %p %lu 0x%08lx)\n",
3232 hBinding
, pDeviceID
, pVetoType
, pszVetoName
, ulNameLength
, ulFlags
);
3234 if (ulFlags
& ~CM_DISABLE_BITS
)
3235 return CR_INVALID_FLAG
;
3237 if (!IsValidDeviceInstanceID(pDeviceID
) ||
3238 IsRootDeviceInstanceID(pDeviceID
))
3239 return CR_INVALID_DEVINST
;
3241 return DisableDeviceInstance(pDeviceID
,
3251 PNP_UninstallDevInst(
3257 return CR_CALL_NOT_IMPLEMENTED
;
3262 CheckForDeviceId(LPWSTR lpDeviceIdList
,
3268 lpPtr
= lpDeviceIdList
;
3271 dwLength
= wcslen(lpPtr
);
3272 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
3275 lpPtr
+= (dwLength
+ 1);
3283 AppendDeviceId(LPWSTR lpDeviceIdList
,
3284 LPDWORD lpDeviceIdListSize
,
3290 dwLen
= wcslen(lpDeviceId
);
3291 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
3293 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
3295 dwPos
+= (dwLen
+ 1);
3297 lpDeviceIdList
[dwPos
] = 0;
3299 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
3312 CONFIGRET ret
= CR_SUCCESS
;
3315 DWORD dwDeviceIdListSize
;
3316 DWORD dwNewDeviceIdSize
;
3317 WCHAR
* pszDeviceIdList
= NULL
;
3319 UNREFERENCED_PARAMETER(hBinding
);
3321 DPRINT("PNP_AddID(%p %S %S 0x%08lx)\n",
3322 hBinding
, pszDeviceID
, pszID
, ulFlags
);
3324 if (RegOpenKeyExW(hEnumKey
,
3327 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
3328 &hDeviceKey
) != ERROR_SUCCESS
)
3330 DPRINT("Failed to open the device key!\n");
3331 return CR_INVALID_DEVNODE
;
3334 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
3336 if (RegQueryValueExW(hDeviceKey
,
3341 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
3343 DPRINT("Failed to query the desired ID string!\n");
3344 ret
= CR_REGISTRY_ERROR
;
3348 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
3349 if (!dwNewDeviceIdSize
)
3351 ret
= CR_INVALID_POINTER
;
3355 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
3357 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
3358 if (!pszDeviceIdList
)
3360 DPRINT("Failed to allocate memory for the desired ID string!\n");
3361 ret
= CR_OUT_OF_MEMORY
;
3365 if (RegQueryValueExW(hDeviceKey
,
3369 (LPBYTE
)pszDeviceIdList
,
3370 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
3372 DPRINT("Failed to query the desired ID string!\n");
3373 ret
= CR_REGISTRY_ERROR
;
3377 /* Check whether the device ID is already in use */
3378 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
3380 DPRINT("Device ID was found in the ID string!\n");
3385 /* Append the Device ID */
3386 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
3388 if (RegSetValueExW(hDeviceKey
,
3392 (LPBYTE
)pszDeviceIdList
,
3393 dwDeviceIdListSize
) != ERROR_SUCCESS
)
3395 DPRINT("Failed to set the desired ID string!\n");
3396 ret
= CR_REGISTRY_ERROR
;
3400 RegCloseKey(hDeviceKey
);
3401 if (pszDeviceIdList
)
3402 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
3404 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
3418 DPRINT("PNP_RegisterDriver(%p %S 0x%lx)\n",
3419 hBinding
, pszDeviceID
, ulFlags
);
3421 if (ulFlags
& ~CM_REGISTER_DEVICE_DRIVER_BITS
)
3422 return CR_INVALID_FLAG
;
3424 if (!IsValidDeviceInstanceID(pszDeviceID
))
3425 return CR_INVALID_DEVINST
;
3427 SetDeviceStatus(pszDeviceID
, 0, 0);
3439 PPNP_VETO_TYPE pVetoType
,
3444 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData
;
3446 DWORD ret
= CR_SUCCESS
;
3448 DPRINT1("PNP_QueryRemove(%p %S %p %p %lu 0x%lx)\n",
3449 hBinding
, pszDeviceID
, pVetoType
, pszVetoName
,
3450 ulNameLength
, ulFlags
);
3452 if (ulFlags
& ~CM_REMOVE_BITS
)
3453 return CR_INVALID_FLAG
;
3455 if (!IsValidDeviceInstanceID(pszDeviceID
) ||
3456 IsRootDeviceInstanceID(pszDeviceID
))
3457 return CR_INVALID_DEVINST
;
3459 if (pVetoType
!= NULL
)
3460 *pVetoType
= PNP_VetoTypeUnknown
;
3462 if (pszVetoName
!= NULL
&& ulNameLength
> 0)
3463 *pszVetoName
= UNICODE_NULL
;
3465 RtlZeroMemory(&PlugPlayData
, sizeof(PlugPlayData
));
3466 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
3468 PlugPlayData
.VetoName
= pszVetoName
;
3469 PlugPlayData
.NameLength
= ulNameLength
;
3470 // PlugPlayData.Flags =
3472 Status
= NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice
,
3474 sizeof(PlugPlayData
));
3475 if (!NT_SUCCESS(Status
))
3476 ret
= NtStatusToCrError(Status
);
3485 PNP_RequestDeviceEject(
3488 PPNP_VETO_TYPE pVetoType
,
3493 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData
;
3495 DWORD ret
= CR_SUCCESS
;
3497 DPRINT1("PNP_RequestDeviceEject(%p %S %p %p %lu 0x%lx)\n",
3498 hBinding
, pszDeviceID
, pVetoType
, pszVetoName
,
3499 ulNameLength
, ulFlags
);
3502 return CR_INVALID_FLAG
;
3504 if (!IsValidDeviceInstanceID(pszDeviceID
))
3505 return CR_INVALID_DEVINST
;
3507 if (pVetoType
!= NULL
)
3508 *pVetoType
= PNP_VetoTypeUnknown
;
3510 if (pszVetoName
!= NULL
&& ulNameLength
> 0)
3511 *pszVetoName
= UNICODE_NULL
;
3513 RtlZeroMemory(&PlugPlayData
, sizeof(PlugPlayData
));
3514 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
3516 PlugPlayData
.VetoName
= pszVetoName
;
3517 PlugPlayData
.NameLength
= ulNameLength
;
3518 // PlugPlayData.Flags =
3520 Status
= NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice
,
3522 sizeof(PlugPlayData
));
3523 if (!NT_SUCCESS(Status
))
3524 ret
= NtStatusToCrError(Status
);
3533 PNP_IsDockStationPresent(
3541 CONFIGRET ret
= CR_SUCCESS
;
3543 UNREFERENCED_PARAMETER(hBinding
);
3545 DPRINT1("PNP_IsDockStationPresent(%p %p)\n",
3550 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
3554 &hKey
) != ERROR_SUCCESS
)
3555 return CR_REGISTRY_ERROR
;
3557 dwSize
= sizeof(DWORD
);
3558 if (RegQueryValueExW(hKey
,
3563 &dwSize
) != ERROR_SUCCESS
)
3564 ret
= CR_REGISTRY_ERROR
;
3568 if (ret
== CR_SUCCESS
)
3570 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
3572 ret
= CR_REGISTRY_ERROR
;
3574 else if (dwValue
!= 0)
3580 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
3592 WCHAR szDockDeviceInstance
[MAX_DEVICE_ID_LEN
];
3593 PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA DockData
;
3596 DPRINT("PNP_RequestEjectPC(%p)\n", hBinding
);
3598 /* Retrieve the dock device */
3599 DockData
.DeviceInstanceLength
= ARRAYSIZE(szDockDeviceInstance
);
3600 DockData
.DeviceInstance
= szDockDeviceInstance
;
3602 Status
= NtPlugPlayControl(PlugPlayControlRetrieveDock
,
3605 if (!NT_SUCCESS(Status
))
3606 return NtStatusToCrError(Status
);
3608 /* Eject the dock device */
3609 return PNP_RequestDeviceEject(hBinding
,
3610 szDockDeviceInstance
,
3627 PPNP_VETO_TYPE pVetoType
,
3632 CONFIGRET ret
= CR_SUCCESS
;
3633 WCHAR szKeyName
[MAX_PATH
];
3638 UNREFERENCED_PARAMETER(hBinding
);
3640 DPRINT("PNP_HwProfFlags() called\n");
3642 if (!IsValidDeviceInstanceID(pDeviceID
))
3643 return CR_INVALID_DEVINST
;
3648 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
3653 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
3657 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3661 &hKey
) != ERROR_SUCCESS
)
3662 return CR_REGISTRY_ERROR
;
3664 if (ulAction
== PNP_GET_HWPROFFLAGS
)
3666 if (RegOpenKeyExW(hKey
,
3670 &hDeviceKey
) != ERROR_SUCCESS
)
3676 dwSize
= sizeof(DWORD
);
3677 if (RegQueryValueExW(hDeviceKey
,
3682 &dwSize
) != ERROR_SUCCESS
)
3687 RegCloseKey(hDeviceKey
);
3690 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
3692 /* FIXME: not implemented yet */
3693 ret
= CR_CALL_NOT_IMPLEMENTED
;
3708 HWPROFILEINFO
*pHWProfileInfo
,
3709 DWORD ulProfileInfoSize
,
3712 WCHAR szProfileName
[5];
3713 HKEY hKeyConfig
= NULL
;
3714 HKEY hKeyProfiles
= NULL
;
3715 HKEY hKeyProfile
= NULL
;
3716 DWORD dwDisposition
;
3719 CONFIGRET ret
= CR_SUCCESS
;
3721 UNREFERENCED_PARAMETER(hBinding
);
3723 DPRINT("PNP_GetHwProfInfo() called\n");
3725 if (ulProfileInfoSize
== 0)
3727 ret
= CR_INVALID_DATA
;
3733 ret
= CR_INVALID_FLAG
;
3737 /* Initialize the profile information */
3738 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
3739 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
3740 pHWProfileInfo
->HWPI_dwFlags
= 0;
3742 /* Open the 'IDConfigDB' key */
3743 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
3744 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
3747 REG_OPTION_NON_VOLATILE
,
3752 if (lError
!= ERROR_SUCCESS
)
3754 ret
= CR_REGISTRY_ERROR
;
3758 /* Open the 'Hardware Profiles' subkey */
3759 lError
= RegCreateKeyExW(hKeyConfig
,
3760 L
"Hardware Profiles",
3763 REG_OPTION_NON_VOLATILE
,
3764 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
3768 if (lError
!= ERROR_SUCCESS
)
3770 ret
= CR_REGISTRY_ERROR
;
3774 if (ulIndex
== (ULONG
)-1)
3776 dwSize
= sizeof(ULONG
);
3777 lError
= RegQueryValueExW(hKeyConfig
,
3781 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
3783 if (lError
!= ERROR_SUCCESS
)
3785 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
3786 ret
= CR_REGISTRY_ERROR
;
3792 /* FIXME: not implemented yet */
3793 ret
= CR_CALL_NOT_IMPLEMENTED
;
3797 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
3799 lError
= RegOpenKeyExW(hKeyProfiles
,
3804 if (lError
!= ERROR_SUCCESS
)
3806 ret
= CR_REGISTRY_ERROR
;
3810 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
3811 lError
= RegQueryValueExW(hKeyProfile
,
3815 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
3817 if (lError
!= ERROR_SUCCESS
)
3819 ret
= CR_REGISTRY_ERROR
;
3824 if (hKeyProfile
!= NULL
)
3825 RegCloseKey(hKeyProfile
);
3827 if (hKeyProfiles
!= NULL
)
3828 RegCloseKey(hKeyProfiles
);
3830 if (hKeyConfig
!= NULL
)
3831 RegCloseKey(hKeyConfig
);
3840 PNP_AddEmptyLogConf(
3844 DWORD
*pulLogConfTag
,
3848 return CR_CALL_NOT_IMPLEMENTED
;
3858 DWORD ulLogConfType
,
3863 return CR_CALL_NOT_IMPLEMENTED
;
3870 PNP_GetFirstLogConf(
3873 DWORD ulLogConfType
,
3874 DWORD
*pulLogConfTag
,
3877 HKEY hConfigKey
= NULL
;
3878 DWORD RegDataType
= 0;
3879 ULONG ulDataSize
= 0;
3880 LPBYTE lpData
= NULL
;
3881 CONFIGRET ret
= CR_SUCCESS
;
3883 DPRINT("PNP_GetFirstLogConf(%p %S %lu %p 0x%08lx)\n",
3884 hBinding
, pDeviceID
, ulLogConfType
, pulLogConfTag
, ulFlags
);
3886 if (pulLogConfTag
== NULL
)
3887 return CR_INVALID_POINTER
;
3889 *pulLogConfTag
= (DWORD
)0;
3891 if (ulFlags
& ~LOG_CONF_BITS
)
3892 return CR_INVALID_FLAG
;
3894 if (!IsValidDeviceInstanceID(pDeviceID
))
3895 return CR_INVALID_DEVINST
;
3897 ret
= OpenConfigurationKey(pDeviceID
,
3899 if (ret
!= CR_SUCCESS
)
3901 DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret
);
3902 ret
= CR_NO_MORE_LOG_CONF
;
3906 ret
= GetConfigurationData(hConfigKey
,
3911 if (ret
!= CR_SUCCESS
)
3913 DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret
);
3914 ret
= CR_NO_MORE_LOG_CONF
;
3918 DPRINT("Data size %lu\n", ulDataSize
);
3919 if (ulDataSize
== 0 || lpData
== NULL
)
3921 DPRINT1("No config data available!\n");
3922 ret
= CR_NO_MORE_LOG_CONF
;
3926 /* Get the first tag */
3927 if (RegDataType
== REG_RESOURCE_LIST
)
3929 DPRINT("REG_RESOURCE_LIST\n");
3931 DPRINT("ResourceList->Count %lu\n", ((PCM_RESOURCE_LIST
)lpData
)->Count
);
3932 if (((PCM_RESOURCE_LIST
)lpData
)->Count
== 0)
3934 DPRINT1("No resource descriptors!\n");
3935 ret
= CR_NO_MORE_LOG_CONF
;
3939 DPRINT("lpData %p\n", lpData
);
3940 DPRINT("&List[0] %p\n", &(((PCM_RESOURCE_LIST
)lpData
)->List
[0]));
3942 *pulLogConfTag
= (DWORD
)((DWORD_PTR
)&(((PCM_RESOURCE_LIST
)lpData
)->List
[0]) - (DWORD_PTR
)lpData
);
3943 DPRINT("Offset (Tag): 0x%08lx\n", *pulLogConfTag
);
3945 else if (RegDataType
== REG_RESOURCE_REQUIREMENTS_LIST
)
3947 DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
3949 ret
= CR_NO_MORE_LOG_CONF
;
3955 HeapFree(GetProcessHeap(), 0, lpData
);
3957 if (hConfigKey
!= NULL
)
3958 RegCloseKey(hConfigKey
);
3960 DPRINT("PNP_GetFirstLogConf() returns %lu\n", ret
);
3972 DWORD ulLogConfType
,
3977 HKEY hConfigKey
= NULL
;
3978 DWORD RegDataType
= 0;
3979 ULONG ulDataSize
= 0;
3980 LPBYTE lpData
= NULL
;
3981 CONFIGRET ret
= CR_SUCCESS
;
3983 DPRINT("PNP_GetNextLogConf(%p %S %lu %ul %p 0x%08lx)\n",
3984 hBinding
, pDeviceID
, ulLogConfType
, ulCurrentTag
, pulNextTag
, ulFlags
);
3986 if (pulNextTag
== NULL
)
3987 return CR_INVALID_POINTER
;
3989 *pulNextTag
= (DWORD
)0;
3992 return CR_INVALID_FLAG
;
3994 if (!IsValidDeviceInstanceID(pDeviceID
))
3995 return CR_INVALID_DEVINST
;
3997 ret
= OpenConfigurationKey(pDeviceID
,
3999 if (ret
!= CR_SUCCESS
)
4001 DPRINT1("OpenConfigurationKey() failed (Error %lu)\n", ret
);
4002 ret
= CR_NO_MORE_LOG_CONF
;
4006 ret
= GetConfigurationData(hConfigKey
,
4011 if (ret
!= CR_SUCCESS
)
4013 DPRINT1("GetConfigurationData() failed (Error %lu)\n", ret
);
4014 ret
= CR_NO_MORE_LOG_CONF
;
4018 DPRINT("Data size %lu\n", ulDataSize
);
4020 if (ulDataSize
== 0 || lpData
== NULL
)
4022 DPRINT1("No config data available!\n");
4023 ret
= CR_NO_MORE_LOG_CONF
;
4027 /* FIXME: Get the next tag */
4028 if (RegDataType
== REG_RESOURCE_LIST
)
4030 DPRINT1("FIXME: REG_RESOURCE_LIST\n");
4032 ret
= CR_NO_MORE_LOG_CONF
;
4035 else if (RegDataType
== REG_RESOURCE_REQUIREMENTS_LIST
)
4037 DPRINT1("FIXME: REG_RESOURCE_REQUIREMENTS_LIST\n");
4039 ret
= CR_NO_MORE_LOG_CONF
;
4045 HeapFree(GetProcessHeap(), 0, lpData
);
4047 if (hConfigKey
!= NULL
)
4048 RegCloseKey(hConfigKey
);
4050 DPRINT("PNP_GetNextLogConf() returns %lu\n", ret
);
4059 PNP_GetLogConfPriority(
4068 return CR_CALL_NOT_IMPLEMENTED
;
4079 DWORD ulLogConfType
,
4080 RESOURCEID ResourceID
,
4081 DWORD
*pulResourceTag
,
4083 PNP_RPC_BUFFER_SIZE ResourceLen
,
4087 return CR_CALL_NOT_IMPLEMENTED
;
4098 DWORD ulLogConfType
,
4099 RESOURCEID ResourceID
,
4100 DWORD ulResourceTag
,
4101 DWORD
*pulPreviousResType
,
4102 DWORD
*pulPreviousResTag
,
4106 return CR_CALL_NOT_IMPLEMENTED
;