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/umpnpmgr.c
23 * PURPOSE: User-mode Plug and Play manager
24 * PROGRAMMER: Eric Kohl (eric.kohl@reactos.org)
25 * Hervé Poussineau (hpoussin@reactos.org)
26 * Colin Finck (colin@reactos.org)
29 /* INCLUDES *****************************************************************/
31 #define WIN32_NO_STATUS
33 #define COM_NO_WINDOWS_H
45 #include <umpnpmgr/sysguid.h>
55 /* GLOBALS ******************************************************************/
57 static WCHAR ServiceName
[] = L
"PlugPlay";
59 static SERVICE_STATUS_HANDLE ServiceStatusHandle
;
60 static SERVICE_STATUS ServiceStatus
;
62 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
64 static HKEY hEnumKey
= NULL
;
65 static HKEY hClassKey
= NULL
;
67 static HANDLE hUserToken
= NULL
;
68 static HANDLE hInstallEvent
= NULL
;
69 static HANDLE hNoPendingInstalls
= NULL
;
71 static SLIST_HEADER DeviceInstallListHead
;
72 static HANDLE hDeviceInstallListNotEmpty
;
76 SLIST_ENTRY ListEntry
;
78 } DeviceInstallParams
;
80 /* FUNCTIONS *****************************************************************/
83 RpcServerThread(LPVOID lpParameter
)
86 BOOLEAN RegisteredProtSeq
= FALSE
;
88 UNREFERENCED_PARAMETER(lpParameter
);
90 DPRINT("RpcServerThread() called\n");
93 /* 2k/XP/2k3-compatible protocol sequence/endpoint */
94 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
97 NULL
); // Security descriptor
98 if (Status
== RPC_S_OK
)
99 RegisteredProtSeq
= TRUE
;
101 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
104 /* Vista/7-compatible protocol sequence/endpoint */
105 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
108 NULL
); // Security descriptor
109 if (Status
== RPC_S_OK
)
110 RegisteredProtSeq
= TRUE
;
112 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
114 /* Make sure there's a usable endpoint */
115 if (RegisteredProtSeq
== FALSE
)
118 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
121 if (Status
!= RPC_S_OK
)
123 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
127 Status
= RpcServerListen(1,
130 if (Status
!= RPC_S_OK
)
132 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
136 /* ROS HACK (this should never happen...) */
137 DPRINT1("*** Other devices won't be installed correctly. If something\n");
138 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
140 DPRINT("RpcServerThread() done\n");
146 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
148 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
152 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
154 HeapFree(GetProcessHeap(), 0, ptr
);
158 static CONFIGRET WINAPI
159 NtStatusToCrError(NTSTATUS Status
)
163 case STATUS_NOT_IMPLEMENTED
:
164 return CR_CALL_NOT_IMPLEMENTED
;
166 case STATUS_INVALID_PARAMETER
:
167 return CR_INVALID_DATA
;
169 case STATUS_NO_SUCH_DEVICE
:
170 return CR_NO_SUCH_DEVINST
;
172 case STATUS_ACCESS_DENIED
:
173 return CR_ACCESS_DENIED
;
175 case STATUS_BUFFER_TOO_SMALL
:
176 return CR_BUFFER_SMALL
;
178 case STATUS_OBJECT_NAME_NOT_FOUND
:
179 return CR_NO_SUCH_VALUE
;
188 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
189 OUT LPWSTR pszEnumerator
,
190 OUT LPWSTR pszDevice
,
191 OUT LPWSTR pszInstance
)
193 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
194 LPWSTR lpEnumerator
= NULL
;
195 LPWSTR lpDevice
= NULL
;
196 LPWSTR lpInstance
= NULL
;
199 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
205 lpEnumerator
= szLocalDeviceInstanceID
;
207 ptr
= wcschr(lpEnumerator
, L
'\\');
213 ptr
= wcschr(lpDevice
, L
'\\');
221 if (lpEnumerator
!= NULL
)
222 wcscpy(pszEnumerator
, lpEnumerator
);
224 if (lpDevice
!= NULL
)
225 wcscpy(pszDevice
, lpDevice
);
227 if (lpInstance
!= NULL
)
228 wcscpy(pszInstance
, lpInstance
);
232 /* PUBLIC FUNCTIONS **********************************************************/
240 UNREFERENCED_PARAMETER(hBinding
);
251 UNREFERENCED_PARAMETER(hBinding
);
263 UNREFERENCED_PARAMETER(hBinding
);
278 UNREFERENCED_PARAMETER(hBinding
);
279 UNREFERENCED_PARAMETER(ulFlags
);
281 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
292 UNREFERENCED_PARAMETER(hBinding
);
294 DPRINT("PNP_InitDetection() called\n");
307 DWORD ReturnValue
= CR_FAILURE
;
310 UNREFERENCED_PARAMETER(hBinding
);
311 UNREFERENCED_PARAMETER(Admin
);
313 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
315 /* Get the users token */
316 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
320 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
326 CloseHandle(hUserToken
);
330 if (!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
332 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
336 /* Trigger the installer thread */
338 SetEvent(hInstallEvent
);
340 ReturnValue
= CR_SUCCESS
;
344 CloseHandle(hProcess
);
353 PNP_ValidateDeviceInstance(
358 CONFIGRET ret
= CR_SUCCESS
;
359 HKEY hDeviceKey
= NULL
;
361 UNREFERENCED_PARAMETER(hBinding
);
362 UNREFERENCED_PARAMETER(ulFlags
);
364 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
367 if (RegOpenKeyExW(hEnumKey
,
373 DPRINT("Could not open the Device Key!\n");
374 ret
= CR_NO_SUCH_DEVNODE
;
378 /* FIXME: add more tests */
381 if (hDeviceKey
!= NULL
)
382 RegCloseKey(hDeviceKey
);
384 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
393 PNP_GetRootDeviceInstance(
396 PNP_RPC_STRING_LEN ulLength
)
398 CONFIGRET ret
= CR_SUCCESS
;
400 UNREFERENCED_PARAMETER(hBinding
);
402 DPRINT("PNP_GetRootDeviceInstance() called\n");
406 ret
= CR_INVALID_POINTER
;
409 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
411 ret
= CR_BUFFER_SMALL
;
419 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
428 PNP_GetRelatedDeviceInstance(
430 DWORD ulRelationship
,
432 LPWSTR pRelatedDeviceId
,
433 PNP_RPC_STRING_LEN
*pulLength
,
436 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
437 CONFIGRET ret
= CR_SUCCESS
;
440 UNREFERENCED_PARAMETER(hBinding
);
441 UNREFERENCED_PARAMETER(ulFlags
);
443 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
444 DPRINT(" Relationship %ld\n", ulRelationship
);
445 DPRINT(" DeviceId %S\n", pDeviceID
);
447 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
450 PlugPlayData
.Relation
= ulRelationship
;
452 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
453 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
455 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
456 (PVOID
)&PlugPlayData
,
457 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
458 if (!NT_SUCCESS(Status
))
460 ret
= NtStatusToCrError(Status
);
463 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
464 if (ret
== CR_SUCCESS
)
466 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
476 PNP_EnumerateSubKeys(
481 PNP_RPC_STRING_LEN ulLength
,
482 PNP_RPC_STRING_LEN
*pulRequiredLen
,
485 CONFIGRET ret
= CR_SUCCESS
;
489 UNREFERENCED_PARAMETER(hBinding
);
490 UNREFERENCED_PARAMETER(ulFlags
);
492 DPRINT("PNP_EnumerateSubKeys() called\n");
496 case PNP_ENUMERATOR_SUBKEYS
:
500 case PNP_CLASS_SUBKEYS
:
508 *pulRequiredLen
= ulLength
;
509 dwError
= RegEnumKeyExW(hKey
,
517 if (dwError
!= ERROR_SUCCESS
)
519 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
526 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
534 GetRelationsInstanceList(
535 _In_ PWSTR pszDevice
,
537 _Inout_ PWSTR pszBuffer
,
538 _Inout_ PDWORD pulLength
)
540 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
542 CONFIGRET ret
= CR_SUCCESS
;
544 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
547 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
549 PlugPlayData
.Relations
= 3;
551 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
553 PlugPlayData
.Relations
= 2;
555 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
557 PlugPlayData
.Relations
= 1;
559 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
561 PlugPlayData
.Relations
= 0;
564 PlugPlayData
.BufferSize
= *pulLength
* sizeof(WCHAR
);
565 PlugPlayData
.Buffer
= pszBuffer
;
567 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
568 (PVOID
)&PlugPlayData
,
569 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
570 if (NT_SUCCESS(Status
))
572 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
576 ret
= NtStatusToCrError(Status
);
585 GetServiceInstanceList(
586 _In_ PWSTR pszService
,
587 _Inout_ PWSTR pszBuffer
,
588 _Inout_ PDWORD pulLength
)
590 WCHAR szPathBuffer
[512];
592 HKEY hServicesKey
= NULL
, hServiceKey
= NULL
, hEnumKey
= NULL
;
593 DWORD dwValues
, dwSize
, dwIndex
, dwUsedLength
, dwPathLength
;
596 CONFIGRET ret
= CR_SUCCESS
;
598 /* Open the device key */
599 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
600 L
"System\\CurrentControlSet\\Services",
604 if (dwError
!= ERROR_SUCCESS
)
606 DPRINT("Failed to open the services key (Error %lu)\n", dwError
);
607 return CR_REGISTRY_ERROR
;
610 dwError
= RegOpenKeyExW(hServicesKey
,
615 if (dwError
!= ERROR_SUCCESS
)
617 DPRINT("Failed to open the service key (Error %lu)\n", dwError
);
618 ret
= CR_REGISTRY_ERROR
;
622 dwError
= RegOpenKeyExW(hServiceKey
,
627 if (dwError
!= ERROR_SUCCESS
)
629 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError
);
630 ret
= CR_REGISTRY_ERROR
;
634 /* Retrieve the number of device instances */
635 dwSize
= sizeof(DWORD
);
636 dwError
= RegQueryValueExW(hEnumKey
,
642 if (dwError
!= ERROR_SUCCESS
)
644 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError
);
648 DPRINT("dwValues %lu\n", dwValues
);
653 for (dwIndex
= 0; dwIndex
< dwValues
; dwIndex
++)
655 wsprintf(szName
, L
"%lu", dwIndex
);
657 dwSize
= sizeof(szPathBuffer
);
658 dwError
= RegQueryValueExW(hEnumKey
,
662 (LPBYTE
)szPathBuffer
,
664 if (dwError
!= ERROR_SUCCESS
)
667 DPRINT("Path: %S\n", szPathBuffer
);
669 dwPathLength
= wcslen(szPathBuffer
) + 1;
670 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
672 ret
= CR_BUFFER_SMALL
;
676 wcscpy(pPtr
, szPathBuffer
);
677 dwUsedLength
+= dwPathLength
;
678 pPtr
+= dwPathLength
;
680 *pPtr
= UNICODE_NULL
;
684 if (hEnumKey
!= NULL
)
685 RegCloseKey(hEnumKey
);
687 if (hServiceKey
!= NULL
)
688 RegCloseKey(hServiceKey
);
690 if (hServicesKey
!= NULL
)
691 RegCloseKey(hServicesKey
);
693 if (ret
== CR_SUCCESS
)
694 *pulLength
= dwUsedLength
+ 1;
704 GetDeviceInstanceList(
705 _In_ PWSTR pszDevice
,
706 _Inout_ PWSTR pszBuffer
,
707 _Inout_ PDWORD pulLength
)
709 WCHAR szInstanceBuffer
[MAX_DEVICE_ID_LEN
];
710 WCHAR szPathBuffer
[512];
712 DWORD dwInstanceLength
, dwPathLength
, dwUsedLength
;
713 DWORD dwIndex
, dwError
;
715 CONFIGRET ret
= CR_SUCCESS
;
717 /* Open the device key */
718 dwError
= RegOpenKeyExW(hEnumKey
,
721 KEY_ENUMERATE_SUB_KEYS
,
723 if (dwError
!= ERROR_SUCCESS
)
725 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
726 return CR_REGISTRY_ERROR
;
732 for (dwIndex
= 0; ; dwIndex
++)
734 dwInstanceLength
= MAX_DEVICE_ID_LEN
;
735 dwError
= RegEnumKeyExW(hDeviceKey
,
743 if (dwError
!= ERROR_SUCCESS
)
746 wsprintf(szPathBuffer
, L
"%s\\%s", pszDevice
, szInstanceBuffer
);
747 DPRINT("Path: %S\n", szPathBuffer
);
749 dwPathLength
= wcslen(szPathBuffer
) + 1;
750 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
752 ret
= CR_BUFFER_SMALL
;
756 wcscpy(pPtr
, szPathBuffer
);
757 dwUsedLength
+= dwPathLength
;
758 pPtr
+= dwPathLength
;
760 *pPtr
= UNICODE_NULL
;
763 RegCloseKey(hDeviceKey
);
765 if (ret
== CR_SUCCESS
)
766 *pulLength
= dwUsedLength
+ 1;
775 GetEnumeratorInstanceList(
776 _In_ PWSTR pszEnumerator
,
777 _Inout_ PWSTR pszBuffer
,
778 _Inout_ PDWORD pulLength
)
780 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
781 WCHAR szPathBuffer
[512];
784 DWORD dwIndex
, dwDeviceLength
, dwUsedLength
, dwRemainingLength
, dwPathLength
;
786 CONFIGRET ret
= CR_SUCCESS
;
788 /* Open the enumerator key */
789 dwError
= RegOpenKeyExW(hEnumKey
,
792 KEY_ENUMERATE_SUB_KEYS
,
794 if (dwError
!= ERROR_SUCCESS
)
796 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
797 return CR_REGISTRY_ERROR
;
801 dwRemainingLength
= *pulLength
;
804 for (dwIndex
= 0; ; dwIndex
++)
806 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
807 dwError
= RegEnumKeyExW(hEnumeratorKey
,
815 if (dwError
!= ERROR_SUCCESS
)
818 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
819 DPRINT("Path: %S\n", szPathBuffer
);
821 dwPathLength
= dwRemainingLength
;
822 ret
= GetDeviceInstanceList(szPathBuffer
,
825 if (ret
!= CR_SUCCESS
)
828 dwUsedLength
+= dwPathLength
- 1;
829 dwRemainingLength
+= dwPathLength
- 1;
830 pPtr
+= dwPathLength
- 1;
833 RegCloseKey(hEnumeratorKey
);
835 if (ret
== CR_SUCCESS
)
836 *pulLength
= dwUsedLength
+ 1;
847 _Inout_ PWSTR pszBuffer
,
848 _Inout_ PDWORD pulLength
)
850 WCHAR szEnumeratorBuffer
[MAX_DEVICE_ID_LEN
];
852 DWORD dwIndex
, dwEnumeratorLength
, dwUsedLength
, dwRemainingLength
, dwPathLength
;
854 CONFIGRET ret
= CR_SUCCESS
;
857 dwRemainingLength
= *pulLength
;
860 for (dwIndex
= 0; ; dwIndex
++)
862 dwEnumeratorLength
= MAX_DEVICE_ID_LEN
;
863 dwError
= RegEnumKeyExW(hEnumKey
,
867 NULL
, NULL
, NULL
, NULL
);
868 if (dwError
!= ERROR_SUCCESS
)
871 dwPathLength
= dwRemainingLength
;
872 ret
= GetEnumeratorInstanceList(szEnumeratorBuffer
,
875 if (ret
!= CR_SUCCESS
)
878 dwUsedLength
+= dwPathLength
- 1;
879 dwRemainingLength
+= dwPathLength
- 1;
880 pPtr
+= dwPathLength
- 1;
883 if (ret
== CR_SUCCESS
)
884 *pulLength
= dwUsedLength
+ 1;
899 PNP_RPC_STRING_LEN
*pulLength
,
902 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
903 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
904 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
905 CONFIGRET ret
= CR_SUCCESS
;
907 DPRINT("PNP_GetDeviceList() called\n");
909 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
910 return CR_INVALID_FLAG
;
912 if (pulLength
== NULL
)
913 return CR_INVALID_POINTER
;
915 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
917 return CR_INVALID_POINTER
;
920 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
921 CM_GETIDLIST_FILTER_POWERRELATIONS
|
922 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
923 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
925 ret
= GetRelationsInstanceList(pszFilter
,
930 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
932 ret
= GetServiceInstanceList(pszFilter
,
936 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
938 SplitDeviceInstanceID(pszFilter
,
943 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
945 ret
= GetDeviceInstanceList(pszFilter
,
951 ret
= GetEnumeratorInstanceList(pszFilter
,
956 else /* CM_GETIDLIST_FILTER_NONE */
958 ret
= GetAllInstanceList(Buffer
,
968 GetRelationsInstanceListSize(
969 _In_ PWSTR pszDevice
,
971 _Inout_ PDWORD pulLength
)
973 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
975 CONFIGRET ret
= CR_SUCCESS
;
977 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
980 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
982 PlugPlayData
.Relations
= 3;
984 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
986 PlugPlayData
.Relations
= 2;
988 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
990 PlugPlayData
.Relations
= 1;
992 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
994 PlugPlayData
.Relations
= 0;
997 PlugPlayData
.BufferSize
= 0;
998 PlugPlayData
.Buffer
= NULL
;
1000 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
1001 (PVOID
)&PlugPlayData
,
1002 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
1003 if (NT_SUCCESS(Status
))
1005 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
1009 ret
= NtStatusToCrError(Status
);
1018 GetServiceInstanceListSize(
1019 _In_ PWSTR pszService
,
1020 _Out_ PDWORD pulLength
)
1022 HKEY hServicesKey
= NULL
, hServiceKey
= NULL
, hEnumKey
= NULL
;
1023 DWORD dwValues
, dwMaxValueLength
, dwSize
;
1025 CONFIGRET ret
= CR_SUCCESS
;
1027 /* Open the device key */
1028 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1029 L
"System\\CurrentControlSet\\Services",
1033 if (dwError
!= ERROR_SUCCESS
)
1035 DPRINT("Failed to open the services key (Error %lu)\n", dwError
);
1036 return CR_REGISTRY_ERROR
;
1039 dwError
= RegOpenKeyExW(hServicesKey
,
1044 if (dwError
!= ERROR_SUCCESS
)
1046 DPRINT("Failed to open the service key (Error %lu)\n", dwError
);
1047 ret
= CR_REGISTRY_ERROR
;
1051 dwError
= RegOpenKeyExW(hServiceKey
,
1056 if (dwError
!= ERROR_SUCCESS
)
1058 DPRINT("Failed to open the service enum key (Error %lu)\n", dwError
);
1059 ret
= CR_REGISTRY_ERROR
;
1063 /* Retrieve the number of device instances */
1064 dwSize
= sizeof(DWORD
);
1065 dwError
= RegQueryValueExW(hEnumKey
,
1071 if (dwError
!= ERROR_SUCCESS
)
1073 DPRINT("RegQueryValueExW failed (Error %lu)\n", dwError
);
1077 /* Retrieve the maximum instance name length */
1078 dwError
= RegQueryInfoKeyW(hEnumKey
,
1090 if (dwError
!= ERROR_SUCCESS
)
1092 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
1093 dwMaxValueLength
= MAX_DEVICE_ID_LEN
;
1096 DPRINT("dwValues %lu dwMaxValueLength %lu\n", dwValues
, dwMaxValueLength
/ sizeof(WCHAR
));
1098 /* Return the largest possible buffer size */
1099 *pulLength
= dwValues
* dwMaxValueLength
/ sizeof(WCHAR
) + 2;
1102 if (hEnumKey
!= NULL
)
1103 RegCloseKey(hEnumKey
);
1105 if (hServiceKey
!= NULL
)
1106 RegCloseKey(hServiceKey
);
1108 if (hServicesKey
!= NULL
)
1109 RegCloseKey(hServicesKey
);
1117 GetDeviceInstanceListSize(
1118 _In_ LPCWSTR pszDevice
,
1119 _Out_ PULONG pulLength
)
1122 DWORD dwSubKeys
, dwMaxSubKeyLength
;
1125 /* Open the device key */
1126 dwError
= RegOpenKeyExW(hEnumKey
,
1131 if (dwError
!= ERROR_SUCCESS
)
1133 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
1134 return CR_REGISTRY_ERROR
;
1137 /* Retrieve the number of device instances and the maximum name length */
1138 dwError
= RegQueryInfoKeyW(hDeviceKey
,
1150 if (dwError
!= ERROR_SUCCESS
)
1152 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
1154 dwMaxSubKeyLength
= 0;
1157 /* Close the device key */
1158 RegCloseKey(hDeviceKey
);
1160 /* Return the largest possible buffer size */
1161 *pulLength
= dwSubKeys
* (wcslen(pszDevice
) + 1 + dwMaxSubKeyLength
+ 1);
1169 GetEnumeratorInstanceListSize(
1170 _In_ LPCWSTR pszEnumerator
,
1171 _Out_ PULONG pulLength
)
1173 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
1174 WCHAR szPathBuffer
[512];
1175 HKEY hEnumeratorKey
;
1176 DWORD dwIndex
, dwDeviceLength
, dwBufferLength
;
1178 CONFIGRET ret
= CR_SUCCESS
;
1182 /* Open the enumerator key */
1183 dwError
= RegOpenKeyExW(hEnumKey
,
1186 KEY_ENUMERATE_SUB_KEYS
,
1188 if (dwError
!= ERROR_SUCCESS
)
1190 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
1191 return CR_REGISTRY_ERROR
;
1194 for (dwIndex
= 0; ; dwIndex
++)
1196 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
1197 dwError
= RegEnumKeyExW(hEnumeratorKey
,
1205 if (dwError
!= ERROR_SUCCESS
)
1208 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
1209 DPRINT("Path: %S\n", szPathBuffer
);
1211 ret
= GetDeviceInstanceListSize(szPathBuffer
, &dwBufferLength
);
1212 if (ret
!= CR_SUCCESS
)
1218 *pulLength
+= dwBufferLength
;
1221 /* Close the enumerator key */
1222 RegCloseKey(hEnumeratorKey
);
1230 GetAllInstanceListSize(
1231 _Out_ PULONG pulLength
)
1233 WCHAR szEnumeratorBuffer
[MAX_DEVICE_ID_LEN
];
1234 DWORD dwIndex
, dwEnumeratorLength
, dwBufferLength
;
1236 CONFIGRET ret
= CR_SUCCESS
;
1238 for (dwIndex
= 0; ; dwIndex
++)
1240 dwEnumeratorLength
= MAX_DEVICE_ID_LEN
;
1241 dwError
= RegEnumKeyExW(hEnumKey
,
1244 &dwEnumeratorLength
,
1245 NULL
, NULL
, NULL
, NULL
);
1246 if (dwError
!= ERROR_SUCCESS
)
1249 /* Get the size of all device instances for the enumerator */
1250 ret
= GetEnumeratorInstanceListSize(szEnumeratorBuffer
,
1252 if (ret
!= CR_SUCCESS
)
1255 *pulLength
+= dwBufferLength
;
1265 PNP_GetDeviceListSize(
1268 PNP_RPC_BUFFER_SIZE
*pulLength
,
1271 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1272 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1273 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1274 CONFIGRET ret
= CR_SUCCESS
;
1276 DPRINT("PNP_GetDeviceListSize(%p %S %p 0x%lx)\n",
1277 hBinding
, pszFilter
, pulLength
, ulFlags
);
1279 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
1280 return CR_INVALID_FLAG
;
1282 if (pulLength
== NULL
)
1283 return CR_INVALID_POINTER
;
1285 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
1286 (pszFilter
== NULL
))
1287 return CR_INVALID_POINTER
;
1292 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
1293 CM_GETIDLIST_FILTER_POWERRELATIONS
|
1294 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
1295 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
1297 ret
= GetRelationsInstanceListSize(pszFilter
,
1301 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
1303 ret
= GetServiceInstanceListSize(pszFilter
,
1306 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
1308 SplitDeviceInstanceID(pszFilter
,
1313 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
1315 ret
= GetDeviceInstanceListSize(pszFilter
,
1320 ret
= GetEnumeratorInstanceListSize(pszFilter
,
1324 else /* CM_GETIDLIST_FILTER_NONE */
1326 ret
= GetAllInstanceListSize(pulLength
);
1329 /* Add one character for the terminating double UNICODE_NULL */
1330 if (ret
== CR_SUCCESS
)
1346 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
1347 CONFIGRET ret
= CR_SUCCESS
;
1350 UNREFERENCED_PARAMETER(hBinding
);
1351 UNREFERENCED_PARAMETER(ulFlags
);
1353 DPRINT("PNP_GetDepth() called\n");
1355 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1358 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
1359 (PVOID
)&PlugPlayData
,
1360 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
1361 if (NT_SUCCESS(Status
))
1363 *pulDepth
= PlugPlayData
.Depth
;
1367 ret
= NtStatusToCrError(Status
);
1370 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
1379 PNP_GetDeviceRegProp(
1383 DWORD
*pulRegDataType
,
1385 PNP_PROP_SIZE
*pulTransferLen
,
1386 PNP_PROP_SIZE
*pulLength
,
1389 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
1390 CONFIGRET ret
= CR_SUCCESS
;
1391 LPWSTR lpValueName
= NULL
;
1396 UNREFERENCED_PARAMETER(hBinding
);
1398 DPRINT("PNP_GetDeviceRegProp() called\n");
1400 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1402 ret
= CR_INVALID_POINTER
;
1408 ret
= CR_INVALID_FLAG
;
1412 /* FIXME: Check pDeviceID */
1414 if (*pulLength
< *pulTransferLen
)
1415 *pulLength
= *pulTransferLen
;
1417 *pulTransferLen
= 0;
1421 case CM_DRP_DEVICEDESC
:
1422 lpValueName
= L
"DeviceDesc";
1425 case CM_DRP_HARDWAREID
:
1426 lpValueName
= L
"HardwareID";
1429 case CM_DRP_COMPATIBLEIDS
:
1430 lpValueName
= L
"CompatibleIDs";
1433 case CM_DRP_SERVICE
:
1434 lpValueName
= L
"Service";
1438 lpValueName
= L
"Class";
1441 case CM_DRP_CLASSGUID
:
1442 lpValueName
= L
"ClassGUID";
1446 lpValueName
= L
"Driver";
1449 case CM_DRP_CONFIGFLAGS
:
1450 lpValueName
= L
"ConfigFlags";
1454 lpValueName
= L
"Mfg";
1457 case CM_DRP_FRIENDLYNAME
:
1458 lpValueName
= L
"FriendlyName";
1461 case CM_DRP_LOCATION_INFORMATION
:
1462 lpValueName
= L
"LocationInformation";
1465 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
1466 PlugPlayData
.Property
= PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME
;
1469 case CM_DRP_CAPABILITIES
:
1470 lpValueName
= L
"Capabilities";
1473 case CM_DRP_UI_NUMBER
:
1474 PlugPlayData
.Property
= PNP_PROPERTY_UI_NUMBER
;
1477 case CM_DRP_UPPERFILTERS
:
1478 lpValueName
= L
"UpperFilters";
1481 case CM_DRP_LOWERFILTERS
:
1482 lpValueName
= L
"LowerFilters";
1485 case CM_DRP_BUSTYPEGUID
:
1486 PlugPlayData
.Property
= PNP_PROPERTY_BUSTYPEGUID
;
1489 case CM_DRP_LEGACYBUSTYPE
:
1490 PlugPlayData
.Property
= PNP_PROPERTY_LEGACYBUSTYPE
;
1493 case CM_DRP_BUSNUMBER
:
1494 PlugPlayData
.Property
= PNP_PROPERTY_BUSNUMBER
;
1497 case CM_DRP_ENUMERATOR_NAME
:
1498 PlugPlayData
.Property
= PNP_PROPERTY_ENUMERATOR_NAME
;
1501 case CM_DRP_SECURITY
:
1502 lpValueName
= L
"Security";
1505 case CM_DRP_DEVTYPE
:
1506 lpValueName
= L
"DeviceType";
1509 case CM_DRP_EXCLUSIVE
:
1510 lpValueName
= L
"Exclusive";
1513 case CM_DRP_CHARACTERISTICS
:
1514 lpValueName
= L
"DeviceCharacteristics";
1517 case CM_DRP_ADDRESS
:
1518 PlugPlayData
.Property
= PNP_PROPERTY_ADDRESS
;
1521 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1522 lpValueName
= L
"UINumberDescFormat";
1525 case CM_DRP_DEVICE_POWER_DATA
:
1526 PlugPlayData
.Property
= PNP_PROPERTY_POWER_DATA
;
1529 case CM_DRP_REMOVAL_POLICY
:
1530 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY
;
1533 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
1534 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
;
1537 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1538 lpValueName
= L
"RemovalPolicy";
1541 case CM_DRP_INSTALL_STATE
:
1542 PlugPlayData
.Property
= PNP_PROPERTY_INSTALL_STATE
;
1545 #if (WINVER >= _WIN32_WINNT_WS03)
1546 case CM_DRP_LOCATION_PATHS
:
1547 PlugPlayData
.Property
= PNP_PROPERTY_LOCATION_PATHS
;
1551 #if (WINVER >= _WIN32_WINNT_WIN7)
1552 case CM_DRP_BASE_CONTAINERID
:
1553 PlugPlayData
.Property
= PNP_PROPERTY_CONTAINERID
;
1558 ret
= CR_INVALID_PROPERTY
;
1562 DPRINT("Value name: %S\n", lpValueName
);
1566 /* Retrieve information from the Registry */
1567 lError
= RegOpenKeyExW(hEnumKey
,
1572 if (lError
!= ERROR_SUCCESS
)
1576 ret
= CR_INVALID_DEVNODE
;
1580 lError
= RegQueryValueExW(hKey
,
1586 if (lError
!= ERROR_SUCCESS
)
1588 if (lError
== ERROR_MORE_DATA
)
1590 ret
= CR_BUFFER_SMALL
;
1595 ret
= CR_NO_SUCH_VALUE
;
1601 /* Retrieve information from the Device Node */
1602 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1604 PlugPlayData
.Buffer
= Buffer
;
1605 PlugPlayData
.BufferSize
= *pulLength
;
1607 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
1608 (PVOID
)&PlugPlayData
,
1609 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
1610 if (NT_SUCCESS(Status
))
1612 *pulLength
= PlugPlayData
.BufferSize
;
1616 ret
= NtStatusToCrError(Status
);
1622 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1627 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1636 PNP_SetDeviceRegProp(
1642 PNP_PROP_SIZE ulLength
,
1645 CONFIGRET ret
= CR_SUCCESS
;
1646 LPWSTR lpValueName
= NULL
;
1649 UNREFERENCED_PARAMETER(hBinding
);
1650 UNREFERENCED_PARAMETER(ulFlags
);
1652 DPRINT("PNP_SetDeviceRegProp() called\n");
1654 DPRINT("DeviceId: %S\n", pDeviceId
);
1655 DPRINT("Property: %lu\n", ulProperty
);
1656 DPRINT("DataType: %lu\n", ulDataType
);
1657 DPRINT("Length: %lu\n", ulLength
);
1661 case CM_DRP_DEVICEDESC
:
1662 lpValueName
= L
"DeviceDesc";
1665 case CM_DRP_HARDWAREID
:
1666 lpValueName
= L
"HardwareID";
1669 case CM_DRP_COMPATIBLEIDS
:
1670 lpValueName
= L
"CompatibleIDs";
1673 case CM_DRP_SERVICE
:
1674 lpValueName
= L
"Service";
1678 lpValueName
= L
"Class";
1681 case CM_DRP_CLASSGUID
:
1682 lpValueName
= L
"ClassGUID";
1686 lpValueName
= L
"Driver";
1689 case CM_DRP_CONFIGFLAGS
:
1690 lpValueName
= L
"ConfigFlags";
1694 lpValueName
= L
"Mfg";
1697 case CM_DRP_FRIENDLYNAME
:
1698 lpValueName
= L
"FriendlyName";
1701 case CM_DRP_LOCATION_INFORMATION
:
1702 lpValueName
= L
"LocationInformation";
1705 case CM_DRP_UPPERFILTERS
:
1706 lpValueName
= L
"UpperFilters";
1709 case CM_DRP_LOWERFILTERS
:
1710 lpValueName
= L
"LowerFilters";
1713 case CM_DRP_SECURITY
:
1714 lpValueName
= L
"Security";
1717 case CM_DRP_DEVTYPE
:
1718 lpValueName
= L
"DeviceType";
1721 case CM_DRP_EXCLUSIVE
:
1722 lpValueName
= L
"Exclusive";
1725 case CM_DRP_CHARACTERISTICS
:
1726 lpValueName
= L
"DeviceCharacteristics";
1729 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1730 lpValueName
= L
"UINumberDescFormat";
1733 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1734 lpValueName
= L
"RemovalPolicy";
1738 return CR_INVALID_PROPERTY
;
1741 DPRINT("Value name: %S\n", lpValueName
);
1743 if (RegOpenKeyExW(hEnumKey
,
1748 return CR_INVALID_DEVNODE
;
1752 if (RegDeleteValueW(hKey
,
1754 ret
= CR_REGISTRY_ERROR
;
1758 if (RegSetValueExW(hKey
,
1764 ret
= CR_REGISTRY_ERROR
;
1769 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1778 PNP_GetClassInstance(
1781 LPWSTR pszClassInstance
,
1782 PNP_RPC_STRING_LEN ulLength
)
1785 return CR_CALL_NOT_IMPLEMENTED
;
1800 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1809 return CR_REGISTRY_ERROR
;
1811 /* FIXME: Set security key */
1822 PNP_DeleteRegistryKey(
1825 LPWSTR pszParentKey
,
1830 return CR_CALL_NOT_IMPLEMENTED
;
1839 DWORD
*pulClassCount
,
1845 UNREFERENCED_PARAMETER(hBinding
);
1846 UNREFERENCED_PARAMETER(ulFlags
);
1848 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1853 if (dwError
!= ERROR_SUCCESS
)
1854 return CR_INVALID_DATA
;
1856 dwError
= RegQueryInfoKeyW(hKey
,
1869 if (dwError
!= ERROR_SUCCESS
)
1870 return CR_INVALID_DATA
;
1881 LPWSTR pszClassGuid
,
1883 PNP_RPC_STRING_LEN
*pulLength
,
1886 WCHAR szKeyName
[MAX_PATH
];
1887 CONFIGRET ret
= CR_SUCCESS
;
1891 UNREFERENCED_PARAMETER(hBinding
);
1892 UNREFERENCED_PARAMETER(ulFlags
);
1894 DPRINT("PNP_GetClassName() called\n");
1896 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1897 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1898 lstrcatW(szKeyName
, pszClassGuid
);
1900 return CR_INVALID_DATA
;
1902 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1907 return CR_REGISTRY_ERROR
;
1909 dwSize
= *pulLength
* sizeof(WCHAR
);
1910 if (RegQueryValueExW(hKey
,
1918 ret
= CR_REGISTRY_ERROR
;
1922 *pulLength
= dwSize
/ sizeof(WCHAR
);
1927 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1938 LPWSTR pszClassGuid
,
1941 CONFIGRET ret
= CR_SUCCESS
;
1943 UNREFERENCED_PARAMETER(hBinding
);
1945 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1947 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1949 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1950 ret
= CR_REGISTRY_ERROR
;
1954 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1955 ret
= CR_REGISTRY_ERROR
;
1958 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1967 PNP_GetInterfaceDeviceAlias(
1969 LPWSTR pszInterfaceDevice
,
1970 GUID
*AliasInterfaceGuid
,
1971 LPWSTR pszAliasInterfaceDevice
,
1972 PNP_RPC_STRING_LEN
*pulLength
,
1973 PNP_RPC_STRING_LEN
*pulTransferLen
,
1977 return CR_CALL_NOT_IMPLEMENTED
;
1984 PNP_GetInterfaceDeviceList(
1986 GUID
*InterfaceGuid
,
1989 PNP_RPC_BUFFER_SIZE
*pulLength
,
1993 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1994 DWORD ret
= CR_SUCCESS
;
1996 UNREFERENCED_PARAMETER(hBinding
);
1998 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2001 PlugPlayData
.Flags
= ulFlags
;
2002 PlugPlayData
.FilterGuid
= InterfaceGuid
;
2003 PlugPlayData
.Buffer
= Buffer
;
2004 PlugPlayData
.BufferSize
= *pulLength
;
2006 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
2007 (PVOID
)&PlugPlayData
,
2008 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
2009 if (NT_SUCCESS(Status
))
2011 *pulLength
= PlugPlayData
.BufferSize
;
2015 ret
= NtStatusToCrError(Status
);
2018 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
2026 PNP_GetInterfaceDeviceListSize(
2028 PNP_RPC_BUFFER_SIZE
*pulLen
,
2029 GUID
*InterfaceGuid
,
2034 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
2035 DWORD ret
= CR_SUCCESS
;
2037 UNREFERENCED_PARAMETER(hBinding
);
2039 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
2041 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2044 PlugPlayData
.FilterGuid
= InterfaceGuid
;
2045 PlugPlayData
.Buffer
= NULL
;
2046 PlugPlayData
.BufferSize
= 0;
2047 PlugPlayData
.Flags
= ulFlags
;
2049 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
2050 (PVOID
)&PlugPlayData
,
2051 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
2052 if (NT_SUCCESS(Status
))
2054 *pulLen
= PlugPlayData
.BufferSize
;
2058 ret
= NtStatusToCrError(Status
);
2061 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
2069 PNP_RegisterDeviceClassAssociation(
2072 GUID
*InterfaceGuid
,
2073 LPWSTR pszReference
,
2075 PNP_RPC_STRING_LEN
*pulLength
,
2076 PNP_RPC_STRING_LEN
*pulTransferLen
,
2080 return CR_CALL_NOT_IMPLEMENTED
;
2087 PNP_UnregisterDeviceClassAssociation(
2089 LPWSTR pszInterfaceDevice
,
2093 return CR_CALL_NOT_IMPLEMENTED
;
2100 PNP_GetClassRegProp(
2102 LPWSTR pszClassGuid
,
2104 DWORD
*pulRegDataType
,
2106 PNP_RPC_STRING_LEN
*pulTransferLen
,
2107 PNP_RPC_STRING_LEN
*pulLength
,
2110 CONFIGRET ret
= CR_SUCCESS
;
2111 LPWSTR lpValueName
= NULL
;
2112 HKEY hInstKey
= NULL
;
2113 HKEY hPropKey
= NULL
;
2116 UNREFERENCED_PARAMETER(hBinding
);
2118 DPRINT("PNP_GetClassRegProp() called\n");
2120 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2122 ret
= CR_INVALID_POINTER
;
2128 ret
= CR_INVALID_FLAG
;
2132 if (*pulLength
< *pulTransferLen
)
2133 *pulLength
= *pulTransferLen
;
2135 *pulTransferLen
= 0;
2139 case CM_CRP_SECURITY
:
2140 lpValueName
= L
"Security";
2143 case CM_CRP_DEVTYPE
:
2144 lpValueName
= L
"DeviceType";
2147 case CM_CRP_EXCLUSIVE
:
2148 lpValueName
= L
"Exclusive";
2151 case CM_CRP_CHARACTERISTICS
:
2152 lpValueName
= L
"DeviceCharacteristics";
2156 ret
= CR_INVALID_PROPERTY
;
2160 DPRINT("Value name: %S\n", lpValueName
);
2162 lError
= RegOpenKeyExW(hClassKey
,
2167 if (lError
!= ERROR_SUCCESS
)
2170 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2174 lError
= RegOpenKeyExW(hInstKey
,
2179 if (lError
!= ERROR_SUCCESS
)
2182 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2186 lError
= RegQueryValueExW(hPropKey
,
2192 if (lError
!= ERROR_SUCCESS
)
2194 if (lError
== ERROR_MORE_DATA
)
2196 ret
= CR_BUFFER_SMALL
;
2201 ret
= CR_NO_SUCH_VALUE
;
2206 if (ret
== CR_SUCCESS
)
2207 *pulTransferLen
= *pulLength
;
2209 if (hPropKey
!= NULL
)
2210 RegCloseKey(hPropKey
);
2212 if (hInstKey
!= NULL
)
2213 RegCloseKey(hInstKey
);
2215 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
2224 PNP_SetClassRegProp(
2226 LPWSTR pszClassGuid
,
2230 PNP_PROP_SIZE ulLength
,
2233 CONFIGRET ret
= CR_SUCCESS
;
2234 LPWSTR lpValueName
= NULL
;
2239 UNREFERENCED_PARAMETER(hBinding
);
2241 DPRINT("PNP_SetClassRegProp() called\n");
2244 return CR_INVALID_FLAG
;
2248 case CM_CRP_SECURITY
:
2249 lpValueName
= L
"Security";
2252 case CM_CRP_DEVTYPE
:
2253 lpValueName
= L
"DeviceType";
2256 case CM_CRP_EXCLUSIVE
:
2257 lpValueName
= L
"Exclusive";
2260 case CM_CRP_CHARACTERISTICS
:
2261 lpValueName
= L
"DeviceCharacteristics";
2265 return CR_INVALID_PROPERTY
;
2268 lError
= RegOpenKeyExW(hClassKey
,
2273 if (lError
!= ERROR_SUCCESS
)
2275 ret
= CR_NO_SUCH_REGISTRY_KEY
;
2279 /* FIXME: Set security descriptor */
2280 lError
= RegCreateKeyExW(hInstKey
,
2284 REG_OPTION_NON_VOLATILE
,
2289 if (lError
!= ERROR_SUCCESS
)
2291 ret
= CR_REGISTRY_ERROR
;
2297 if (RegDeleteValueW(hPropKey
,
2299 ret
= CR_REGISTRY_ERROR
;
2303 if (RegSetValueExW(hPropKey
,
2309 ret
= CR_REGISTRY_ERROR
;
2313 if (hPropKey
!= NULL
)
2314 RegCloseKey(hPropKey
);
2316 if (hInstKey
!= NULL
)
2317 RegCloseKey(hInstKey
);
2324 CreateDeviceInstance(LPWSTR pszDeviceID
)
2326 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
2327 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
2328 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
2329 HKEY hKeyEnumerator
;
2335 /* Split the instance ID */
2336 SplitDeviceInstanceID(pszDeviceID
,
2341 /* Open or create the enumerator key */
2342 lError
= RegCreateKeyExW(hEnumKey
,
2346 REG_OPTION_NON_VOLATILE
,
2351 if (lError
!= ERROR_SUCCESS
)
2353 return CR_REGISTRY_ERROR
;
2356 /* Open or create the device key */
2357 lError
= RegCreateKeyExW(hKeyEnumerator
,
2361 REG_OPTION_NON_VOLATILE
,
2367 /* Close the enumerator key */
2368 RegCloseKey(hKeyEnumerator
);
2370 if (lError
!= ERROR_SUCCESS
)
2372 return CR_REGISTRY_ERROR
;
2375 /* Try to open the instance key and fail if it exists */
2376 lError
= RegOpenKeyExW(hKeyDevice
,
2381 if (lError
== ERROR_SUCCESS
)
2383 DPRINT1("Instance %S already exists!\n", szInstance
);
2384 RegCloseKey(hKeyInstance
);
2385 RegCloseKey(hKeyDevice
);
2386 return CR_ALREADY_SUCH_DEVINST
;
2389 /* Create a new instance key */
2390 lError
= RegCreateKeyExW(hKeyDevice
,
2394 REG_OPTION_NON_VOLATILE
,
2400 /* Close the device key */
2401 RegCloseKey(hKeyDevice
);
2403 if (lError
!= ERROR_SUCCESS
)
2405 return CR_REGISTRY_ERROR
;
2408 /* Create the 'Control' sub key */
2409 lError
= RegCreateKeyExW(hKeyInstance
,
2413 REG_OPTION_NON_VOLATILE
,
2418 if (lError
== ERROR_SUCCESS
)
2420 RegCloseKey(hKeyControl
);
2423 RegCloseKey(hKeyInstance
);
2425 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
2435 LPWSTR pszParentDeviceID
,
2436 PNP_RPC_STRING_LEN ulLength
,
2439 CONFIGRET ret
= CR_SUCCESS
;
2441 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
2443 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
2445 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
2446 DWORD dwInstanceNumber
;
2448 /* Generated ID is: Root\<Device ID>\<Instance number> */
2449 dwInstanceNumber
= 0;
2452 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
2453 pszDeviceID
, dwInstanceNumber
);
2455 /* Try to create a device instance with this ID */
2456 ret
= CreateDeviceInstance(szGeneratedInstance
);
2460 while (ret
== CR_ALREADY_SUCH_DEVINST
);
2462 if (ret
== CR_SUCCESS
)
2464 /* pszDeviceID is an out parameter too for generated IDs */
2465 if (wcslen(szGeneratedInstance
) > ulLength
)
2467 ret
= CR_BUFFER_SMALL
;
2471 wcscpy(pszDeviceID
, szGeneratedInstance
);
2477 /* Create the device instance */
2478 ret
= CreateDeviceInstance(pszDeviceID
);
2481 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
2488 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
2489 LPWSTR pszDeviceInstanceSource
)
2491 DPRINT("MoveDeviceInstance: not implemented\n");
2493 return CR_CALL_NOT_IMPLEMENTED
;
2498 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
2501 DPRINT("SetupDeviceInstance: not implemented\n");
2503 return CR_CALL_NOT_IMPLEMENTED
;
2508 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
2510 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
2511 CONFIGRET ret
= CR_SUCCESS
;
2514 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
2516 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
2517 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
2518 if (!NT_SUCCESS(Status
))
2519 ret
= NtStatusToCrError(Status
);
2526 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
2528 DPRINT("DisableDeviceInstance: not implemented\n");
2530 return CR_CALL_NOT_IMPLEMENTED
;
2535 ReenumerateDeviceInstance(
2536 _In_ LPWSTR pszDeviceInstance
,
2539 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData
;
2540 CONFIGRET ret
= CR_SUCCESS
;
2543 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
2544 pszDeviceInstance
, ulFlags
);
2546 if (ulFlags
& ~CM_REENUMERATE_BITS
)
2547 return CR_INVALID_FLAG
;
2549 if (ulFlags
& CM_REENUMERATE_RETRY_INSTALLATION
)
2551 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
2554 RtlInitUnicodeString(&EnumerateDeviceData
.DeviceInstance
,
2556 EnumerateDeviceData
.Flags
= 0;
2558 Status
= NtPlugPlayControl(PlugPlayControlEnumerateDevice
,
2559 &EnumerateDeviceData
,
2560 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA
));
2561 if (!NT_SUCCESS(Status
))
2562 ret
= NtStatusToCrError(Status
);
2571 PNP_DeviceInstanceAction(
2575 LPWSTR pszDeviceInstance1
,
2576 LPWSTR pszDeviceInstance2
)
2578 CONFIGRET ret
= CR_SUCCESS
;
2580 UNREFERENCED_PARAMETER(hBinding
);
2582 DPRINT("PNP_DeviceInstanceAction() called\n");
2586 case PNP_DEVINST_MOVE
:
2587 ret
= MoveDeviceInstance(pszDeviceInstance1
,
2588 pszDeviceInstance2
);
2591 case PNP_DEVINST_SETUP
:
2592 ret
= SetupDeviceInstance(pszDeviceInstance1
,
2596 case PNP_DEVINST_ENABLE
:
2597 ret
= EnableDeviceInstance(pszDeviceInstance1
);
2600 case PNP_DEVINST_DISABLE
:
2601 ret
= DisableDeviceInstance(pszDeviceInstance1
);
2604 case PNP_DEVINST_REENUMERATE
:
2605 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
,
2610 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2611 ret
= CR_CALL_NOT_IMPLEMENTED
;
2614 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2623 PNP_GetDeviceStatus(
2630 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
2631 CONFIGRET ret
= CR_SUCCESS
;
2634 UNREFERENCED_PARAMETER(hBinding
);
2635 UNREFERENCED_PARAMETER(ulFlags
);
2637 DPRINT("PNP_GetDeviceStatus() called\n");
2639 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2641 PlugPlayData
.Operation
= 0; /* Get status */
2643 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2644 (PVOID
)&PlugPlayData
,
2645 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2646 if (NT_SUCCESS(Status
))
2648 *pulStatus
= PlugPlayData
.DeviceStatus
;
2649 *pulProblem
= PlugPlayData
.DeviceProblem
;
2653 ret
= NtStatusToCrError(Status
);
2656 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2665 PNP_SetDeviceProblem(
2672 return CR_CALL_NOT_IMPLEMENTED
;
2682 PPNP_VETO_TYPE pVetoType
,
2688 return CR_CALL_NOT_IMPLEMENTED
;
2694 PNP_UninstallDevInst(
2700 return CR_CALL_NOT_IMPLEMENTED
;
2705 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2711 lpPtr
= lpDeviceIdList
;
2714 dwLength
= wcslen(lpPtr
);
2715 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2718 lpPtr
+= (dwLength
+ 1);
2726 AppendDeviceId(LPWSTR lpDeviceIdList
,
2727 LPDWORD lpDeviceIdListSize
,
2733 dwLen
= wcslen(lpDeviceId
);
2734 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2736 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2738 dwPos
+= (dwLen
+ 1);
2740 lpDeviceIdList
[dwPos
] = 0;
2742 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2755 CONFIGRET ret
= CR_SUCCESS
;
2758 DWORD dwDeviceIdListSize
;
2759 DWORD dwNewDeviceIdSize
;
2760 WCHAR
* pszDeviceIdList
= NULL
;
2762 UNREFERENCED_PARAMETER(hBinding
);
2764 DPRINT("PNP_AddID() called\n");
2765 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2766 DPRINT(" DeviceId: %S\n", pszID
);
2767 DPRINT(" Flags: %lx\n", ulFlags
);
2769 if (RegOpenKeyExW(hEnumKey
,
2772 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2773 &hDeviceKey
) != ERROR_SUCCESS
)
2775 DPRINT("Failed to open the device key!\n");
2776 return CR_INVALID_DEVNODE
;
2779 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2781 if (RegQueryValueExW(hDeviceKey
,
2786 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2788 DPRINT("Failed to query the desired ID string!\n");
2789 ret
= CR_REGISTRY_ERROR
;
2793 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2794 if (!dwNewDeviceIdSize
)
2796 ret
= CR_INVALID_POINTER
;
2800 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2802 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2803 if (!pszDeviceIdList
)
2805 DPRINT("Failed to allocate memory for the desired ID string!\n");
2806 ret
= CR_OUT_OF_MEMORY
;
2810 if (RegQueryValueExW(hDeviceKey
,
2814 (LPBYTE
)pszDeviceIdList
,
2815 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2817 DPRINT("Failed to query the desired ID string!\n");
2818 ret
= CR_REGISTRY_ERROR
;
2822 /* Check whether the device ID is already in use */
2823 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2825 DPRINT("Device ID was found in the ID string!\n");
2830 /* Append the Device ID */
2831 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2833 if (RegSetValueExW(hDeviceKey
,
2837 (LPBYTE
)pszDeviceIdList
,
2838 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2840 DPRINT("Failed to set the desired ID string!\n");
2841 ret
= CR_REGISTRY_ERROR
;
2845 RegCloseKey(hDeviceKey
);
2846 if (pszDeviceIdList
)
2847 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2849 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2864 return CR_CALL_NOT_IMPLEMENTED
;
2874 PPNP_VETO_TYPE pVetoType
,
2880 return CR_CALL_NOT_IMPLEMENTED
;
2887 PNP_RequestDeviceEject(
2890 PPNP_VETO_TYPE pVetoType
,
2896 return CR_CALL_NOT_IMPLEMENTED
;
2903 PNP_IsDockStationPresent(
2911 CONFIGRET ret
= CR_SUCCESS
;
2913 UNREFERENCED_PARAMETER(hBinding
);
2915 DPRINT1("PNP_IsDockStationPresent() called\n");
2919 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2923 &hKey
) != ERROR_SUCCESS
)
2924 return CR_REGISTRY_ERROR
;
2926 dwSize
= sizeof(DWORD
);
2927 if (RegQueryValueExW(hKey
,
2932 &dwSize
) != ERROR_SUCCESS
)
2933 ret
= CR_REGISTRY_ERROR
;
2937 if (ret
== CR_SUCCESS
)
2939 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2941 ret
= CR_REGISTRY_ERROR
;
2943 else if (dwValue
!= 0)
2949 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2962 return CR_CALL_NOT_IMPLEMENTED
;
2975 PPNP_VETO_TYPE pVetoType
,
2980 CONFIGRET ret
= CR_SUCCESS
;
2981 WCHAR szKeyName
[MAX_PATH
];
2986 UNREFERENCED_PARAMETER(hBinding
);
2988 DPRINT("PNP_HwProfFlags() called\n");
2993 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2998 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
3002 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3006 &hKey
) != ERROR_SUCCESS
)
3007 return CR_REGISTRY_ERROR
;
3009 if (ulAction
== PNP_GET_HWPROFFLAGS
)
3011 if (RegOpenKeyExW(hKey
,
3015 &hDeviceKey
) != ERROR_SUCCESS
)
3021 dwSize
= sizeof(DWORD
);
3022 if (RegQueryValueExW(hDeviceKey
,
3027 &dwSize
) != ERROR_SUCCESS
)
3032 RegCloseKey(hDeviceKey
);
3035 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
3037 /* FIXME: not implemented yet */
3038 ret
= CR_CALL_NOT_IMPLEMENTED
;
3053 HWPROFILEINFO
*pHWProfileInfo
,
3054 DWORD ulProfileInfoSize
,
3057 WCHAR szProfileName
[5];
3058 HKEY hKeyConfig
= NULL
;
3059 HKEY hKeyProfiles
= NULL
;
3060 HKEY hKeyProfile
= NULL
;
3061 DWORD dwDisposition
;
3064 CONFIGRET ret
= CR_SUCCESS
;
3066 UNREFERENCED_PARAMETER(hBinding
);
3068 DPRINT("PNP_GetHwProfInfo() called\n");
3070 if (ulProfileInfoSize
== 0)
3072 ret
= CR_INVALID_DATA
;
3078 ret
= CR_INVALID_FLAG
;
3082 /* Initialize the profile information */
3083 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
3084 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
3085 pHWProfileInfo
->HWPI_dwFlags
= 0;
3087 /* Open the 'IDConfigDB' key */
3088 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
3089 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
3092 REG_OPTION_NON_VOLATILE
,
3097 if (lError
!= ERROR_SUCCESS
)
3099 ret
= CR_REGISTRY_ERROR
;
3103 /* Open the 'Hardware Profiles' subkey */
3104 lError
= RegCreateKeyExW(hKeyConfig
,
3105 L
"Hardware Profiles",
3108 REG_OPTION_NON_VOLATILE
,
3109 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
3113 if (lError
!= ERROR_SUCCESS
)
3115 ret
= CR_REGISTRY_ERROR
;
3119 if (ulIndex
== (ULONG
)-1)
3121 dwSize
= sizeof(ULONG
);
3122 lError
= RegQueryValueExW(hKeyConfig
,
3126 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
3128 if (lError
!= ERROR_SUCCESS
)
3130 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
3131 ret
= CR_REGISTRY_ERROR
;
3137 /* FIXME: not implemented yet */
3138 ret
= CR_CALL_NOT_IMPLEMENTED
;
3142 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
3144 lError
= RegOpenKeyExW(hKeyProfiles
,
3149 if (lError
!= ERROR_SUCCESS
)
3151 ret
= CR_REGISTRY_ERROR
;
3155 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
3156 lError
= RegQueryValueExW(hKeyProfile
,
3160 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
3162 if (lError
!= ERROR_SUCCESS
)
3164 ret
= CR_REGISTRY_ERROR
;
3169 if (hKeyProfile
!= NULL
)
3170 RegCloseKey(hKeyProfile
);
3172 if (hKeyProfiles
!= NULL
)
3173 RegCloseKey(hKeyProfiles
);
3175 if (hKeyConfig
!= NULL
)
3176 RegCloseKey(hKeyConfig
);
3185 PNP_AddEmptyLogConf(
3189 DWORD
*pulLogConfTag
,
3193 return CR_CALL_NOT_IMPLEMENTED
;
3203 DWORD ulLogConfType
,
3208 return CR_CALL_NOT_IMPLEMENTED
;
3215 PNP_GetFirstLogConf(
3218 DWORD ulLogConfType
,
3219 DWORD
*pulLogConfTag
,
3223 return CR_CALL_NOT_IMPLEMENTED
;
3233 DWORD ulLogConfType
,
3239 return CR_CALL_NOT_IMPLEMENTED
;
3246 PNP_GetLogConfPriority(
3255 return CR_CALL_NOT_IMPLEMENTED
;
3266 DWORD ulLogConfType
,
3267 RESOURCEID ResourceID
,
3268 DWORD
*pulResourceTag
,
3270 PNP_RPC_BUFFER_SIZE ResourceLen
,
3274 return CR_CALL_NOT_IMPLEMENTED
;
3285 DWORD ulLogConfType
,
3286 RESOURCEID ResourceID
,
3287 DWORD ulResourceTag
,
3288 DWORD
*pulPreviousResType
,
3289 DWORD
*pulPreviousResTag
,
3293 return CR_CALL_NOT_IMPLEMENTED
;
3304 DWORD ulLogConfType
,
3305 RESOURCEID ResourceID
,
3306 DWORD ulResourceTag
,
3307 DWORD
*pulNextResType
,
3308 DWORD
*pulNextResTag
,
3312 return CR_CALL_NOT_IMPLEMENTED
;
3323 DWORD ulLogConfType
,
3324 RESOURCEID ResourceID
,
3325 DWORD ulResourceTag
,
3327 PNP_RPC_BUFFER_SIZE BufferLen
,
3331 return CR_CALL_NOT_IMPLEMENTED
;
3338 PNP_GetResDesDataSize(
3342 DWORD ulLogConfType
,
3343 RESOURCEID ResourceID
,
3344 DWORD ulResourceTag
,
3349 return CR_CALL_NOT_IMPLEMENTED
;
3360 DWORD ulLogConfType
,
3361 RESOURCEID CurrentResourceID
,
3362 RESOURCEID NewResourceID
,
3363 DWORD ulResourceTag
,
3365 PNP_RPC_BUFFER_SIZE ResourceLen
,
3369 return CR_CALL_NOT_IMPLEMENTED
;
3376 PNP_DetectResourceConflict(
3379 RESOURCEID ResourceID
,
3381 PNP_RPC_BUFFER_SIZE ResourceLen
,
3382 BOOL
*pbConflictDetected
,
3385 DPRINT("PNP_DetectResourceConflict()\n");
3387 if (pbConflictDetected
!= NULL
)
3388 *pbConflictDetected
= FALSE
;
3390 return CR_CALL_NOT_IMPLEMENTED
;
3397 PNP_QueryResConfList(
3400 RESOURCEID ResourceID
,
3402 PNP_RPC_BUFFER_SIZE ResourceLen
,
3404 PNP_RPC_BUFFER_SIZE BufferLen
,
3408 return CR_CALL_NOT_IMPLEMENTED
;
3417 DWORD ulHardwareProfile
,
3421 return CR_CALL_NOT_IMPLEMENTED
;
3428 PNP_QueryArbitratorFreeData(
3433 RESOURCEID ResourceID
,
3437 return CR_CALL_NOT_IMPLEMENTED
;
3444 PNP_QueryArbitratorFreeSize(
3448 RESOURCEID ResourceID
,
3452 return CR_CALL_NOT_IMPLEMENTED
;
3463 return CR_CALL_NOT_IMPLEMENTED
;
3470 PNP_RegisterNotification(
3476 PNOTIFY_DATA pNotifyData
;
3479 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
3480 hBinding
, ulFlags
, pulNotify
);
3483 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
3484 if (pNotifyData
== NULL
)
3485 return CR_OUT_OF_MEMORY
;
3487 *pulNotify
= (DWORD
)pNotifyData
;
3499 PNP_UnregisterNotification(
3503 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
3504 hBinding
, ulNotify
);
3508 return CR_CALL_NOT_IMPLEMENTED
;
3518 PNP_GetCustomDevProp(
3521 LPWSTR CustomPropName
,
3522 DWORD
*pulRegDataType
,
3524 PNP_RPC_STRING_LEN
*pulTransferLen
,
3525 PNP_RPC_STRING_LEN
*pulLength
,
3528 HKEY hDeviceKey
= NULL
;
3529 HKEY hParamKey
= NULL
;
3531 CONFIGRET ret
= CR_SUCCESS
;
3533 UNREFERENCED_PARAMETER(hBinding
);
3535 DPRINT("PNP_GetCustomDevProp() called\n");
3537 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
3539 ret
= CR_INVALID_POINTER
;
3543 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
3545 ret
= CR_INVALID_FLAG
;
3549 if (*pulLength
< *pulTransferLen
)
3550 *pulLength
= *pulTransferLen
;
3552 *pulTransferLen
= 0;
3554 lError
= RegOpenKeyExW(hEnumKey
,
3559 if (lError
!= ERROR_SUCCESS
)
3561 ret
= CR_REGISTRY_ERROR
;
3565 lError
= RegOpenKeyExW(hDeviceKey
,
3566 L
"Device Parameters",
3570 if (lError
!= ERROR_SUCCESS
)
3572 ret
= CR_REGISTRY_ERROR
;
3576 lError
= RegQueryValueExW(hParamKey
,
3582 if (lError
!= ERROR_SUCCESS
)
3584 if (lError
== ERROR_MORE_DATA
)
3586 ret
= CR_BUFFER_SMALL
;
3591 ret
= CR_NO_SUCH_VALUE
;
3596 if (ret
== CR_SUCCESS
)
3597 *pulTransferLen
= *pulLength
;
3599 if (hParamKey
!= NULL
)
3600 RegCloseKey(hParamKey
);
3602 if (hDeviceKey
!= NULL
)
3603 RegCloseKey(hDeviceKey
);
3605 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3614 PNP_GetVersionInternal(
3618 UNREFERENCED_PARAMETER(hBinding
);
3628 PNP_GetBlockedDriverInfo(
3631 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3632 PNP_RPC_BUFFER_SIZE
*pulLength
,
3636 return CR_CALL_NOT_IMPLEMENTED
;
3643 PNP_GetServerSideDeviceInstallFlags(
3645 DWORD
*pulSSDIFlags
,
3648 UNREFERENCED_PARAMETER(hBinding
);
3650 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
3651 hBinding
, pulSSDIFlags
, ulFlags
);
3653 if (pulSSDIFlags
== NULL
)
3654 return CR_INVALID_POINTER
;
3657 return CR_INVALID_FLAG
;
3669 PNP_GetObjectPropKeys(
3673 LPWSTR PropertyCultureName
,
3674 PNP_PROP_COUNT
*PropertyCount
,
3675 PNP_PROP_COUNT
*TransferLen
,
3676 DEVPROPKEY
*PropertyKeys
,
3680 return CR_CALL_NOT_IMPLEMENTED
;
3691 LPWSTR PropertyCultureName
,
3692 const DEVPROPKEY
*PropertyKey
,
3693 DEVPROPTYPE
*PropertyType
,
3694 PNP_PROP_SIZE
*PropertySize
,
3695 PNP_PROP_SIZE
*TransferLen
,
3696 BYTE
*PropertyBuffer
,
3700 return CR_CALL_NOT_IMPLEMENTED
;
3711 LPWSTR PropertyCultureName
,
3712 const DEVPROPKEY
*PropertyKey
,
3713 DEVPROPTYPE PropertyType
,
3714 PNP_PROP_SIZE PropertySize
,
3715 BYTE
*PropertyBuffer
,
3719 return CR_CALL_NOT_IMPLEMENTED
;
3730 return CR_CALL_NOT_IMPLEMENTED
;
3737 PNP_ApplyPowerSettings(
3741 return CR_CALL_NOT_IMPLEMENTED
;
3748 PNP_DriverStoreAddDriverPackage(
3752 return CR_CALL_NOT_IMPLEMENTED
;
3759 PNP_DriverStoreDeleteDriverPackage(
3763 return CR_CALL_NOT_IMPLEMENTED
;
3770 PNP_RegisterServiceNotification(
3774 return CR_CALL_NOT_IMPLEMENTED
;
3781 PNP_SetActiveService(
3787 return CR_CALL_NOT_IMPLEMENTED
;
3794 PNP_DeleteServiceDevices(
3798 return CR_CALL_NOT_IMPLEMENTED
;
3803 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3805 BOOL DeviceInstalled
= FALSE
;
3808 HANDLE hInstallEvent
;
3809 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3810 LPVOID Environment
= NULL
;
3811 PROCESS_INFORMATION ProcessInfo
;
3812 STARTUPINFOW StartupInfo
;
3816 /* The following lengths are constant (see below), they cannot overflow */
3817 WCHAR CommandLine
[116];
3818 WCHAR InstallEventName
[73];
3820 WCHAR UuidString
[39];
3822 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3824 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3826 if (RegOpenKeyExW(hEnumKey
,
3830 &DeviceKey
) == ERROR_SUCCESS
)
3832 if (RegQueryValueExW(DeviceKey
,
3837 NULL
) == ERROR_SUCCESS
)
3839 DPRINT("No need to install: %S\n", DeviceInstance
);
3840 RegCloseKey(DeviceKey
);
3844 BytesWritten
= sizeof(DWORD
);
3845 if (RegQueryValueExW(DeviceKey
,
3850 &BytesWritten
) == ERROR_SUCCESS
)
3852 if (Value
& CONFIGFLAG_FAILEDINSTALL
)
3854 DPRINT("No need to install: %S\n", DeviceInstance
);
3855 RegCloseKey(DeviceKey
);
3860 RegCloseKey(DeviceKey
);
3863 DPRINT1("Installing: %S\n", DeviceInstance
);
3865 /* Create a random UUID for the named pipe & event*/
3866 UuidCreate(&RandomUuid
);
3867 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3868 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3869 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3870 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3871 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3873 /* Create the event */
3874 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3875 wcscat(InstallEventName
, UuidString
);
3876 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3879 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3883 /* Create the named pipe */
3884 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3885 wcscat(PipeName
, UuidString
);
3886 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3887 if (hPipe
== INVALID_HANDLE_VALUE
)
3889 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3893 /* Launch rundll32 to call ClientSideInstallW */
3894 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3895 wcscat(CommandLine
, PipeName
);
3897 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3898 StartupInfo
.cb
= sizeof(StartupInfo
);
3902 /* newdev has to run under the environment of the current user */
3903 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3905 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3909 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3911 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3917 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3919 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3920 (ShowWizard is only set to FALSE for these two modes) */
3921 ASSERT(!ShowWizard
);
3923 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3925 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3930 /* Wait for the function to connect to our pipe */
3931 if (!ConnectNamedPipe(hPipe
, NULL
))
3933 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3935 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3940 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3941 Value
= sizeof(InstallEventName
);
3942 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3943 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3945 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3946 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3947 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3949 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3950 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3951 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3953 /* Wait for newdev.dll to finish processing */
3954 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3956 /* If the event got signalled, this is success */
3957 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3961 CloseHandle(hInstallEvent
);
3963 if (hPipe
!= INVALID_HANDLE_VALUE
)
3967 DestroyEnvironmentBlock(Environment
);
3969 if (ProcessInfo
.hProcess
)
3970 CloseHandle(ProcessInfo
.hProcess
);
3972 if (ProcessInfo
.hThread
)
3973 CloseHandle(ProcessInfo
.hThread
);
3975 if (!DeviceInstalled
)
3977 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3980 return DeviceInstalled
;
3996 return ERROR_INVALID_PARAMETER
;
3999 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
4000 if (rc
!= ERROR_SUCCESS
)
4002 if (dwType
!= REG_SZ
)
4003 return ERROR_FILE_NOT_FOUND
;
4004 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
4006 return ERROR_NOT_ENOUGH_MEMORY
;
4007 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
4008 if (rc
!= ERROR_SUCCESS
)
4010 HeapFree(GetProcessHeap(), 0, Value
);
4013 /* NULL-terminate the string */
4014 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
4017 return ERROR_SUCCESS
;
4025 DWORD regType
, active
, size
;
4029 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
4030 if (rc
!= ERROR_SUCCESS
)
4033 size
= sizeof(DWORD
);
4034 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
4035 if (rc
!= ERROR_SUCCESS
)
4037 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
4040 ret
= (active
!= 0);
4046 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
4055 HKEY ControlKey
= NULL
;
4056 LPWSTR SystemStartOptions
= NULL
;
4057 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
4058 BOOL ConsoleBoot
= FALSE
;
4063 L
"SYSTEM\\CurrentControlSet\\Control",
4068 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
4069 if (rc
!= ERROR_SUCCESS
)
4072 /* Check for CONSOLE switch in SystemStartOptions */
4073 CurrentOption
= SystemStartOptions
;
4074 while (CurrentOption
)
4076 NextOption
= wcschr(CurrentOption
, L
' ');
4078 *NextOption
= L
'\0';
4079 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
4081 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
4085 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
4089 if (ControlKey
!= NULL
)
4090 RegCloseKey(ControlKey
);
4091 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
4096 /* Loop to install all queued devices installations */
4098 DeviceInstallThread(LPVOID lpParameter
)
4100 PSLIST_ENTRY ListEntry
;
4101 DeviceInstallParams
* Params
;
4104 UNREFERENCED_PARAMETER(lpParameter
);
4106 WaitForSingleObject(hInstallEvent
, INFINITE
);
4108 showWizard
= !SetupIsActive() && !IsConsoleBoot();
4112 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
4114 if (ListEntry
== NULL
)
4116 SetEvent(hNoPendingInstalls
);
4117 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
4121 ResetEvent(hNoPendingInstalls
);
4122 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
4123 InstallDevice(Params
->DeviceIds
, showWizard
);
4124 HeapFree(GetProcessHeap(), 0, Params
);
4133 PnpEventThread(LPVOID lpParameter
)
4135 DWORD dwRet
= ERROR_SUCCESS
;
4137 RPC_STATUS RpcStatus
;
4138 PPLUGPLAY_EVENT_BLOCK PnpEvent
, NewPnpEvent
;
4141 UNREFERENCED_PARAMETER(lpParameter
);
4143 PnpEventSize
= 0x1000;
4144 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
4145 if (PnpEvent
== NULL
)
4146 return ERROR_OUTOFMEMORY
;
4150 DPRINT("Calling NtGetPlugPlayEvent()\n");
4152 /* Wait for the next PnP event */
4153 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
4155 /* Resize the buffer for the PnP event if it's too small */
4156 if (Status
== STATUS_BUFFER_TOO_SMALL
)
4158 PnpEventSize
+= 0x400;
4159 NewPnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
4160 if (NewPnpEvent
== NULL
)
4162 dwRet
= ERROR_OUTOFMEMORY
;
4165 PnpEvent
= NewPnpEvent
;
4169 if (!NT_SUCCESS(Status
))
4171 DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status
);
4175 /* Process the PnP event */
4176 DPRINT("Received PnP Event\n");
4177 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
4179 DeviceInstallParams
* Params
;
4181 DWORD DeviceIdLength
;
4183 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4185 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
4188 /* Queue device install (will be dequeued by DeviceInstallThread) */
4189 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
4190 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
4193 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
4194 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
4195 SetEvent(hDeviceInstallListNotEmpty
);
4199 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
4201 // DWORD dwRecipient;
4203 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4205 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
4206 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
4209 // DBT_DEVNODES_CHANGED,
4211 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
4213 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
4215 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4217 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
4219 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4221 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
4223 // DWORD dwRecipient;
4225 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4227 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
4228 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
4231 // DBT_DEVNODES_CHANGED,
4233 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
4235 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
4237 // DWORD dwRecipient;
4239 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4241 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
4242 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
4245 // DBT_DEVNODES_CHANGED,
4247 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
4249 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
4251 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4253 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
4255 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
4259 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
4260 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
4261 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
4262 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
4263 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
4266 /* Dequeue the current PnP event and signal the next one */
4267 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
4270 HeapFree(GetProcessHeap(), 0, PnpEvent
);
4277 UpdateServiceStatus(DWORD dwState
)
4279 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
4280 ServiceStatus
.dwCurrentState
= dwState
;
4281 ServiceStatus
.dwControlsAccepted
= 0;
4282 ServiceStatus
.dwWin32ExitCode
= 0;
4283 ServiceStatus
.dwServiceSpecificExitCode
= 0;
4284 ServiceStatus
.dwCheckPoint
= 0;
4286 if (dwState
== SERVICE_START_PENDING
||
4287 dwState
== SERVICE_STOP_PENDING
||
4288 dwState
== SERVICE_PAUSE_PENDING
||
4289 dwState
== SERVICE_CONTINUE_PENDING
)
4290 ServiceStatus
.dwWaitHint
= 10000;
4292 ServiceStatus
.dwWaitHint
= 0;
4294 SetServiceStatus(ServiceStatusHandle
,
4300 ServiceControlHandler(DWORD dwControl
,
4305 DPRINT1("ServiceControlHandler() called\n");
4309 case SERVICE_CONTROL_STOP
:
4310 DPRINT1(" SERVICE_CONTROL_STOP received\n");
4311 /* Stop listening to RPC Messages */
4312 RpcMgmtStopServerListening(NULL
);
4313 UpdateServiceStatus(SERVICE_STOPPED
);
4314 return ERROR_SUCCESS
;
4316 case SERVICE_CONTROL_PAUSE
:
4317 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
4318 UpdateServiceStatus(SERVICE_PAUSED
);
4319 return ERROR_SUCCESS
;
4321 case SERVICE_CONTROL_CONTINUE
:
4322 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
4323 UpdateServiceStatus(SERVICE_RUNNING
);
4324 return ERROR_SUCCESS
;
4326 case SERVICE_CONTROL_INTERROGATE
:
4327 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
4328 SetServiceStatus(ServiceStatusHandle
,
4330 return ERROR_SUCCESS
;
4332 case SERVICE_CONTROL_SHUTDOWN
:
4333 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
4334 /* Stop listening to RPC Messages */
4335 RpcMgmtStopServerListening(NULL
);
4336 UpdateServiceStatus(SERVICE_STOPPED
);
4337 return ERROR_SUCCESS
;
4340 DPRINT1(" Control %lu received\n", dwControl
);
4341 return ERROR_CALL_NOT_IMPLEMENTED
;
4347 ServiceMain(DWORD argc
, LPTSTR
*argv
)
4352 UNREFERENCED_PARAMETER(argc
);
4353 UNREFERENCED_PARAMETER(argv
);
4355 DPRINT("ServiceMain() called\n");
4357 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
4358 ServiceControlHandler
,
4360 if (!ServiceStatusHandle
)
4362 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
4366 UpdateServiceStatus(SERVICE_START_PENDING
);
4368 hThread
= CreateThread(NULL
,
4374 if (hThread
!= NULL
)
4375 CloseHandle(hThread
);
4377 hThread
= CreateThread(NULL
,
4383 if (hThread
!= NULL
)
4384 CloseHandle(hThread
);
4386 hThread
= CreateThread(NULL
,
4388 DeviceInstallThread
,
4392 if (hThread
!= NULL
)
4393 CloseHandle(hThread
);
4395 UpdateServiceStatus(SERVICE_RUNNING
);
4397 DPRINT("ServiceMain() done\n");
4401 InitializePnPManager(VOID
)
4406 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
4408 /* We need this privilege for using CreateProcessAsUserW */
4409 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
4411 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
4412 if (hInstallEvent
== NULL
)
4414 dwError
= GetLastError();
4415 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
4419 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
4420 if (hDeviceInstallListNotEmpty
== NULL
)
4422 dwError
= GetLastError();
4423 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
4427 hNoPendingInstalls
= CreateEventW(NULL
,
4430 L
"Global\\PnP_No_Pending_Install_Events");
4431 if (hNoPendingInstalls
== NULL
)
4433 dwError
= GetLastError();
4434 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
4438 InitializeSListHead(&DeviceInstallListHead
);
4440 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
4441 L
"System\\CurrentControlSet\\Enum",
4445 if (dwError
!= ERROR_SUCCESS
)
4447 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
4451 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
4452 L
"System\\CurrentControlSet\\Control\\Class",
4456 if (dwError
!= ERROR_SUCCESS
)
4458 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
4462 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
4468 DllMain(HINSTANCE hinstDLL
,
4474 case DLL_PROCESS_ATTACH
:
4475 DisableThreadLibraryCalls(hinstDLL
);
4476 InitializePnPManager();
4479 case DLL_PROCESS_DETACH
: