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 pDeviceID
,
198 _Out_ DWORD
*pulStatus
,
199 _Out_ DWORD
*pulProblem
)
201 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
202 CONFIGRET ret
= CR_SUCCESS
;
205 DPRINT("GetDeviceStatus(%S %p %p)\n",
206 pDeviceID
, pulStatus
, pulProblem
);
208 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
210 PlugPlayData
.Operation
= 0; /* Get status */
212 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
213 (PVOID
)&PlugPlayData
,
214 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
215 if (NT_SUCCESS(Status
))
217 *pulStatus
= PlugPlayData
.DeviceStatus
;
218 *pulProblem
= PlugPlayData
.DeviceProblem
;
222 ret
= NtStatusToCrError(Status
);
231 IsValidDeviceInstanceID(
232 _In_ PWSTR pszDeviceInstanceID
)
234 INT nPartLength
[3] = {0, 0, 0};
235 INT nLength
= 0, nParts
= 0;
238 DPRINT("IsValidDeviceInstanceID(%S)\n",
239 pszDeviceInstanceID
);
241 if (pszDeviceInstanceID
== NULL
)
243 DPRINT("Device instance ID is NULL!\n");
247 p
= pszDeviceInstanceID
;
248 while (*p
!= UNICODE_NULL
)
255 DPRINT("Too many separators: %d\n", nParts
);
261 nPartLength
[nParts
]++;
265 if (nLength
>= MAX_DEVICE_ID_LEN
)
267 DPRINT("Too long: %d\n", nLength
);
276 DPRINT("Invalid number of separtors: %d\n", nParts
);
280 if ((nPartLength
[0] == 0) ||
281 (nPartLength
[1] == 0) ||
282 (nPartLength
[2] == 0))
284 DPRINT("Invalid part lengths: %d %d %d\n",
285 nPartLength
[0], nPartLength
[1], nPartLength
[2]);
289 DPRINT("Valid device instance ID!\n");
297 IsRootDeviceInstanceID(
298 _In_ PWSTR pszDeviceInstanceID
)
300 if (_wcsicmp(pszDeviceInstanceID
, szRootDeviceInstanceID
) == 0)
307 /* PUBLIC FUNCTIONS **********************************************************/
315 UNREFERENCED_PARAMETER(hBinding
);
326 UNREFERENCED_PARAMETER(hBinding
);
338 UNREFERENCED_PARAMETER(hBinding
);
353 UNREFERENCED_PARAMETER(hBinding
);
354 UNREFERENCED_PARAMETER(ulFlags
);
356 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
367 UNREFERENCED_PARAMETER(hBinding
);
369 DPRINT("PNP_InitDetection() called\n");
382 DWORD ReturnValue
= CR_FAILURE
;
385 UNREFERENCED_PARAMETER(hBinding
);
386 UNREFERENCED_PARAMETER(Admin
);
388 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
390 /* Get the users token */
391 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
395 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
401 CloseHandle(hUserToken
);
405 if (!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
407 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
411 /* Trigger the installer thread */
413 SetEvent(hInstallEvent
);
415 ReturnValue
= CR_SUCCESS
;
419 CloseHandle(hProcess
);
428 PNP_ValidateDeviceInstance(
433 CONFIGRET ret
= CR_SUCCESS
;
434 HKEY hDeviceKey
= NULL
;
436 UNREFERENCED_PARAMETER(hBinding
);
437 UNREFERENCED_PARAMETER(ulFlags
);
439 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
442 if (!IsValidDeviceInstanceID(pDeviceID
))
443 return CR_INVALID_DEVINST
;
445 if (RegOpenKeyExW(hEnumKey
,
451 DPRINT("Could not open the Device Key!\n");
452 ret
= CR_NO_SUCH_DEVNODE
;
456 /* FIXME: add more tests */
459 if (hDeviceKey
!= NULL
)
460 RegCloseKey(hDeviceKey
);
462 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
471 PNP_GetRootDeviceInstance(
474 PNP_RPC_STRING_LEN ulLength
)
476 CONFIGRET ret
= CR_SUCCESS
;
478 UNREFERENCED_PARAMETER(hBinding
);
480 DPRINT("PNP_GetRootDeviceInstance() called\n");
484 ret
= CR_INVALID_POINTER
;
487 if (ulLength
< lstrlenW(szRootDeviceInstanceID
) + 1)
489 ret
= CR_BUFFER_SMALL
;
494 szRootDeviceInstanceID
);
497 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
506 PNP_GetRelatedDeviceInstance(
508 DWORD ulRelationship
,
510 LPWSTR pRelatedDeviceId
,
511 PNP_RPC_STRING_LEN
*pulLength
,
514 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
515 CONFIGRET ret
= CR_SUCCESS
;
518 UNREFERENCED_PARAMETER(hBinding
);
519 UNREFERENCED_PARAMETER(ulFlags
);
521 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
522 DPRINT(" Relationship %ld\n", ulRelationship
);
523 DPRINT(" DeviceId %S\n", pDeviceID
);
525 if (!IsValidDeviceInstanceID(pDeviceID
))
526 return CR_INVALID_DEVINST
;
528 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
531 PlugPlayData
.Relation
= ulRelationship
;
533 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
534 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
536 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
537 (PVOID
)&PlugPlayData
,
538 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
539 if (!NT_SUCCESS(Status
))
541 ret
= NtStatusToCrError(Status
);
544 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
545 if (ret
== CR_SUCCESS
)
547 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
557 PNP_EnumerateSubKeys(
562 PNP_RPC_STRING_LEN ulLength
,
563 PNP_RPC_STRING_LEN
*pulRequiredLen
,
566 CONFIGRET ret
= CR_SUCCESS
;
570 UNREFERENCED_PARAMETER(hBinding
);
571 UNREFERENCED_PARAMETER(ulFlags
);
573 DPRINT("PNP_EnumerateSubKeys() called\n");
577 case PNP_ENUMERATOR_SUBKEYS
:
581 case PNP_CLASS_SUBKEYS
:
589 *pulRequiredLen
= ulLength
;
590 dwError
= RegEnumKeyExW(hKey
,
598 if (dwError
!= ERROR_SUCCESS
)
600 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
607 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
615 GetRelationsInstanceList(
616 _In_ PWSTR pszDevice
,
618 _Inout_ PWSTR pszBuffer
,
619 _Inout_ PDWORD pulLength
)
621 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
623 CONFIGRET ret
= CR_SUCCESS
;
625 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
628 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
630 PlugPlayData
.Relations
= 3;
632 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
634 PlugPlayData
.Relations
= 2;
636 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
638 PlugPlayData
.Relations
= 1;
640 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
642 PlugPlayData
.Relations
= 0;
645 PlugPlayData
.BufferSize
= *pulLength
* sizeof(WCHAR
);
646 PlugPlayData
.Buffer
= pszBuffer
;
648 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
649 (PVOID
)&PlugPlayData
,
650 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
651 if (NT_SUCCESS(Status
))
653 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
657 ret
= NtStatusToCrError(Status
);
666 GetServiceInstanceList(
667 _In_ PWSTR pszService
,
668 _Inout_ PWSTR pszBuffer
,
669 _Inout_ PDWORD pulLength
)
671 WCHAR szPathBuffer
[512];
673 HKEY hServicesKey
= NULL
, hServiceKey
= NULL
, hEnumKey
= NULL
;
674 DWORD dwValues
, dwSize
, dwIndex
, dwUsedLength
, dwPathLength
;
677 CONFIGRET ret
= CR_SUCCESS
;
679 /* Open the device key */
680 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
681 L
"System\\CurrentControlSet\\Services",
685 if (dwError
!= ERROR_SUCCESS
)
687 DPRINT("Failed to open the services key (Error %lu)\n", dwError
);
688 return CR_REGISTRY_ERROR
;
691 dwError
= RegOpenKeyExW(hServicesKey
,
696 if (dwError
!= ERROR_SUCCESS
)
698 DPRINT("Failed to open the service key (Error %lu)\n", dwError
);
699 ret
= CR_REGISTRY_ERROR
;
703 dwError
= RegOpenKeyExW(hServiceKey
,
708 if (dwError
!= ERROR_SUCCESS
)
710 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError
);
711 ret
= CR_REGISTRY_ERROR
;
715 /* Retrieve the number of device instances */
716 dwSize
= sizeof(DWORD
);
717 dwError
= RegQueryValueExW(hEnumKey
,
723 if (dwError
!= ERROR_SUCCESS
)
725 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError
);
729 DPRINT("dwValues %lu\n", dwValues
);
734 for (dwIndex
= 0; dwIndex
< dwValues
; dwIndex
++)
736 wsprintf(szName
, L
"%lu", dwIndex
);
738 dwSize
= sizeof(szPathBuffer
);
739 dwError
= RegQueryValueExW(hEnumKey
,
743 (LPBYTE
)szPathBuffer
,
745 if (dwError
!= ERROR_SUCCESS
)
748 DPRINT("Path: %S\n", szPathBuffer
);
750 dwPathLength
= wcslen(szPathBuffer
) + 1;
751 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
753 ret
= CR_BUFFER_SMALL
;
757 wcscpy(pPtr
, szPathBuffer
);
758 dwUsedLength
+= dwPathLength
;
759 pPtr
+= dwPathLength
;
761 *pPtr
= UNICODE_NULL
;
765 if (hEnumKey
!= NULL
)
766 RegCloseKey(hEnumKey
);
768 if (hServiceKey
!= NULL
)
769 RegCloseKey(hServiceKey
);
771 if (hServicesKey
!= NULL
)
772 RegCloseKey(hServicesKey
);
774 if (ret
== CR_SUCCESS
)
775 *pulLength
= dwUsedLength
+ 1;
785 GetDeviceInstanceList(
786 _In_ PWSTR pszDevice
,
787 _Inout_ PWSTR pszBuffer
,
788 _Inout_ PDWORD pulLength
)
790 WCHAR szInstanceBuffer
[MAX_DEVICE_ID_LEN
];
791 WCHAR szPathBuffer
[512];
793 DWORD dwInstanceLength
, dwPathLength
, dwUsedLength
;
794 DWORD dwIndex
, dwError
;
796 CONFIGRET ret
= CR_SUCCESS
;
798 /* Open the device key */
799 dwError
= RegOpenKeyExW(hEnumKey
,
802 KEY_ENUMERATE_SUB_KEYS
,
804 if (dwError
!= ERROR_SUCCESS
)
806 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
807 return CR_REGISTRY_ERROR
;
813 for (dwIndex
= 0; ; dwIndex
++)
815 dwInstanceLength
= MAX_DEVICE_ID_LEN
;
816 dwError
= RegEnumKeyExW(hDeviceKey
,
824 if (dwError
!= ERROR_SUCCESS
)
827 wsprintf(szPathBuffer
, L
"%s\\%s", pszDevice
, szInstanceBuffer
);
828 DPRINT("Path: %S\n", szPathBuffer
);
830 dwPathLength
= wcslen(szPathBuffer
) + 1;
831 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
833 ret
= CR_BUFFER_SMALL
;
837 wcscpy(pPtr
, szPathBuffer
);
838 dwUsedLength
+= dwPathLength
;
839 pPtr
+= dwPathLength
;
841 *pPtr
= UNICODE_NULL
;
844 RegCloseKey(hDeviceKey
);
846 if (ret
== CR_SUCCESS
)
847 *pulLength
= dwUsedLength
+ 1;
856 GetEnumeratorInstanceList(
857 _In_ PWSTR pszEnumerator
,
858 _Inout_ PWSTR pszBuffer
,
859 _Inout_ PDWORD pulLength
)
861 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
862 WCHAR szPathBuffer
[512];
865 DWORD dwIndex
, dwDeviceLength
, dwUsedLength
, dwRemainingLength
, dwPathLength
;
867 CONFIGRET ret
= CR_SUCCESS
;
869 /* Open the enumerator key */
870 dwError
= RegOpenKeyExW(hEnumKey
,
873 KEY_ENUMERATE_SUB_KEYS
,
875 if (dwError
!= ERROR_SUCCESS
)
877 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
878 return CR_REGISTRY_ERROR
;
882 dwRemainingLength
= *pulLength
;
885 for (dwIndex
= 0; ; dwIndex
++)
887 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
888 dwError
= RegEnumKeyExW(hEnumeratorKey
,
896 if (dwError
!= ERROR_SUCCESS
)
899 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
900 DPRINT("Path: %S\n", szPathBuffer
);
902 dwPathLength
= dwRemainingLength
;
903 ret
= GetDeviceInstanceList(szPathBuffer
,
906 if (ret
!= CR_SUCCESS
)
909 dwUsedLength
+= dwPathLength
- 1;
910 dwRemainingLength
+= dwPathLength
- 1;
911 pPtr
+= dwPathLength
- 1;
914 RegCloseKey(hEnumeratorKey
);
916 if (ret
== CR_SUCCESS
)
917 *pulLength
= dwUsedLength
+ 1;
928 _Inout_ PWSTR pszBuffer
,
929 _Inout_ PDWORD pulLength
)
931 WCHAR szEnumeratorBuffer
[MAX_DEVICE_ID_LEN
];
933 DWORD dwIndex
, dwEnumeratorLength
, dwUsedLength
, dwRemainingLength
, dwPathLength
;
935 CONFIGRET ret
= CR_SUCCESS
;
938 dwRemainingLength
= *pulLength
;
941 for (dwIndex
= 0; ; dwIndex
++)
943 dwEnumeratorLength
= MAX_DEVICE_ID_LEN
;
944 dwError
= RegEnumKeyExW(hEnumKey
,
948 NULL
, NULL
, NULL
, NULL
);
949 if (dwError
!= ERROR_SUCCESS
)
952 dwPathLength
= dwRemainingLength
;
953 ret
= GetEnumeratorInstanceList(szEnumeratorBuffer
,
956 if (ret
!= CR_SUCCESS
)
959 dwUsedLength
+= dwPathLength
- 1;
960 dwRemainingLength
+= dwPathLength
- 1;
961 pPtr
+= dwPathLength
- 1;
964 if (ret
== CR_SUCCESS
)
965 *pulLength
= dwUsedLength
+ 1;
980 PNP_RPC_STRING_LEN
*pulLength
,
983 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
984 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
985 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
986 CONFIGRET ret
= CR_SUCCESS
;
988 DPRINT("PNP_GetDeviceList() called\n");
990 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
991 return CR_INVALID_FLAG
;
993 if (pulLength
== NULL
)
994 return CR_INVALID_POINTER
;
996 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
998 return CR_INVALID_POINTER
;
1001 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
1002 CM_GETIDLIST_FILTER_POWERRELATIONS
|
1003 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
1004 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
1006 ret
= GetRelationsInstanceList(pszFilter
,
1011 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
1013 ret
= GetServiceInstanceList(pszFilter
,
1017 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
1019 SplitDeviceInstanceID(pszFilter
,
1024 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
1026 ret
= GetDeviceInstanceList(pszFilter
,
1032 ret
= GetEnumeratorInstanceList(pszFilter
,
1037 else /* CM_GETIDLIST_FILTER_NONE */
1039 ret
= GetAllInstanceList(Buffer
,
1049 GetRelationsInstanceListSize(
1050 _In_ PWSTR pszDevice
,
1052 _Inout_ PDWORD pulLength
)
1054 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
1056 CONFIGRET ret
= CR_SUCCESS
;
1058 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1061 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
1063 PlugPlayData
.Relations
= 3;
1065 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
1067 PlugPlayData
.Relations
= 2;
1069 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
1071 PlugPlayData
.Relations
= 1;
1073 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
1075 PlugPlayData
.Relations
= 0;
1078 PlugPlayData
.BufferSize
= 0;
1079 PlugPlayData
.Buffer
= NULL
;
1081 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
1082 (PVOID
)&PlugPlayData
,
1083 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
1084 if (NT_SUCCESS(Status
))
1086 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
1090 ret
= NtStatusToCrError(Status
);
1099 GetServiceInstanceListSize(
1100 _In_ PWSTR pszService
,
1101 _Out_ PDWORD pulLength
)
1103 HKEY hServicesKey
= NULL
, hServiceKey
= NULL
, hEnumKey
= NULL
;
1104 DWORD dwValues
, dwMaxValueLength
, dwSize
;
1106 CONFIGRET ret
= CR_SUCCESS
;
1108 /* Open the device key */
1109 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1110 L
"System\\CurrentControlSet\\Services",
1114 if (dwError
!= ERROR_SUCCESS
)
1116 DPRINT("Failed to open the services key (Error %lu)\n", dwError
);
1117 return CR_REGISTRY_ERROR
;
1120 dwError
= RegOpenKeyExW(hServicesKey
,
1125 if (dwError
!= ERROR_SUCCESS
)
1127 DPRINT("Failed to open the service key (Error %lu)\n", dwError
);
1128 ret
= CR_REGISTRY_ERROR
;
1132 dwError
= RegOpenKeyExW(hServiceKey
,
1137 if (dwError
!= ERROR_SUCCESS
)
1139 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError
);
1140 ret
= CR_REGISTRY_ERROR
;
1144 /* Retrieve the number of device instances */
1145 dwSize
= sizeof(DWORD
);
1146 dwError
= RegQueryValueExW(hEnumKey
,
1152 if (dwError
!= ERROR_SUCCESS
)
1154 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError
);
1158 /* Retrieve the maximum instance name length */
1159 dwError
= RegQueryInfoKeyW(hEnumKey
,
1171 if (dwError
!= ERROR_SUCCESS
)
1173 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
1174 dwMaxValueLength
= MAX_DEVICE_ID_LEN
;
1177 DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues
, dwMaxValueLength
/ sizeof(WCHAR
));
1179 /* Return the largest possible buffer size */
1180 *pulLength
= dwValues
* dwMaxValueLength
/ sizeof(WCHAR
) + 2;
1183 if (hEnumKey
!= NULL
)
1184 RegCloseKey(hEnumKey
);
1186 if (hServiceKey
!= NULL
)
1187 RegCloseKey(hServiceKey
);
1189 if (hServicesKey
!= NULL
)
1190 RegCloseKey(hServicesKey
);
1198 GetDeviceInstanceListSize(
1199 _In_ LPCWSTR pszDevice
,
1200 _Out_ PULONG pulLength
)
1203 DWORD dwSubKeys
, dwMaxSubKeyLength
;
1206 /* Open the device key */
1207 dwError
= RegOpenKeyExW(hEnumKey
,
1212 if (dwError
!= ERROR_SUCCESS
)
1214 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
1215 return CR_REGISTRY_ERROR
;
1218 /* Retrieve the number of device instances and the maximum name length */
1219 dwError
= RegQueryInfoKeyW(hDeviceKey
,
1231 if (dwError
!= ERROR_SUCCESS
)
1233 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
1235 dwMaxSubKeyLength
= 0;
1238 /* Close the device key */
1239 RegCloseKey(hDeviceKey
);
1241 /* Return the largest possible buffer size */
1242 *pulLength
= dwSubKeys
* (wcslen(pszDevice
) + 1 + dwMaxSubKeyLength
+ 1);
1250 GetEnumeratorInstanceListSize(
1251 _In_ LPCWSTR pszEnumerator
,
1252 _Out_ PULONG pulLength
)
1254 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
1255 WCHAR szPathBuffer
[512];
1256 HKEY hEnumeratorKey
;
1257 DWORD dwIndex
, dwDeviceLength
, dwBufferLength
;
1259 CONFIGRET ret
= CR_SUCCESS
;
1263 /* Open the enumerator key */
1264 dwError
= RegOpenKeyExW(hEnumKey
,
1267 KEY_ENUMERATE_SUB_KEYS
,
1269 if (dwError
!= ERROR_SUCCESS
)
1271 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
1272 return CR_REGISTRY_ERROR
;
1275 for (dwIndex
= 0; ; dwIndex
++)
1277 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
1278 dwError
= RegEnumKeyExW(hEnumeratorKey
,
1286 if (dwError
!= ERROR_SUCCESS
)
1289 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
1290 DPRINT("Path: %S\n", szPathBuffer
);
1292 ret
= GetDeviceInstanceListSize(szPathBuffer
, &dwBufferLength
);
1293 if (ret
!= CR_SUCCESS
)
1299 *pulLength
+= dwBufferLength
;
1302 /* Close the enumerator key */
1303 RegCloseKey(hEnumeratorKey
);
1311 GetAllInstanceListSize(
1312 _Out_ PULONG pulLength
)
1314 WCHAR szEnumeratorBuffer
[MAX_DEVICE_ID_LEN
];
1315 DWORD dwIndex
, dwEnumeratorLength
, dwBufferLength
;
1317 CONFIGRET ret
= CR_SUCCESS
;
1319 for (dwIndex
= 0; ; dwIndex
++)
1321 dwEnumeratorLength
= MAX_DEVICE_ID_LEN
;
1322 dwError
= RegEnumKeyExW(hEnumKey
,
1325 &dwEnumeratorLength
,
1326 NULL
, NULL
, NULL
, NULL
);
1327 if (dwError
!= ERROR_SUCCESS
)
1330 /* Get the size of all device instances for the enumerator */
1331 ret
= GetEnumeratorInstanceListSize(szEnumeratorBuffer
,
1333 if (ret
!= CR_SUCCESS
)
1336 *pulLength
+= dwBufferLength
;
1346 PNP_GetDeviceListSize(
1349 PNP_RPC_BUFFER_SIZE
*pulLength
,
1352 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1353 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1354 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1355 CONFIGRET ret
= CR_SUCCESS
;
1357 DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%lx)\n",
1358 hBinding
, pszFilter
, pulLength
, ulFlags
);
1360 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
1361 return CR_INVALID_FLAG
;
1363 if (pulLength
== NULL
)
1364 return CR_INVALID_POINTER
;
1366 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
1367 (pszFilter
== NULL
))
1368 return CR_INVALID_POINTER
;
1373 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
1374 CM_GETIDLIST_FILTER_POWERRELATIONS
|
1375 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
1376 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
1378 ret
= GetRelationsInstanceListSize(pszFilter
,
1382 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
1384 ret
= GetServiceInstanceListSize(pszFilter
,
1387 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
1389 SplitDeviceInstanceID(pszFilter
,
1394 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
1396 ret
= GetDeviceInstanceListSize(pszFilter
,
1401 ret
= GetEnumeratorInstanceListSize(pszFilter
,
1405 else /* CM_GETIDLIST_FILTER_NONE */
1407 ret
= GetAllInstanceListSize(pulLength
);
1410 /* Add one character for the terminating double UNICODE_NULL */
1411 if (ret
== CR_SUCCESS
)
1427 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
1428 CONFIGRET ret
= CR_SUCCESS
;
1431 UNREFERENCED_PARAMETER(hBinding
);
1432 UNREFERENCED_PARAMETER(ulFlags
);
1434 DPRINT("PNP_GetDepth() called\n");
1436 if (!IsValidDeviceInstanceID(pszDeviceID
))
1437 return CR_INVALID_DEVINST
;
1439 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1442 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
1443 (PVOID
)&PlugPlayData
,
1444 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
1445 if (NT_SUCCESS(Status
))
1447 *pulDepth
= PlugPlayData
.Depth
;
1451 ret
= NtStatusToCrError(Status
);
1454 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
1463 PNP_GetDeviceRegProp(
1467 DWORD
*pulRegDataType
,
1469 PNP_PROP_SIZE
*pulTransferLen
,
1470 PNP_PROP_SIZE
*pulLength
,
1473 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
1474 CONFIGRET ret
= CR_SUCCESS
;
1475 LPWSTR lpValueName
= NULL
;
1480 UNREFERENCED_PARAMETER(hBinding
);
1482 DPRINT("PNP_GetDeviceRegProp() called\n");
1484 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1486 ret
= CR_INVALID_POINTER
;
1492 ret
= CR_INVALID_FLAG
;
1496 /* Check pDeviceID */
1497 if (!IsValidDeviceInstanceID(pDeviceID
))
1499 ret
= CR_INVALID_DEVINST
;
1503 if (*pulLength
< *pulTransferLen
)
1504 *pulLength
= *pulTransferLen
;
1506 *pulTransferLen
= 0;
1510 case CM_DRP_DEVICEDESC
:
1511 lpValueName
= L
"DeviceDesc";
1514 case CM_DRP_HARDWAREID
:
1515 lpValueName
= L
"HardwareID";
1518 case CM_DRP_COMPATIBLEIDS
:
1519 lpValueName
= L
"CompatibleIDs";
1522 case CM_DRP_SERVICE
:
1523 lpValueName
= L
"Service";
1527 lpValueName
= L
"Class";
1530 case CM_DRP_CLASSGUID
:
1531 lpValueName
= L
"ClassGUID";
1535 lpValueName
= L
"Driver";
1538 case CM_DRP_CONFIGFLAGS
:
1539 lpValueName
= L
"ConfigFlags";
1543 lpValueName
= L
"Mfg";
1546 case CM_DRP_FRIENDLYNAME
:
1547 lpValueName
= L
"FriendlyName";
1550 case CM_DRP_LOCATION_INFORMATION
:
1551 lpValueName
= L
"LocationInformation";
1554 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
1555 PlugPlayData
.Property
= PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME
;
1558 case CM_DRP_CAPABILITIES
:
1559 lpValueName
= L
"Capabilities";
1562 case CM_DRP_UI_NUMBER
:
1563 PlugPlayData
.Property
= PNP_PROPERTY_UI_NUMBER
;
1566 case CM_DRP_UPPERFILTERS
:
1567 lpValueName
= L
"UpperFilters";
1570 case CM_DRP_LOWERFILTERS
:
1571 lpValueName
= L
"LowerFilters";
1574 case CM_DRP_BUSTYPEGUID
:
1575 PlugPlayData
.Property
= PNP_PROPERTY_BUSTYPEGUID
;
1578 case CM_DRP_LEGACYBUSTYPE
:
1579 PlugPlayData
.Property
= PNP_PROPERTY_LEGACYBUSTYPE
;
1582 case CM_DRP_BUSNUMBER
:
1583 PlugPlayData
.Property
= PNP_PROPERTY_BUSNUMBER
;
1586 case CM_DRP_ENUMERATOR_NAME
:
1587 PlugPlayData
.Property
= PNP_PROPERTY_ENUMERATOR_NAME
;
1590 case CM_DRP_SECURITY
:
1591 lpValueName
= L
"Security";
1594 case CM_DRP_DEVTYPE
:
1595 lpValueName
= L
"DeviceType";
1598 case CM_DRP_EXCLUSIVE
:
1599 lpValueName
= L
"Exclusive";
1602 case CM_DRP_CHARACTERISTICS
:
1603 lpValueName
= L
"DeviceCharacteristics";
1606 case CM_DRP_ADDRESS
:
1607 PlugPlayData
.Property
= PNP_PROPERTY_ADDRESS
;
1610 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1611 lpValueName
= L
"UINumberDescFormat";
1614 case CM_DRP_DEVICE_POWER_DATA
:
1615 PlugPlayData
.Property
= PNP_PROPERTY_POWER_DATA
;
1618 case CM_DRP_REMOVAL_POLICY
:
1619 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY
;
1622 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
1623 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
;
1626 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1627 lpValueName
= L
"RemovalPolicy";
1630 case CM_DRP_INSTALL_STATE
:
1631 PlugPlayData
.Property
= PNP_PROPERTY_INSTALL_STATE
;
1634 #if (WINVER >= _WIN32_WINNT_WS03)
1635 case CM_DRP_LOCATION_PATHS
:
1636 PlugPlayData
.Property
= PNP_PROPERTY_LOCATION_PATHS
;
1640 #if (WINVER >= _WIN32_WINNT_WIN7)
1641 case CM_DRP_BASE_CONTAINERID
:
1642 PlugPlayData
.Property
= PNP_PROPERTY_CONTAINERID
;
1647 ret
= CR_INVALID_PROPERTY
;
1651 DPRINT("Value name: %S\n", lpValueName
);
1655 /* Retrieve information from the Registry */
1656 lError
= RegOpenKeyExW(hEnumKey
,
1661 if (lError
!= ERROR_SUCCESS
)
1665 ret
= CR_INVALID_DEVNODE
;
1669 lError
= RegQueryValueExW(hKey
,
1675 if (lError
!= ERROR_SUCCESS
)
1677 if (lError
== ERROR_MORE_DATA
)
1679 ret
= CR_BUFFER_SMALL
;
1684 ret
= CR_NO_SUCH_VALUE
;
1690 /* Retrieve information from the Device Node */
1691 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1693 PlugPlayData
.Buffer
= Buffer
;
1694 PlugPlayData
.BufferSize
= *pulLength
;
1696 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
1697 (PVOID
)&PlugPlayData
,
1698 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
1699 if (NT_SUCCESS(Status
))
1701 *pulLength
= PlugPlayData
.BufferSize
;
1705 ret
= NtStatusToCrError(Status
);
1711 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1716 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1725 PNP_SetDeviceRegProp(
1731 PNP_PROP_SIZE ulLength
,
1734 CONFIGRET ret
= CR_SUCCESS
;
1735 LPWSTR lpValueName
= NULL
;
1738 UNREFERENCED_PARAMETER(hBinding
);
1739 UNREFERENCED_PARAMETER(ulFlags
);
1741 DPRINT("PNP_SetDeviceRegProp() called\n");
1743 DPRINT("DeviceId: %S\n", pDeviceId
);
1744 DPRINT("Property: %lu\n", ulProperty
);
1745 DPRINT("DataType: %lu\n", ulDataType
);
1746 DPRINT("Length: %lu\n", ulLength
);
1748 if (!IsValidDeviceInstanceID(pDeviceId
))
1749 return CR_INVALID_DEVINST
;
1753 case CM_DRP_DEVICEDESC
:
1754 lpValueName
= L
"DeviceDesc";
1757 case CM_DRP_HARDWAREID
:
1758 lpValueName
= L
"HardwareID";
1761 case CM_DRP_COMPATIBLEIDS
:
1762 lpValueName
= L
"CompatibleIDs";
1765 case CM_DRP_SERVICE
:
1766 lpValueName
= L
"Service";
1770 lpValueName
= L
"Class";
1773 case CM_DRP_CLASSGUID
:
1774 lpValueName
= L
"ClassGUID";
1778 lpValueName
= L
"Driver";
1781 case CM_DRP_CONFIGFLAGS
:
1782 lpValueName
= L
"ConfigFlags";
1786 lpValueName
= L
"Mfg";
1789 case CM_DRP_FRIENDLYNAME
:
1790 lpValueName
= L
"FriendlyName";
1793 case CM_DRP_LOCATION_INFORMATION
:
1794 lpValueName
= L
"LocationInformation";
1797 case CM_DRP_UPPERFILTERS
:
1798 lpValueName
= L
"UpperFilters";
1801 case CM_DRP_LOWERFILTERS
:
1802 lpValueName
= L
"LowerFilters";
1805 case CM_DRP_SECURITY
:
1806 lpValueName
= L
"Security";
1809 case CM_DRP_DEVTYPE
:
1810 lpValueName
= L
"DeviceType";
1813 case CM_DRP_EXCLUSIVE
:
1814 lpValueName
= L
"Exclusive";
1817 case CM_DRP_CHARACTERISTICS
:
1818 lpValueName
= L
"DeviceCharacteristics";
1821 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1822 lpValueName
= L
"UINumberDescFormat";
1825 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1826 lpValueName
= L
"RemovalPolicy";
1830 return CR_INVALID_PROPERTY
;
1833 DPRINT("Value name: %S\n", lpValueName
);
1835 if (RegOpenKeyExW(hEnumKey
,
1840 return CR_INVALID_DEVNODE
;
1844 if (RegDeleteValueW(hKey
,
1846 ret
= CR_REGISTRY_ERROR
;
1850 if (RegSetValueExW(hKey
,
1856 ret
= CR_REGISTRY_ERROR
;
1861 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1870 PNP_GetClassInstance(
1873 LPWSTR pszClassInstance
,
1874 PNP_RPC_STRING_LEN ulLength
)
1876 WCHAR szClassGuid
[40];
1877 WCHAR szClassInstance
[5];
1878 HKEY hDeviceClassKey
= NULL
;
1879 HKEY hClassInstanceKey
;
1880 ULONG ulTransferLength
, ulDataLength
;
1881 DWORD dwDataType
, dwDisposition
, i
;
1883 CONFIGRET ret
= CR_SUCCESS
;
1885 DPRINT("PNP_GetClassInstance(%p %S %p %lu)\n",
1886 hBinding
, pDeviceId
, pszClassInstance
, ulLength
);
1888 if (!IsValidDeviceInstanceID(pDeviceId
))
1889 return CR_INVALID_DEVINST
;
1891 ulTransferLength
= ulLength
;
1892 ret
= PNP_GetDeviceRegProp(hBinding
,
1896 (BYTE
*)pszClassInstance
,
1900 if (ret
== CR_SUCCESS
)
1903 ulTransferLength
= sizeof(szClassGuid
);
1904 ulDataLength
= sizeof(szClassGuid
);
1905 ret
= PNP_GetDeviceRegProp(hBinding
,
1909 (BYTE
*)szClassGuid
,
1913 if (ret
!= CR_SUCCESS
)
1915 DPRINT1("PNP_GetDeviceRegProp() failed (Error %lu)\n", ret
);
1919 dwError
= RegOpenKeyExW(hClassKey
,
1924 if (dwError
!= ERROR_SUCCESS
)
1926 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError
);
1931 for (i
= 0; i
< 10000; i
++)
1933 wsprintf(szClassInstance
, L
"%04lu", i
);
1935 dwError
= RegCreateKeyExW(hDeviceClassKey
,
1939 REG_OPTION_NON_VOLATILE
,
1944 if (dwError
== ERROR_SUCCESS
)
1946 RegCloseKey(hClassInstanceKey
);
1948 if (dwDisposition
== REG_CREATED_NEW_KEY
)
1950 wsprintf(pszClassInstance
,
1955 ulDataLength
= (wcslen(pszClassInstance
) + 1) * sizeof(WCHAR
);
1956 ret
= PNP_SetDeviceRegProp(hBinding
,
1960 (BYTE
*)pszClassInstance
,
1963 if (ret
!= CR_SUCCESS
)
1965 DPRINT1("PNP_SetDeviceRegProp() failed (Error %lu)\n", ret
);
1966 RegDeleteKeyW(hDeviceClassKey
,
1976 if (hDeviceClassKey
!= NULL
)
1977 RegCloseKey(hDeviceClassKey
);
1994 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2003 return CR_REGISTRY_ERROR
;
2005 /* FIXME: Set security key */
2016 PNP_DeleteRegistryKey(
2019 LPWSTR pszParentKey
,
2024 return CR_CALL_NOT_IMPLEMENTED
;
2033 DWORD
*pulClassCount
,
2039 UNREFERENCED_PARAMETER(hBinding
);
2040 UNREFERENCED_PARAMETER(ulFlags
);
2042 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2047 if (dwError
!= ERROR_SUCCESS
)
2048 return CR_INVALID_DATA
;
2050 dwError
= RegQueryInfoKeyW(hKey
,
2063 if (dwError
!= ERROR_SUCCESS
)
2064 return CR_INVALID_DATA
;
2075 LPWSTR pszClassGuid
,
2077 PNP_RPC_STRING_LEN
*pulLength
,
2080 WCHAR szKeyName
[MAX_PATH
];
2081 CONFIGRET ret
= CR_SUCCESS
;
2085 UNREFERENCED_PARAMETER(hBinding
);
2086 UNREFERENCED_PARAMETER(ulFlags
);
2088 DPRINT("PNP_GetClassName() called\n");
2090 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
2091 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
2092 lstrcatW(szKeyName
, pszClassGuid
);
2094 return CR_INVALID_DATA
;
2096 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2101 return CR_REGISTRY_ERROR
;
2103 dwSize
= *pulLength
* sizeof(WCHAR
);
2104 if (RegQueryValueExW(hKey
,
2112 ret
= CR_REGISTRY_ERROR
;
2116 *pulLength
= dwSize
/ sizeof(WCHAR
);
2121 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
2132 LPWSTR pszClassGuid
,
2135 CONFIGRET ret
= CR_SUCCESS
;
2137 UNREFERENCED_PARAMETER(hBinding
);
2139 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
2141 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
2143 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
2144 ret
= CR_REGISTRY_ERROR
;
2148 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
2149 ret
= CR_REGISTRY_ERROR
;
2152 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
2161 PNP_GetInterfaceDeviceAlias(
2163 LPWSTR pszInterfaceDevice
,
2164 GUID
*AliasInterfaceGuid
,
2165 LPWSTR pszAliasInterfaceDevice
,
2166 PNP_RPC_STRING_LEN
*pulLength
,
2167 PNP_RPC_STRING_LEN
*pulTransferLen
,
2171 return CR_CALL_NOT_IMPLEMENTED
;
2178 PNP_GetInterfaceDeviceList(
2180 GUID
*InterfaceGuid
,
2183 PNP_RPC_BUFFER_SIZE
*pulLength
,
2187 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
2188 DWORD ret
= CR_SUCCESS
;
2190 UNREFERENCED_PARAMETER(hBinding
);
2192 if (!IsValidDeviceInstanceID(pszDeviceID
))
2193 return CR_INVALID_DEVINST
;
2195 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2198 PlugPlayData
.Flags
= ulFlags
;
2199 PlugPlayData
.FilterGuid
= InterfaceGuid
;
2200 PlugPlayData
.Buffer
= Buffer
;
2201 PlugPlayData
.BufferSize
= *pulLength
;
2203 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
2204 (PVOID
)&PlugPlayData
,
2205 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
2206 if (NT_SUCCESS(Status
))
2208 *pulLength
= PlugPlayData
.BufferSize
;
2212 ret
= NtStatusToCrError(Status
);
2215 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
2223 PNP_GetInterfaceDeviceListSize(
2225 PNP_RPC_BUFFER_SIZE
*pulLen
,
2226 GUID
*InterfaceGuid
,
2231 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
2232 DWORD ret
= CR_SUCCESS
;
2234 UNREFERENCED_PARAMETER(hBinding
);
2236 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
2238 if (!IsValidDeviceInstanceID(pszDeviceID
))
2239 return CR_INVALID_DEVINST
;
2241 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2244 PlugPlayData
.FilterGuid
= InterfaceGuid
;
2245 PlugPlayData
.Buffer
= NULL
;
2246 PlugPlayData
.BufferSize
= 0;
2247 PlugPlayData
.Flags
= ulFlags
;
2249 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
2250 (PVOID
)&PlugPlayData
,
2251 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
2252 if (NT_SUCCESS(Status
))
2254 *pulLen
= PlugPlayData
.BufferSize
;
2258 ret
= NtStatusToCrError(Status
);
2261 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
2269 PNP_RegisterDeviceClassAssociation(
2272 GUID
*InterfaceGuid
,
2273 LPWSTR pszReference
,
2275 PNP_RPC_STRING_LEN
*pulLength
,
2276 PNP_RPC_STRING_LEN
*pulTransferLen
,
2280 return CR_CALL_NOT_IMPLEMENTED
;
2287 PNP_UnregisterDeviceClassAssociation(
2289 LPWSTR pszInterfaceDevice
,
2293 return CR_CALL_NOT_IMPLEMENTED
;
2300 PNP_GetClassRegProp(
2302 LPWSTR pszClassGuid
,
2304 DWORD
*pulRegDataType
,
2306 PNP_RPC_STRING_LEN
*pulTransferLen
,
2307 PNP_RPC_STRING_LEN
*pulLength
,
2310 CONFIGRET ret
= CR_SUCCESS
;
2311 LPWSTR lpValueName
= NULL
;
2312 HKEY hInstKey
= NULL
;
2313 HKEY hPropKey
= NULL
;
2316 UNREFERENCED_PARAMETER(hBinding
);
2318 DPRINT("PNP_GetClassRegProp() called\n");
2320 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2322 ret
= CR_INVALID_POINTER
;
2328 ret
= CR_INVALID_FLAG
;
2332 if (*pulLength
< *pulTransferLen
)
2333 *pulLength
= *pulTransferLen
;
2335 *pulTransferLen
= 0;
2339 case CM_CRP_SECURITY
:
2340 lpValueName
= L
"Security";
2343 case CM_CRP_DEVTYPE
:
2344 lpValueName
= L
"DeviceType";
2347 case CM_CRP_EXCLUSIVE
:
2348 lpValueName
= L
"Exclusive";
2351 case CM_CRP_CHARACTERISTICS
:
2352 lpValueName
= L
"DeviceCharacteristics";
2356 ret
= CR_INVALID_PROPERTY
;
2360 DPRINT("Value name: %S\n", lpValueName
);
2362 lError
= RegOpenKeyExW(hClassKey
,
2367 if (lError
!= ERROR_SUCCESS
)
2370 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2374 lError
= RegOpenKeyExW(hInstKey
,
2379 if (lError
!= ERROR_SUCCESS
)
2382 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2386 lError
= RegQueryValueExW(hPropKey
,
2392 if (lError
!= ERROR_SUCCESS
)
2394 if (lError
== ERROR_MORE_DATA
)
2396 ret
= CR_BUFFER_SMALL
;
2401 ret
= CR_NO_SUCH_VALUE
;
2406 if (ret
== CR_SUCCESS
)
2407 *pulTransferLen
= *pulLength
;
2409 if (hPropKey
!= NULL
)
2410 RegCloseKey(hPropKey
);
2412 if (hInstKey
!= NULL
)
2413 RegCloseKey(hInstKey
);
2415 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
2424 PNP_SetClassRegProp(
2426 LPWSTR pszClassGuid
,
2430 PNP_PROP_SIZE ulLength
,
2433 CONFIGRET ret
= CR_SUCCESS
;
2434 LPWSTR lpValueName
= NULL
;
2439 UNREFERENCED_PARAMETER(hBinding
);
2441 DPRINT("PNP_SetClassRegProp() called\n");
2444 return CR_INVALID_FLAG
;
2448 case CM_CRP_SECURITY
:
2449 lpValueName
= L
"Security";
2452 case CM_CRP_DEVTYPE
:
2453 lpValueName
= L
"DeviceType";
2456 case CM_CRP_EXCLUSIVE
:
2457 lpValueName
= L
"Exclusive";
2460 case CM_CRP_CHARACTERISTICS
:
2461 lpValueName
= L
"DeviceCharacteristics";
2465 return CR_INVALID_PROPERTY
;
2468 lError
= RegOpenKeyExW(hClassKey
,
2473 if (lError
!= ERROR_SUCCESS
)
2475 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2479 /* FIXME: Set security descriptor */
2480 lError
= RegCreateKeyExW(hInstKey
,
2484 REG_OPTION_NON_VOLATILE
,
2489 if (lError
!= ERROR_SUCCESS
)
2491 ret
= CR_REGISTRY_ERROR
;
2497 if (RegDeleteValueW(hPropKey
,
2499 ret
= CR_REGISTRY_ERROR
;
2503 if (RegSetValueExW(hPropKey
,
2509 ret
= CR_REGISTRY_ERROR
;
2513 if (hPropKey
!= NULL
)
2514 RegCloseKey(hPropKey
);
2516 if (hInstKey
!= NULL
)
2517 RegCloseKey(hInstKey
);
2524 CreateDeviceInstance(LPWSTR pszDeviceID
)
2526 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
2527 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
2528 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
2529 HKEY hKeyEnumerator
;
2535 /* Split the instance ID */
2536 SplitDeviceInstanceID(pszDeviceID
,
2541 /* Open or create the enumerator key */
2542 lError
= RegCreateKeyExW(hEnumKey
,
2546 REG_OPTION_NON_VOLATILE
,
2551 if (lError
!= ERROR_SUCCESS
)
2553 return CR_REGISTRY_ERROR
;
2556 /* Open or create the device key */
2557 lError
= RegCreateKeyExW(hKeyEnumerator
,
2561 REG_OPTION_NON_VOLATILE
,
2567 /* Close the enumerator key */
2568 RegCloseKey(hKeyEnumerator
);
2570 if (lError
!= ERROR_SUCCESS
)
2572 return CR_REGISTRY_ERROR
;
2575 /* Try to open the instance key and fail if it exists */
2576 lError
= RegOpenKeyExW(hKeyDevice
,
2581 if (lError
== ERROR_SUCCESS
)
2583 DPRINT1("Instance %S already exists!\n", szInstance
);
2584 RegCloseKey(hKeyInstance
);
2585 RegCloseKey(hKeyDevice
);
2586 return CR_ALREADY_SUCH_DEVINST
;
2589 /* Create a new instance key */
2590 lError
= RegCreateKeyExW(hKeyDevice
,
2594 REG_OPTION_NON_VOLATILE
,
2600 /* Close the device key */
2601 RegCloseKey(hKeyDevice
);
2603 if (lError
!= ERROR_SUCCESS
)
2605 return CR_REGISTRY_ERROR
;
2608 /* Create the 'Control' sub key */
2609 lError
= RegCreateKeyExW(hKeyInstance
,
2613 REG_OPTION_NON_VOLATILE
,
2618 if (lError
== ERROR_SUCCESS
)
2620 RegCloseKey(hKeyControl
);
2623 RegCloseKey(hKeyInstance
);
2625 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
2635 LPWSTR pszParentDeviceID
,
2636 PNP_RPC_STRING_LEN ulLength
,
2639 CONFIGRET ret
= CR_SUCCESS
;
2641 DPRINT("PNP_CreateDevInst(%p %S %S %lu 0x%08lx)\n",
2642 hBinding
, pszParentDeviceID
, pszDeviceID
, ulLength
, ulFlags
);
2644 if (ulFlags
& ~CM_CREATE_DEVNODE_BITS
)
2645 return CR_INVALID_FLAG
;
2647 if (pszDeviceID
== NULL
|| pszParentDeviceID
== NULL
)
2648 return CR_INVALID_POINTER
;
2650 /* Fail, if the parent device is not the root device */
2651 if (!IsRootDeviceInstanceID(pszParentDeviceID
))
2652 return CR_INVALID_DEVINST
;
2654 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
2656 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
2657 DWORD dwInstanceNumber
;
2659 /* Generated ID is: Root\<Device ID>\<Instance number> */
2660 dwInstanceNumber
= 0;
2663 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
2664 pszDeviceID
, dwInstanceNumber
);
2666 /* Try to create a device instance with this ID */
2667 ret
= CreateDeviceInstance(szGeneratedInstance
);
2671 while (ret
== CR_ALREADY_SUCH_DEVINST
);
2673 if (ret
== CR_SUCCESS
)
2675 /* pszDeviceID is an out parameter too for generated IDs */
2676 if (wcslen(szGeneratedInstance
) > ulLength
)
2678 ret
= CR_BUFFER_SMALL
;
2682 wcscpy(pszDeviceID
, szGeneratedInstance
);
2688 /* Create the device instance */
2689 ret
= CreateDeviceInstance(pszDeviceID
);
2692 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
2699 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
2700 LPWSTR pszDeviceInstanceSource
)
2702 DPRINT("MoveDeviceInstance: not implemented\n");
2704 return CR_CALL_NOT_IMPLEMENTED
;
2709 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
2712 DPRINT("SetupDeviceInstance: not implemented\n");
2714 return CR_CALL_NOT_IMPLEMENTED
;
2719 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
2721 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
2722 CONFIGRET ret
= CR_SUCCESS
;
2725 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
2727 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
2728 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
2729 if (!NT_SUCCESS(Status
))
2730 ret
= NtStatusToCrError(Status
);
2737 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
2739 DPRINT("DisableDeviceInstance: not implemented\n");
2741 return CR_CALL_NOT_IMPLEMENTED
;
2746 ReenumerateDeviceInstance(
2747 _In_ LPWSTR pszDeviceInstance
,
2750 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData
;
2751 CONFIGRET ret
= CR_SUCCESS
;
2754 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
2755 pszDeviceInstance
, ulFlags
);
2757 if (ulFlags
& ~CM_REENUMERATE_BITS
)
2758 return CR_INVALID_FLAG
;
2760 if (ulFlags
& CM_REENUMERATE_RETRY_INSTALLATION
)
2762 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
2765 RtlInitUnicodeString(&EnumerateDeviceData
.DeviceInstance
,
2767 EnumerateDeviceData
.Flags
= 0;
2769 Status
= NtPlugPlayControl(PlugPlayControlEnumerateDevice
,
2770 &EnumerateDeviceData
,
2771 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA
));
2772 if (!NT_SUCCESS(Status
))
2773 ret
= NtStatusToCrError(Status
);
2782 PNP_DeviceInstanceAction(
2786 LPWSTR pszDeviceInstance1
,
2787 LPWSTR pszDeviceInstance2
)
2789 CONFIGRET ret
= CR_SUCCESS
;
2791 UNREFERENCED_PARAMETER(hBinding
);
2793 DPRINT("PNP_DeviceInstanceAction() called\n");
2797 case PNP_DEVINST_MOVE
:
2798 ret
= MoveDeviceInstance(pszDeviceInstance1
,
2799 pszDeviceInstance2
);
2802 case PNP_DEVINST_SETUP
:
2803 ret
= SetupDeviceInstance(pszDeviceInstance1
,
2807 case PNP_DEVINST_ENABLE
:
2808 ret
= EnableDeviceInstance(pszDeviceInstance1
);
2811 case PNP_DEVINST_DISABLE
:
2812 ret
= DisableDeviceInstance(pszDeviceInstance1
);
2815 case PNP_DEVINST_REENUMERATE
:
2816 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
,
2821 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2822 ret
= CR_CALL_NOT_IMPLEMENTED
;
2825 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2834 PNP_GetDeviceStatus(
2841 UNREFERENCED_PARAMETER(hBinding
);
2842 UNREFERENCED_PARAMETER(ulFlags
);
2844 DPRINT("PNP_GetDeviceStatus(%p %S %p %p)\n",
2845 hBinding
, pDeviceID
, pulStatus
, pulProblem
, ulFlags
);
2847 if (!IsValidDeviceInstanceID(pDeviceID
))
2848 return CR_INVALID_DEVINST
;
2850 return GetDeviceStatus(pDeviceID
, pulStatus
, pulProblem
);
2857 PNP_SetDeviceProblem(
2864 return CR_CALL_NOT_IMPLEMENTED
;
2874 PPNP_VETO_TYPE pVetoType
,
2880 return CR_CALL_NOT_IMPLEMENTED
;
2886 PNP_UninstallDevInst(
2892 return CR_CALL_NOT_IMPLEMENTED
;
2897 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2903 lpPtr
= lpDeviceIdList
;
2906 dwLength
= wcslen(lpPtr
);
2907 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2910 lpPtr
+= (dwLength
+ 1);
2918 AppendDeviceId(LPWSTR lpDeviceIdList
,
2919 LPDWORD lpDeviceIdListSize
,
2925 dwLen
= wcslen(lpDeviceId
);
2926 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2928 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2930 dwPos
+= (dwLen
+ 1);
2932 lpDeviceIdList
[dwPos
] = 0;
2934 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2947 CONFIGRET ret
= CR_SUCCESS
;
2950 DWORD dwDeviceIdListSize
;
2951 DWORD dwNewDeviceIdSize
;
2952 WCHAR
* pszDeviceIdList
= NULL
;
2954 UNREFERENCED_PARAMETER(hBinding
);
2956 DPRINT("PNP_AddID() called\n");
2957 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2958 DPRINT(" DeviceId: %S\n", pszID
);
2959 DPRINT(" Flags: %lx\n", ulFlags
);
2961 if (RegOpenKeyExW(hEnumKey
,
2964 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2965 &hDeviceKey
) != ERROR_SUCCESS
)
2967 DPRINT("Failed to open the device key!\n");
2968 return CR_INVALID_DEVNODE
;
2971 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2973 if (RegQueryValueExW(hDeviceKey
,
2978 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2980 DPRINT("Failed to query the desired ID string!\n");
2981 ret
= CR_REGISTRY_ERROR
;
2985 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2986 if (!dwNewDeviceIdSize
)
2988 ret
= CR_INVALID_POINTER
;
2992 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2994 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2995 if (!pszDeviceIdList
)
2997 DPRINT("Failed to allocate memory for the desired ID string!\n");
2998 ret
= CR_OUT_OF_MEMORY
;
3002 if (RegQueryValueExW(hDeviceKey
,
3006 (LPBYTE
)pszDeviceIdList
,
3007 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
3009 DPRINT("Failed to query the desired ID string!\n");
3010 ret
= CR_REGISTRY_ERROR
;
3014 /* Check whether the device ID is already in use */
3015 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
3017 DPRINT("Device ID was found in the ID string!\n");
3022 /* Append the Device ID */
3023 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
3025 if (RegSetValueExW(hDeviceKey
,
3029 (LPBYTE
)pszDeviceIdList
,
3030 dwDeviceIdListSize
) != ERROR_SUCCESS
)
3032 DPRINT("Failed to set the desired ID string!\n");
3033 ret
= CR_REGISTRY_ERROR
;
3037 RegCloseKey(hDeviceKey
);
3038 if (pszDeviceIdList
)
3039 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
3041 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
3056 return CR_CALL_NOT_IMPLEMENTED
;
3066 PPNP_VETO_TYPE pVetoType
,
3071 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData
;
3073 DWORD ret
= CR_SUCCESS
;
3075 DPRINT1("PNP_QueryRemove(%p %S %p %p %lu 0x%lx)\n",
3076 hBinding
, pszDeviceID
, pVetoType
, pszVetoName
,
3077 ulNameLength
, ulFlags
);
3079 if (ulFlags
& ~CM_REMOVE_BITS
)
3080 return CR_INVALID_FLAG
;
3082 if (!IsValidDeviceInstanceID(pszDeviceID
) ||
3083 IsRootDeviceInstanceID(pszDeviceID
))
3084 return CR_INVALID_DEVINST
;
3086 if (pVetoType
!= NULL
)
3087 *pVetoType
= PNP_VetoTypeUnknown
;
3089 if (pszVetoName
!= NULL
&& ulNameLength
> 0)
3090 *pszVetoName
= UNICODE_NULL
;
3092 RtlZeroMemory(&PlugPlayData
, sizeof(PlugPlayData
));
3093 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
3095 PlugPlayData
.VetoName
= pszVetoName
;
3096 PlugPlayData
.NameLength
= ulNameLength
;
3097 // PlugPlayData.Flags =
3099 Status
= NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice
,
3101 sizeof(PlugPlayData
));
3102 if (!NT_SUCCESS(Status
))
3103 ret
= NtStatusToCrError(Status
);
3112 PNP_RequestDeviceEject(
3115 PPNP_VETO_TYPE pVetoType
,
3120 PLUGPLAY_CONTROL_QUERY_REMOVE_DATA PlugPlayData
;
3122 DWORD ret
= CR_SUCCESS
;
3124 DPRINT1("PNP_RequestDeviceEject(%p %S %p %p %lu 0x%lx)\n",
3125 hBinding
, pszDeviceID
, pVetoType
, pszVetoName
,
3126 ulNameLength
, ulFlags
);
3129 return CR_INVALID_FLAG
;
3131 if (!IsValidDeviceInstanceID(pszDeviceID
))
3132 return CR_INVALID_DEVINST
;
3134 if (pVetoType
!= NULL
)
3135 *pVetoType
= PNP_VetoTypeUnknown
;
3137 if (pszVetoName
!= NULL
&& ulNameLength
> 0)
3138 *pszVetoName
= UNICODE_NULL
;
3140 RtlZeroMemory(&PlugPlayData
, sizeof(PlugPlayData
));
3141 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
3143 PlugPlayData
.VetoName
= pszVetoName
;
3144 PlugPlayData
.NameLength
= ulNameLength
;
3145 // PlugPlayData.Flags =
3147 Status
= NtPlugPlayControl(PlugPlayControlQueryAndRemoveDevice
,
3149 sizeof(PlugPlayData
));
3150 if (!NT_SUCCESS(Status
))
3151 ret
= NtStatusToCrError(Status
);
3160 PNP_IsDockStationPresent(
3168 CONFIGRET ret
= CR_SUCCESS
;
3170 UNREFERENCED_PARAMETER(hBinding
);
3172 DPRINT1("PNP_IsDockStationPresent() called\n");
3176 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
3180 &hKey
) != ERROR_SUCCESS
)
3181 return CR_REGISTRY_ERROR
;
3183 dwSize
= sizeof(DWORD
);
3184 if (RegQueryValueExW(hKey
,
3189 &dwSize
) != ERROR_SUCCESS
)
3190 ret
= CR_REGISTRY_ERROR
;
3194 if (ret
== CR_SUCCESS
)
3196 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
3198 ret
= CR_REGISTRY_ERROR
;
3200 else if (dwValue
!= 0)
3206 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
3218 WCHAR szDockDeviceInstance
[MAX_DEVICE_ID_LEN
];
3219 PLUGPLAY_CONTROL_RETRIEVE_DOCK_DATA DockData
;
3222 DPRINT("PNP_RequestEjectPC(%p)\n", hBinding
);
3224 /* Retrieve the dock device */
3225 DockData
.DeviceInstanceLength
= ARRAYSIZE(szDockDeviceInstance
);
3226 DockData
.DeviceInstance
= szDockDeviceInstance
;
3228 Status
= NtPlugPlayControl(PlugPlayControlRetrieveDock
,
3231 if (!NT_SUCCESS(Status
))
3232 return NtStatusToCrError(Status
);
3234 /* Eject the dock device */
3235 return PNP_RequestDeviceEject(hBinding
,
3236 szDockDeviceInstance
,
3253 PPNP_VETO_TYPE pVetoType
,
3258 CONFIGRET ret
= CR_SUCCESS
;
3259 WCHAR szKeyName
[MAX_PATH
];
3264 UNREFERENCED_PARAMETER(hBinding
);
3266 DPRINT("PNP_HwProfFlags() called\n");
3268 if (!IsValidDeviceInstanceID(pDeviceID
))
3269 return CR_INVALID_DEVINST
;
3274 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
3279 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
3283 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3287 &hKey
) != ERROR_SUCCESS
)
3288 return CR_REGISTRY_ERROR
;
3290 if (ulAction
== PNP_GET_HWPROFFLAGS
)
3292 if (RegOpenKeyExW(hKey
,
3296 &hDeviceKey
) != ERROR_SUCCESS
)
3302 dwSize
= sizeof(DWORD
);
3303 if (RegQueryValueExW(hDeviceKey
,
3308 &dwSize
) != ERROR_SUCCESS
)
3313 RegCloseKey(hDeviceKey
);
3316 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
3318 /* FIXME: not implemented yet */
3319 ret
= CR_CALL_NOT_IMPLEMENTED
;
3334 HWPROFILEINFO
*pHWProfileInfo
,
3335 DWORD ulProfileInfoSize
,
3338 WCHAR szProfileName
[5];
3339 HKEY hKeyConfig
= NULL
;
3340 HKEY hKeyProfiles
= NULL
;
3341 HKEY hKeyProfile
= NULL
;
3342 DWORD dwDisposition
;
3345 CONFIGRET ret
= CR_SUCCESS
;
3347 UNREFERENCED_PARAMETER(hBinding
);
3349 DPRINT("PNP_GetHwProfInfo() called\n");
3351 if (ulProfileInfoSize
== 0)
3353 ret
= CR_INVALID_DATA
;
3359 ret
= CR_INVALID_FLAG
;
3363 /* Initialize the profile information */
3364 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
3365 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
3366 pHWProfileInfo
->HWPI_dwFlags
= 0;
3368 /* Open the 'IDConfigDB' key */
3369 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
3370 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
3373 REG_OPTION_NON_VOLATILE
,
3378 if (lError
!= ERROR_SUCCESS
)
3380 ret
= CR_REGISTRY_ERROR
;
3384 /* Open the 'Hardware Profiles' subkey */
3385 lError
= RegCreateKeyExW(hKeyConfig
,
3386 L
"Hardware Profiles",
3389 REG_OPTION_NON_VOLATILE
,
3390 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
3394 if (lError
!= ERROR_SUCCESS
)
3396 ret
= CR_REGISTRY_ERROR
;
3400 if (ulIndex
== (ULONG
)-1)
3402 dwSize
= sizeof(ULONG
);
3403 lError
= RegQueryValueExW(hKeyConfig
,
3407 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
3409 if (lError
!= ERROR_SUCCESS
)
3411 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
3412 ret
= CR_REGISTRY_ERROR
;
3418 /* FIXME: not implemented yet */
3419 ret
= CR_CALL_NOT_IMPLEMENTED
;
3423 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
3425 lError
= RegOpenKeyExW(hKeyProfiles
,
3430 if (lError
!= ERROR_SUCCESS
)
3432 ret
= CR_REGISTRY_ERROR
;
3436 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
3437 lError
= RegQueryValueExW(hKeyProfile
,
3441 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
3443 if (lError
!= ERROR_SUCCESS
)
3445 ret
= CR_REGISTRY_ERROR
;
3450 if (hKeyProfile
!= NULL
)
3451 RegCloseKey(hKeyProfile
);
3453 if (hKeyProfiles
!= NULL
)
3454 RegCloseKey(hKeyProfiles
);
3456 if (hKeyConfig
!= NULL
)
3457 RegCloseKey(hKeyConfig
);
3466 PNP_AddEmptyLogConf(
3470 DWORD
*pulLogConfTag
,
3474 return CR_CALL_NOT_IMPLEMENTED
;
3484 DWORD ulLogConfType
,
3489 return CR_CALL_NOT_IMPLEMENTED
;
3496 PNP_GetFirstLogConf(
3499 DWORD ulLogConfType
,
3500 DWORD
*pulLogConfTag
,
3504 return CR_CALL_NOT_IMPLEMENTED
;
3514 DWORD ulLogConfType
,
3520 return CR_CALL_NOT_IMPLEMENTED
;
3527 PNP_GetLogConfPriority(
3536 return CR_CALL_NOT_IMPLEMENTED
;
3547 DWORD ulLogConfType
,
3548 RESOURCEID ResourceID
,
3549 DWORD
*pulResourceTag
,
3551 PNP_RPC_BUFFER_SIZE ResourceLen
,
3555 return CR_CALL_NOT_IMPLEMENTED
;
3566 DWORD ulLogConfType
,
3567 RESOURCEID ResourceID
,
3568 DWORD ulResourceTag
,
3569 DWORD
*pulPreviousResType
,
3570 DWORD
*pulPreviousResTag
,
3574 return CR_CALL_NOT_IMPLEMENTED
;
3585 DWORD ulLogConfType
,
3586 RESOURCEID ResourceID
,
3587 DWORD ulResourceTag
,
3588 DWORD
*pulNextResType
,
3589 DWORD
*pulNextResTag
,
3593 return CR_CALL_NOT_IMPLEMENTED
;
3604 DWORD ulLogConfType
,
3605 RESOURCEID ResourceID
,
3606 DWORD ulResourceTag
,
3608 PNP_RPC_BUFFER_SIZE BufferLen
,
3612 return CR_CALL_NOT_IMPLEMENTED
;
3619 PNP_GetResDesDataSize(
3623 DWORD ulLogConfType
,
3624 RESOURCEID ResourceID
,
3625 DWORD ulResourceTag
,
3630 return CR_CALL_NOT_IMPLEMENTED
;
3641 DWORD ulLogConfType
,
3642 RESOURCEID CurrentResourceID
,
3643 RESOURCEID NewResourceID
,
3644 DWORD ulResourceTag
,
3646 PNP_RPC_BUFFER_SIZE ResourceLen
,
3650 return CR_CALL_NOT_IMPLEMENTED
;
3657 PNP_DetectResourceConflict(
3660 RESOURCEID ResourceID
,
3662 PNP_RPC_BUFFER_SIZE ResourceLen
,
3663 BOOL
*pbConflictDetected
,
3666 DPRINT("PNP_DetectResourceConflict()\n");
3668 if (pbConflictDetected
!= NULL
)
3669 *pbConflictDetected
= FALSE
;
3671 return CR_CALL_NOT_IMPLEMENTED
;
3678 PNP_QueryResConfList(
3681 RESOURCEID ResourceID
,
3683 PNP_RPC_BUFFER_SIZE ResourceLen
,
3685 PNP_RPC_BUFFER_SIZE BufferLen
,
3689 return CR_CALL_NOT_IMPLEMENTED
;
3698 DWORD ulHardwareProfile
,
3701 return CR_CALL_NOT_IMPLEMENTED
;
3708 PNP_QueryArbitratorFreeData(
3713 RESOURCEID ResourceID
,
3716 return CR_CALL_NOT_IMPLEMENTED
;
3723 PNP_QueryArbitratorFreeSize(
3727 RESOURCEID ResourceID
,
3730 if (pulSize
!= NULL
)
3733 return CR_CALL_NOT_IMPLEMENTED
;
3744 return CR_CALL_NOT_IMPLEMENTED
;
3751 PNP_RegisterNotification(
3755 BYTE
*pNotificationFilter
,
3756 DWORD ulNotificationFilterSize
,
3762 PDEV_BROADCAST_DEVICEINTERFACE_W pBroadcastDeviceInterface
;
3763 PDEV_BROADCAST_HANDLE pBroadcastDeviceHandle
;
3765 PNOTIFY_DATA pNotifyData
;
3768 DPRINT1("PNP_RegisterNotification(%p %lx '%S' %p %lu 0x%lx %p %lx %p)\n",
3769 hBinding
, ulUnknown2
, pszName
, pNotificationFilter
,
3770 ulNotificationFilterSize
, ulFlags
, pulNotify
, ulUnknown8
, pulUnknown9
);
3772 if (pNotificationFilter
== NULL
||
3773 pulNotify
== NULL
||
3774 pulUnknown9
== NULL
)
3775 return CR_INVALID_POINTER
;
3778 return CR_INVALID_FLAG
;
3780 if ((ulNotificationFilterSize
< sizeof(DEV_BROADCAST_HDR
)) ||
3781 (((PDEV_BROADCAST_HDR
)pNotificationFilter
)->dbch_size
< sizeof(DEV_BROADCAST_HDR
)))
3782 return CR_INVALID_DATA
;
3784 if (((PDEV_BROADCAST_HDR
)pNotificationFilter
)->dbch_devicetype
== DBT_DEVTYP_DEVICEINTERFACE
)
3786 DPRINT1("DBT_DEVTYP_DEVICEINTERFACE\n");
3787 pBroadcastDeviceInterface
= (PDEV_BROADCAST_DEVICEINTERFACE_W
)pNotificationFilter
;
3789 if ((ulNotificationFilterSize
< sizeof(DEV_BROADCAST_DEVICEINTERFACE_W
)) ||
3790 (pBroadcastDeviceInterface
->dbcc_size
< sizeof(DEV_BROADCAST_DEVICEINTERFACE_W
)))
3791 return CR_INVALID_DATA
;
3793 else if (((PDEV_BROADCAST_HDR
)pNotificationFilter
)->dbch_devicetype
== DBT_DEVTYP_HANDLE
)
3795 DPRINT1("DBT_DEVTYP_HANDLE\n");
3796 pBroadcastDeviceHandle
= (PDEV_BROADCAST_HANDLE
)pNotificationFilter
;
3798 if ((ulNotificationFilterSize
< sizeof(DEV_BROADCAST_HANDLE
)) ||
3799 (pBroadcastDeviceHandle
->dbch_size
< sizeof(DEV_BROADCAST_HANDLE
)))
3800 return CR_INVALID_DATA
;
3802 if (ulFlags
& DEVICE_NOTIFY_ALL_INTERFACE_CLASSES
)
3803 return CR_INVALID_FLAG
;
3807 DPRINT1("Invalid device type %lu\n", ((PDEV_BROADCAST_HDR
)pNotificationFilter
)->dbch_devicetype
);
3808 return CR_INVALID_DATA
;
3813 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
3814 if (pNotifyData
== NULL
)
3815 return CR_OUT_OF_MEMORY
;
3817 *pulNotify
= (DWORD
)pNotifyData
;
3829 PNP_UnregisterNotification(
3833 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
3834 hBinding
, ulNotify
);
3838 return CR_CALL_NOT_IMPLEMENTED
;
3848 PNP_GetCustomDevProp(
3851 LPWSTR CustomPropName
,
3852 DWORD
*pulRegDataType
,
3854 PNP_RPC_STRING_LEN
*pulTransferLen
,
3855 PNP_RPC_STRING_LEN
*pulLength
,
3858 HKEY hDeviceKey
= NULL
;
3859 HKEY hParamKey
= NULL
;
3861 CONFIGRET ret
= CR_SUCCESS
;
3863 UNREFERENCED_PARAMETER(hBinding
);
3865 DPRINT("PNP_GetCustomDevProp() called\n");
3867 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
3869 ret
= CR_INVALID_POINTER
;
3873 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
3875 ret
= CR_INVALID_FLAG
;
3879 if (!IsValidDeviceInstanceID(pDeviceID
))
3880 return CR_INVALID_DEVINST
;
3882 if (*pulLength
< *pulTransferLen
)
3883 *pulLength
= *pulTransferLen
;
3885 *pulTransferLen
= 0;
3887 lError
= RegOpenKeyExW(hEnumKey
,
3892 if (lError
!= ERROR_SUCCESS
)
3894 ret
= CR_REGISTRY_ERROR
;
3898 lError
= RegOpenKeyExW(hDeviceKey
,
3899 L
"Device Parameters",
3903 if (lError
!= ERROR_SUCCESS
)
3905 ret
= CR_REGISTRY_ERROR
;
3909 lError
= RegQueryValueExW(hParamKey
,
3915 if (lError
!= ERROR_SUCCESS
)
3917 if (lError
== ERROR_MORE_DATA
)
3919 ret
= CR_BUFFER_SMALL
;
3924 ret
= CR_NO_SUCH_VALUE
;
3929 if (ret
== CR_SUCCESS
)
3930 *pulTransferLen
= *pulLength
;
3932 if (hParamKey
!= NULL
)
3933 RegCloseKey(hParamKey
);
3935 if (hDeviceKey
!= NULL
)
3936 RegCloseKey(hDeviceKey
);
3938 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3947 PNP_GetVersionInternal(
3951 UNREFERENCED_PARAMETER(hBinding
);
3961 PNP_GetBlockedDriverInfo(
3964 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3965 PNP_RPC_BUFFER_SIZE
*pulLength
,
3969 return CR_CALL_NOT_IMPLEMENTED
;
3976 PNP_GetServerSideDeviceInstallFlags(
3978 DWORD
*pulSSDIFlags
,
3981 UNREFERENCED_PARAMETER(hBinding
);
3983 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
3984 hBinding
, pulSSDIFlags
, ulFlags
);
3986 if (pulSSDIFlags
== NULL
)
3987 return CR_INVALID_POINTER
;
3990 return CR_INVALID_FLAG
;
4002 PNP_GetObjectPropKeys(
4006 LPWSTR PropertyCultureName
,
4007 PNP_PROP_COUNT
*PropertyCount
,
4008 PNP_PROP_COUNT
*TransferLen
,
4009 DEVPROPKEY
*PropertyKeys
,
4013 return CR_CALL_NOT_IMPLEMENTED
;
4024 LPWSTR PropertyCultureName
,
4025 const DEVPROPKEY
*PropertyKey
,
4026 DEVPROPTYPE
*PropertyType
,
4027 PNP_PROP_SIZE
*PropertySize
,
4028 PNP_PROP_SIZE
*TransferLen
,
4029 BYTE
*PropertyBuffer
,
4033 return CR_CALL_NOT_IMPLEMENTED
;
4044 LPWSTR PropertyCultureName
,
4045 const DEVPROPKEY
*PropertyKey
,
4046 DEVPROPTYPE PropertyType
,
4047 PNP_PROP_SIZE PropertySize
,
4048 BYTE
*PropertyBuffer
,
4052 return CR_CALL_NOT_IMPLEMENTED
;
4063 return CR_CALL_NOT_IMPLEMENTED
;
4070 PNP_ApplyPowerSettings(
4074 return CR_CALL_NOT_IMPLEMENTED
;
4081 PNP_DriverStoreAddDriverPackage(
4085 return CR_CALL_NOT_IMPLEMENTED
;
4092 PNP_DriverStoreDeleteDriverPackage(
4096 return CR_CALL_NOT_IMPLEMENTED
;
4103 PNP_RegisterServiceNotification(
4107 return CR_CALL_NOT_IMPLEMENTED
;
4114 PNP_SetActiveService(
4120 return CR_CALL_NOT_IMPLEMENTED
;
4127 PNP_DeleteServiceDevices(
4131 return CR_CALL_NOT_IMPLEMENTED
;