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: services/umpnpmgr/umpnpmgr.c
23 * PURPOSE: User-mode Plug and Play manager
24 * PROGRAMMER: Eric Kohl
25 * Hervé Poussineau (hpoussin@reactos.org)
26 * Colin Finck (colin@reactos.org)
29 /* INCLUDES *****************************************************************/
31 //#define HAVE_SLIST_ENTRY_IMPLEMENTED
32 #define WIN32_NO_STATUS
34 #define COM_NO_WINDOWS_H
44 #include <umpnpmgr/sysguid.h>
54 /* GLOBALS ******************************************************************/
56 static WCHAR ServiceName
[] = L
"PlugPlay";
58 static SERVICE_STATUS_HANDLE ServiceStatusHandle
;
59 static SERVICE_STATUS ServiceStatus
;
61 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
63 static HKEY hEnumKey
= NULL
;
64 static HKEY hClassKey
= NULL
;
66 static HANDLE hUserToken
= NULL
;
67 static HANDLE hInstallEvent
= NULL
;
68 static HANDLE hNoPendingInstalls
= NULL
;
70 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
71 static SLIST_HEADER DeviceInstallListHead
;
73 static LIST_ENTRY DeviceInstallListHead
;
75 static HANDLE hDeviceInstallListNotEmpty
;
79 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
80 SLIST_ENTRY ListEntry
;
85 } DeviceInstallParams
;
87 /* FUNCTIONS *****************************************************************/
90 RpcServerThread(LPVOID lpParameter
)
93 BOOLEAN RegisteredProtSeq
= FALSE
;
95 UNREFERENCED_PARAMETER(lpParameter
);
97 DPRINT("RpcServerThread() called\n");
100 /* 2k/XP/2k3-compatible protocol sequence/endpoint */
101 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
104 NULL
); // Security descriptor
105 if (Status
== RPC_S_OK
)
106 RegisteredProtSeq
= TRUE
;
108 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
111 /* Vista/7-compatible protocol sequence/endpoint */
112 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
115 NULL
); // Security descriptor
116 if (Status
== RPC_S_OK
)
117 RegisteredProtSeq
= TRUE
;
119 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
121 /* Make sure there's a usable endpoint */
122 if (RegisteredProtSeq
== FALSE
)
125 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
128 if (Status
!= RPC_S_OK
)
130 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
134 Status
= RpcServerListen(1,
137 if (Status
!= RPC_S_OK
)
139 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
143 /* ROS HACK (this should never happen...) */
144 DPRINT1("*** Other devices won't be installed correctly. If something\n");
145 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
147 DPRINT("RpcServerThread() done\n");
153 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
155 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
159 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
161 HeapFree(GetProcessHeap(), 0, ptr
);
165 static CONFIGRET WINAPI
166 NtStatusToCrError(NTSTATUS Status
)
170 case STATUS_NO_SUCH_DEVICE
:
171 return CR_NO_SUCH_DEVINST
;
172 case STATUS_NOT_IMPLEMENTED
:
173 return CR_CALL_NOT_IMPLEMENTED
;
176 /* FIXME: add more mappings */
177 DPRINT1("Unable to map status 0x%08lx\n", Status
);
189 UNREFERENCED_PARAMETER(hBinding
);
200 UNREFERENCED_PARAMETER(hBinding
);
212 UNREFERENCED_PARAMETER(hBinding
);
227 UNREFERENCED_PARAMETER(hBinding
);
228 UNREFERENCED_PARAMETER(ulFlags
);
230 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
241 UNREFERENCED_PARAMETER(hBinding
);
243 DPRINT("PNP_InitDetection() called\n");
256 DWORD ReturnValue
= CR_FAILURE
;
259 UNREFERENCED_PARAMETER(hBinding
);
260 UNREFERENCED_PARAMETER(Admin
);
262 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
264 /* Get the users token */
265 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
269 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
275 CloseHandle(hUserToken
);
279 if (!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
281 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
285 /* Trigger the installer thread */
287 SetEvent(hInstallEvent
);
289 ReturnValue
= CR_SUCCESS
;
293 CloseHandle(hProcess
);
302 PNP_ValidateDeviceInstance(
307 CONFIGRET ret
= CR_SUCCESS
;
308 HKEY hDeviceKey
= NULL
;
310 UNREFERENCED_PARAMETER(hBinding
);
311 UNREFERENCED_PARAMETER(ulFlags
);
313 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
316 if (RegOpenKeyExW(hEnumKey
,
322 DPRINT("Could not open the Device Key!\n");
323 ret
= CR_NO_SUCH_DEVNODE
;
327 /* FIXME: add more tests */
330 if (hDeviceKey
!= NULL
)
331 RegCloseKey(hDeviceKey
);
333 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
342 PNP_GetRootDeviceInstance(
345 PNP_RPC_STRING_LEN ulLength
)
347 CONFIGRET ret
= CR_SUCCESS
;
349 UNREFERENCED_PARAMETER(hBinding
);
351 DPRINT("PNP_GetRootDeviceInstance() called\n");
355 ret
= CR_INVALID_POINTER
;
358 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
360 ret
= CR_BUFFER_SMALL
;
368 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
377 PNP_GetRelatedDeviceInstance(
379 DWORD ulRelationship
,
381 LPWSTR pRelatedDeviceId
,
382 PNP_RPC_STRING_LEN
*pulLength
,
385 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
386 CONFIGRET ret
= CR_SUCCESS
;
389 UNREFERENCED_PARAMETER(hBinding
);
390 UNREFERENCED_PARAMETER(ulFlags
);
392 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
393 DPRINT(" Relationship %ld\n", ulRelationship
);
394 DPRINT(" DeviceId %S\n", pDeviceID
);
396 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
399 PlugPlayData
.Relation
= ulRelationship
;
401 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
402 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
404 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
405 (PVOID
)&PlugPlayData
,
406 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
407 if (!NT_SUCCESS(Status
))
409 ret
= NtStatusToCrError(Status
);
412 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
413 if (ret
== CR_SUCCESS
)
415 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
425 PNP_EnumerateSubKeys(
430 PNP_RPC_STRING_LEN ulLength
,
431 PNP_RPC_STRING_LEN
*pulRequiredLen
,
434 CONFIGRET ret
= CR_SUCCESS
;
438 UNREFERENCED_PARAMETER(hBinding
);
439 UNREFERENCED_PARAMETER(ulFlags
);
441 DPRINT("PNP_EnumerateSubKeys() called\n");
445 case PNP_ENUMERATOR_SUBKEYS
:
449 case PNP_CLASS_SUBKEYS
:
457 *pulRequiredLen
= ulLength
;
458 dwError
= RegEnumKeyExW(hKey
,
466 if (dwError
!= ERROR_SUCCESS
)
468 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
475 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
488 PNP_RPC_STRING_LEN
*pulLength
,
492 return CR_CALL_NOT_IMPLEMENTED
;
499 PNP_GetDeviceListSize(
502 PNP_RPC_BUFFER_SIZE
*pulLen
,
506 return CR_CALL_NOT_IMPLEMENTED
;
519 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
520 CONFIGRET ret
= CR_SUCCESS
;
523 UNREFERENCED_PARAMETER(hBinding
);
524 UNREFERENCED_PARAMETER(ulFlags
);
526 DPRINT("PNP_GetDepth() called\n");
528 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
531 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
532 (PVOID
)&PlugPlayData
,
533 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
534 if (NT_SUCCESS(Status
))
536 *pulDepth
= PlugPlayData
.Depth
;
540 ret
= NtStatusToCrError(Status
);
543 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
552 PNP_GetDeviceRegProp(
556 DWORD
*pulRegDataType
,
558 PNP_PROP_SIZE
*pulTransferLen
,
559 PNP_PROP_SIZE
*pulLength
,
562 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
563 CONFIGRET ret
= CR_SUCCESS
;
564 LPWSTR lpValueName
= NULL
;
569 UNREFERENCED_PARAMETER(hBinding
);
571 DPRINT("PNP_GetDeviceRegProp() called\n");
573 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
575 ret
= CR_INVALID_POINTER
;
581 ret
= CR_INVALID_FLAG
;
585 /* FIXME: Check pDeviceID */
587 if (*pulLength
< *pulTransferLen
)
588 *pulLength
= *pulTransferLen
;
594 case CM_DRP_DEVICEDESC
:
595 lpValueName
= L
"DeviceDesc";
598 case CM_DRP_HARDWAREID
:
599 lpValueName
= L
"HardwareID";
602 case CM_DRP_COMPATIBLEIDS
:
603 lpValueName
= L
"CompatibleIDs";
607 lpValueName
= L
"Service";
611 lpValueName
= L
"Class";
614 case CM_DRP_CLASSGUID
:
615 lpValueName
= L
"ClassGUID";
619 lpValueName
= L
"Driver";
622 case CM_DRP_CONFIGFLAGS
:
623 lpValueName
= L
"ConfigFlags";
627 lpValueName
= L
"Mfg";
630 case CM_DRP_FRIENDLYNAME
:
631 lpValueName
= L
"FriendlyName";
634 case CM_DRP_LOCATION_INFORMATION
:
635 lpValueName
= L
"LocationInformation";
638 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
642 case CM_DRP_CAPABILITIES
:
643 lpValueName
= L
"Capabilities";
646 case CM_DRP_UI_NUMBER
:
650 case CM_DRP_UPPERFILTERS
:
651 lpValueName
= L
"UpperFilters";
654 case CM_DRP_LOWERFILTERS
:
655 lpValueName
= L
"LowerFilters";
658 case CM_DRP_BUSTYPEGUID
:
662 case CM_DRP_LEGACYBUSTYPE
:
666 case CM_DRP_BUSNUMBER
:
670 case CM_DRP_ENUMERATOR_NAME
:
674 case CM_DRP_SECURITY
:
675 lpValueName
= L
"Security";
679 lpValueName
= L
"DeviceType";
682 case CM_DRP_EXCLUSIVE
:
683 lpValueName
= L
"Exclusive";
686 case CM_DRP_CHARACTERISTICS
:
687 lpValueName
= L
"DeviceCharacteristics";
694 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
695 lpValueName
= L
"UINumberDescFormat";
698 case CM_DRP_DEVICE_POWER_DATA
:
702 case CM_DRP_REMOVAL_POLICY
:
706 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
710 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
711 lpValueName
= L
"RemovalPolicy";
714 case CM_DRP_INSTALL_STATE
:
718 #if (WINVER >= _WIN32_WINNT_WS03)
719 case CM_DRP_LOCATION_PATHS
:
724 #if (WINVER >= _WIN32_WINNT_WIN7)
725 case CM_DRP_BASE_CONTAINERID
:
731 ret
= CR_INVALID_PROPERTY
;
735 DPRINT("Value name: %S\n", lpValueName
);
739 /* Retrieve information from the Registry */
740 lError
= RegOpenKeyExW(hEnumKey
,
745 if (lError
!= ERROR_SUCCESS
)
749 ret
= CR_INVALID_DEVNODE
;
753 lError
= RegQueryValueExW(hKey
,
759 if (lError
!= ERROR_SUCCESS
)
761 if (lError
== ERROR_MORE_DATA
)
763 ret
= CR_BUFFER_SMALL
;
768 ret
= CR_NO_SUCH_VALUE
;
774 /* Retrieve information from the Device Node */
775 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
777 PlugPlayData
.Buffer
= Buffer
;
778 PlugPlayData
.BufferSize
= *pulLength
;
782 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
783 PlugPlayData
.Property
= 0xb; // DevicePropertyPhysicalDeviceObjectName;
786 case CM_DRP_UI_NUMBER
:
787 PlugPlayData
.Property
= 0x11; // DevicePropertyUINumber;
790 case CM_DRP_BUSTYPEGUID
:
791 PlugPlayData
.Property
= 0xc; // DevicePropertyBusTypeGuid;
794 case CM_DRP_LEGACYBUSTYPE
:
795 PlugPlayData
.Property
= 0xd; // DevicePropertyLegacyBusType;
798 case CM_DRP_BUSNUMBER
:
799 PlugPlayData
.Property
= 0xe; // DevicePropertyBusNumber;
802 case CM_DRP_ENUMERATOR_NAME
:
803 PlugPlayData
.Property
= 0xf; // DevicePropertyEnumeratorName;
807 PlugPlayData
.Property
= 0x10; // DevicePropertyAddress;
811 /* FIXME: This property is not supported by IoGetDeviceProperty */
812 case CM_DRP_DEVICE_POWER_DATA
:
815 case CM_DRP_REMOVAL_POLICY
:
816 PlugPlayData
.Property
= 0x12; // DevicePropertyRemovalPolicy
820 /* FIXME: This property is not supported by IoGetDeviceProperty */
821 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
824 case CM_DRP_INSTALL_STATE
:
825 PlugPlayData
.Property
= 0x12; // DevicePropertyInstallState;
829 /* FIXME: This property is not supported by IoGetDeviceProperty */
830 #if (WINVER >= _WIN32_WINNT_WS03)
831 case CM_DRP_LOCATION_PATHS
:
835 #if (WINVER >= _WIN32_WINNT_WIN7)
836 case CM_DRP_BASE_CONTAINERID
:
837 PlugPlayData
.Property
= 0x16; // DevicePropertyContainerID;
842 return CR_INVALID_PROPERTY
;
845 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
846 (PVOID
)&PlugPlayData
,
847 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
848 if (NT_SUCCESS(Status
))
850 *pulLength
= PlugPlayData
.BufferSize
;
854 ret
= NtStatusToCrError(Status
);
859 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
864 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
873 PNP_SetDeviceRegProp(
879 PNP_PROP_SIZE ulLength
,
882 CONFIGRET ret
= CR_SUCCESS
;
883 LPWSTR lpValueName
= NULL
;
886 UNREFERENCED_PARAMETER(hBinding
);
887 UNREFERENCED_PARAMETER(ulFlags
);
889 DPRINT("PNP_SetDeviceRegProp() called\n");
891 DPRINT("DeviceId: %S\n", pDeviceId
);
892 DPRINT("Property: %lu\n", ulProperty
);
893 DPRINT("DataType: %lu\n", ulDataType
);
894 DPRINT("Length: %lu\n", ulLength
);
898 case CM_DRP_DEVICEDESC
:
899 lpValueName
= L
"DeviceDesc";
902 case CM_DRP_HARDWAREID
:
903 lpValueName
= L
"HardwareID";
906 case CM_DRP_COMPATIBLEIDS
:
907 lpValueName
= L
"CompatibleIDs";
911 lpValueName
= L
"Service";
915 lpValueName
= L
"Class";
918 case CM_DRP_CLASSGUID
:
919 lpValueName
= L
"ClassGUID";
923 lpValueName
= L
"Driver";
926 case CM_DRP_CONFIGFLAGS
:
927 lpValueName
= L
"ConfigFlags";
931 lpValueName
= L
"Mfg";
934 case CM_DRP_FRIENDLYNAME
:
935 lpValueName
= L
"FriendlyName";
938 case CM_DRP_LOCATION_INFORMATION
:
939 lpValueName
= L
"LocationInformation";
942 case CM_DRP_UPPERFILTERS
:
943 lpValueName
= L
"UpperFilters";
946 case CM_DRP_LOWERFILTERS
:
947 lpValueName
= L
"LowerFilters";
950 case CM_DRP_SECURITY
:
951 lpValueName
= L
"Security";
955 lpValueName
= L
"DeviceType";
958 case CM_DRP_EXCLUSIVE
:
959 lpValueName
= L
"Exclusive";
962 case CM_DRP_CHARACTERISTICS
:
963 lpValueName
= L
"DeviceCharacteristics";
966 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
967 lpValueName
= L
"UINumberDescFormat";
970 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
971 lpValueName
= L
"RemovalPolicy";
975 return CR_INVALID_PROPERTY
;
978 DPRINT("Value name: %S\n", lpValueName
);
980 if (RegOpenKeyExW(hEnumKey
,
985 return CR_INVALID_DEVNODE
;
989 if (RegDeleteValueW(hKey
,
991 ret
= CR_REGISTRY_ERROR
;
995 if (RegSetValueExW(hKey
,
1001 ret
= CR_REGISTRY_ERROR
;
1006 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1015 PNP_GetClassInstance(
1018 LPWSTR pszClassInstance
,
1019 PNP_RPC_STRING_LEN ulLength
)
1022 return CR_CALL_NOT_IMPLEMENTED
;
1037 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1046 return CR_REGISTRY_ERROR
;
1048 /* FIXME: Set security key */
1059 PNP_DeleteRegistryKey(
1062 LPWSTR pszParentKey
,
1067 return CR_CALL_NOT_IMPLEMENTED
;
1076 DWORD
*pulClassCount
,
1082 UNREFERENCED_PARAMETER(hBinding
);
1083 UNREFERENCED_PARAMETER(ulFlags
);
1085 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1090 if (dwError
!= ERROR_SUCCESS
)
1091 return CR_INVALID_DATA
;
1093 dwError
= RegQueryInfoKeyW(hKey
,
1106 if (dwError
!= ERROR_SUCCESS
)
1107 return CR_INVALID_DATA
;
1118 LPWSTR pszClassGuid
,
1120 PNP_RPC_STRING_LEN
*pulLength
,
1123 WCHAR szKeyName
[MAX_PATH
];
1124 CONFIGRET ret
= CR_SUCCESS
;
1128 UNREFERENCED_PARAMETER(hBinding
);
1129 UNREFERENCED_PARAMETER(ulFlags
);
1131 DPRINT("PNP_GetClassName() called\n");
1133 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1134 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1135 lstrcatW(szKeyName
, pszClassGuid
);
1137 return CR_INVALID_DATA
;
1139 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1144 return CR_REGISTRY_ERROR
;
1146 dwSize
= *pulLength
* sizeof(WCHAR
);
1147 if (RegQueryValueExW(hKey
,
1155 ret
= CR_REGISTRY_ERROR
;
1159 *pulLength
= dwSize
/ sizeof(WCHAR
);
1164 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1175 LPWSTR pszClassGuid
,
1178 CONFIGRET ret
= CR_SUCCESS
;
1180 UNREFERENCED_PARAMETER(hBinding
);
1182 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1184 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1186 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1187 ret
= CR_REGISTRY_ERROR
;
1191 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1192 ret
= CR_REGISTRY_ERROR
;
1195 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1204 PNP_GetInterfaceDeviceAlias(
1206 LPWSTR pszInterfaceDevice
,
1207 GUID
*AliasInterfaceGuid
,
1208 LPWSTR pszAliasInterfaceDevice
,
1209 PNP_RPC_STRING_LEN
*pulLength
,
1210 PNP_RPC_STRING_LEN
*pulTransferLen
,
1214 return CR_CALL_NOT_IMPLEMENTED
;
1221 PNP_GetInterfaceDeviceList(
1223 GUID
*InterfaceGuid
,
1226 PNP_RPC_BUFFER_SIZE
*pulLength
,
1230 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1231 DWORD ret
= CR_SUCCESS
;
1233 UNREFERENCED_PARAMETER(hBinding
);
1235 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1238 PlugPlayData
.Flags
= ulFlags
;
1239 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1240 PlugPlayData
.Buffer
= Buffer
;
1241 PlugPlayData
.BufferSize
= *pulLength
;
1243 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1244 (PVOID
)&PlugPlayData
,
1245 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1246 if (NT_SUCCESS(Status
))
1248 *pulLength
= PlugPlayData
.BufferSize
;
1252 ret
= NtStatusToCrError(Status
);
1255 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1263 PNP_GetInterfaceDeviceListSize(
1265 PNP_RPC_BUFFER_SIZE
*pulLen
,
1266 GUID
*InterfaceGuid
,
1271 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1272 DWORD ret
= CR_SUCCESS
;
1274 UNREFERENCED_PARAMETER(hBinding
);
1276 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1278 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1281 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1282 PlugPlayData
.Buffer
= NULL
;
1283 PlugPlayData
.BufferSize
= 0;
1284 PlugPlayData
.Flags
= ulFlags
;
1286 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1287 (PVOID
)&PlugPlayData
,
1288 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1289 if (NT_SUCCESS(Status
))
1291 *pulLen
= PlugPlayData
.BufferSize
;
1295 ret
= NtStatusToCrError(Status
);
1298 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1306 PNP_RegisterDeviceClassAssociation(
1309 GUID
*InterfaceGuid
,
1310 LPWSTR pszReference
,
1312 PNP_RPC_STRING_LEN
*pulLength
,
1313 PNP_RPC_STRING_LEN
*pulTransferLen
,
1317 return CR_CALL_NOT_IMPLEMENTED
;
1324 PNP_UnregisterDeviceClassAssociation(
1326 LPWSTR pszInterfaceDevice
,
1330 return CR_CALL_NOT_IMPLEMENTED
;
1337 PNP_GetClassRegProp(
1339 LPWSTR pszClassGuid
,
1341 DWORD
*pulRegDataType
,
1343 PNP_RPC_STRING_LEN
*pulTransferLen
,
1344 PNP_RPC_STRING_LEN
*pulLength
,
1347 CONFIGRET ret
= CR_SUCCESS
;
1348 LPWSTR lpValueName
= NULL
;
1349 HKEY hInstKey
= NULL
;
1350 HKEY hPropKey
= NULL
;
1353 UNREFERENCED_PARAMETER(hBinding
);
1355 DPRINT("PNP_GetClassRegProp() called\n");
1357 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1359 ret
= CR_INVALID_POINTER
;
1365 ret
= CR_INVALID_FLAG
;
1369 if (*pulLength
< *pulTransferLen
)
1370 *pulLength
= *pulTransferLen
;
1372 *pulTransferLen
= 0;
1376 case CM_CRP_SECURITY
:
1377 lpValueName
= L
"Security";
1380 case CM_CRP_DEVTYPE
:
1381 lpValueName
= L
"DeviceType";
1384 case CM_CRP_EXCLUSIVE
:
1385 lpValueName
= L
"Exclusive";
1388 case CM_CRP_CHARACTERISTICS
:
1389 lpValueName
= L
"DeviceCharacteristics";
1393 ret
= CR_INVALID_PROPERTY
;
1397 DPRINT("Value name: %S\n", lpValueName
);
1399 lError
= RegOpenKeyExW(hClassKey
,
1404 if (lError
!= ERROR_SUCCESS
)
1407 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1411 lError
= RegOpenKeyExW(hInstKey
,
1416 if (lError
!= ERROR_SUCCESS
)
1419 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1423 lError
= RegQueryValueExW(hPropKey
,
1429 if (lError
!= ERROR_SUCCESS
)
1431 if (lError
== ERROR_MORE_DATA
)
1433 ret
= CR_BUFFER_SMALL
;
1438 ret
= CR_NO_SUCH_VALUE
;
1443 if (ret
== CR_SUCCESS
)
1444 *pulTransferLen
= *pulLength
;
1446 if (hPropKey
!= NULL
)
1447 RegCloseKey(hPropKey
);
1449 if (hInstKey
!= NULL
)
1450 RegCloseKey(hInstKey
);
1452 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1461 PNP_SetClassRegProp(
1463 LPWSTR pszClassGuid
,
1467 PNP_PROP_SIZE ulLength
,
1470 CONFIGRET ret
= CR_SUCCESS
;
1471 LPWSTR lpValueName
= NULL
;
1476 UNREFERENCED_PARAMETER(hBinding
);
1478 DPRINT("PNP_SetClassRegProp() called\n");
1481 return CR_INVALID_FLAG
;
1485 case CM_CRP_SECURITY
:
1486 lpValueName
= L
"Security";
1489 case CM_CRP_DEVTYPE
:
1490 lpValueName
= L
"DeviceType";
1493 case CM_CRP_EXCLUSIVE
:
1494 lpValueName
= L
"Exclusive";
1497 case CM_CRP_CHARACTERISTICS
:
1498 lpValueName
= L
"DeviceCharacteristics";
1502 return CR_INVALID_PROPERTY
;
1505 lError
= RegOpenKeyExW(hClassKey
,
1510 if (lError
!= ERROR_SUCCESS
)
1512 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1516 /* FIXME: Set security descriptor */
1517 lError
= RegCreateKeyExW(hInstKey
,
1521 REG_OPTION_NON_VOLATILE
,
1526 if (lError
!= ERROR_SUCCESS
)
1528 ret
= CR_REGISTRY_ERROR
;
1534 if (RegDeleteValueW(hPropKey
,
1536 ret
= CR_REGISTRY_ERROR
;
1540 if (RegSetValueExW(hPropKey
,
1546 ret
= CR_REGISTRY_ERROR
;
1550 if (hPropKey
!= NULL
)
1551 RegCloseKey(hPropKey
);
1553 if (hInstKey
!= NULL
)
1554 RegCloseKey(hInstKey
);
1561 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1562 OUT LPWSTR pszEnumerator
,
1563 OUT LPWSTR pszDevice
,
1564 OUT LPWSTR pszInstance
)
1566 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1567 LPWSTR lpEnumerator
= NULL
;
1568 LPWSTR lpDevice
= NULL
;
1569 LPWSTR lpInstance
= NULL
;
1572 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1578 lpEnumerator
= szLocalDeviceInstanceID
;
1580 ptr
= wcschr(lpEnumerator
, L
'\\');
1586 ptr
= wcschr(lpDevice
, L
'\\');
1594 if (lpEnumerator
!= NULL
)
1595 wcscpy(pszEnumerator
, lpEnumerator
);
1597 if (lpDevice
!= NULL
)
1598 wcscpy(pszDevice
, lpDevice
);
1600 if (lpInstance
!= NULL
)
1601 wcscpy(pszInstance
, lpInstance
);
1606 CreateDeviceInstance(LPWSTR pszDeviceID
)
1608 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1609 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1610 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1611 HKEY hKeyEnumerator
;
1617 /* Split the instance ID */
1618 SplitDeviceInstanceID(pszDeviceID
,
1623 /* Open or create the enumerator key */
1624 lError
= RegCreateKeyExW(hEnumKey
,
1628 REG_OPTION_NON_VOLATILE
,
1633 if (lError
!= ERROR_SUCCESS
)
1635 return CR_REGISTRY_ERROR
;
1638 /* Open or create the device key */
1639 lError
= RegCreateKeyExW(hKeyEnumerator
,
1643 REG_OPTION_NON_VOLATILE
,
1649 /* Close the enumerator key */
1650 RegCloseKey(hKeyEnumerator
);
1652 if (lError
!= ERROR_SUCCESS
)
1654 return CR_REGISTRY_ERROR
;
1657 /* Try to open the instance key and fail if it exists */
1658 lError
= RegOpenKeyExW(hKeyDevice
,
1663 if (lError
== ERROR_SUCCESS
)
1665 DPRINT1("Instance %S already exists!\n", szInstance
);
1666 RegCloseKey(hKeyInstance
);
1667 RegCloseKey(hKeyDevice
);
1668 return CR_ALREADY_SUCH_DEVINST
;
1671 /* Create a new instance key */
1672 lError
= RegCreateKeyExW(hKeyDevice
,
1676 REG_OPTION_NON_VOLATILE
,
1682 /* Close the device key */
1683 RegCloseKey(hKeyDevice
);
1685 if (lError
!= ERROR_SUCCESS
)
1687 return CR_REGISTRY_ERROR
;
1690 /* Create the 'Control' sub key */
1691 lError
= RegCreateKeyExW(hKeyInstance
,
1695 REG_OPTION_NON_VOLATILE
,
1700 if (lError
== ERROR_SUCCESS
)
1702 RegCloseKey(hKeyControl
);
1705 RegCloseKey(hKeyInstance
);
1707 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1717 LPWSTR pszParentDeviceID
,
1718 PNP_RPC_STRING_LEN ulLength
,
1721 CONFIGRET ret
= CR_SUCCESS
;
1723 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1725 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1727 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1728 DWORD dwInstanceNumber
;
1730 /* Generated ID is: Root\<Device ID>\<Instance number> */
1731 dwInstanceNumber
= 0;
1734 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1735 pszDeviceID
, dwInstanceNumber
);
1737 /* Try to create a device instance with this ID */
1738 ret
= CreateDeviceInstance(szGeneratedInstance
);
1742 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1744 if (ret
== CR_SUCCESS
)
1746 /* pszDeviceID is an out parameter too for generated IDs */
1747 if (wcslen(szGeneratedInstance
) > ulLength
)
1749 ret
= CR_BUFFER_SMALL
;
1753 wcscpy(pszDeviceID
, szGeneratedInstance
);
1759 /* Create the device instance */
1760 ret
= CreateDeviceInstance(pszDeviceID
);
1763 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1770 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1771 LPWSTR pszDeviceInstanceSource
)
1773 DPRINT("MoveDeviceInstance: not implemented\n");
1775 return CR_CALL_NOT_IMPLEMENTED
;
1780 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1783 DPRINT("SetupDeviceInstance: not implemented\n");
1785 return CR_CALL_NOT_IMPLEMENTED
;
1790 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1792 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1793 CONFIGRET ret
= CR_SUCCESS
;
1796 DPRINT("Enable device instance\n");
1798 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1799 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1800 if (!NT_SUCCESS(Status
))
1801 ret
= NtStatusToCrError(Status
);
1808 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1810 DPRINT("DisableDeviceInstance: not implemented\n");
1812 return CR_CALL_NOT_IMPLEMENTED
;
1817 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1819 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1821 return CR_CALL_NOT_IMPLEMENTED
;
1828 PNP_DeviceInstanceAction(
1832 LPWSTR pszDeviceInstance1
,
1833 LPWSTR pszDeviceInstance2
)
1835 CONFIGRET ret
= CR_SUCCESS
;
1837 UNREFERENCED_PARAMETER(hBinding
);
1839 DPRINT("PNP_DeviceInstanceAction() called\n");
1843 case PNP_DEVINST_MOVE
:
1844 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1845 pszDeviceInstance2
);
1848 case PNP_DEVINST_SETUP
:
1849 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1853 case PNP_DEVINST_ENABLE
:
1854 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1857 case PNP_DEVINST_DISABLE
:
1858 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1861 case PNP_DEVINST_REENUMERATE
:
1862 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
1866 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
1867 ret
= CR_CALL_NOT_IMPLEMENTED
;
1870 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1879 PNP_GetDeviceStatus(
1886 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1887 CONFIGRET ret
= CR_SUCCESS
;
1890 UNREFERENCED_PARAMETER(hBinding
);
1891 UNREFERENCED_PARAMETER(ulFlags
);
1893 DPRINT("PNP_GetDeviceStatus() called\n");
1895 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1897 PlugPlayData
.Operation
= 0; /* Get status */
1899 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1900 (PVOID
)&PlugPlayData
,
1901 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1902 if (NT_SUCCESS(Status
))
1904 *pulStatus
= PlugPlayData
.DeviceStatus
;
1905 *pulProblem
= PlugPlayData
.DeviceProblem
;
1909 ret
= NtStatusToCrError(Status
);
1912 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1921 PNP_SetDeviceProblem(
1928 return CR_CALL_NOT_IMPLEMENTED
;
1938 PPNP_VETO_TYPE pVetoType
,
1944 return CR_CALL_NOT_IMPLEMENTED
;
1950 PNP_UninstallDevInst(
1956 return CR_CALL_NOT_IMPLEMENTED
;
1961 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1967 lpPtr
= lpDeviceIdList
;
1970 dwLength
= wcslen(lpPtr
);
1971 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1974 lpPtr
+= (dwLength
+ 1);
1982 AppendDeviceId(LPWSTR lpDeviceIdList
,
1983 LPDWORD lpDeviceIdListSize
,
1989 dwLen
= wcslen(lpDeviceId
);
1990 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1992 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1994 dwPos
+= (dwLen
+ 1);
1996 lpDeviceIdList
[dwPos
] = 0;
1998 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2011 CONFIGRET ret
= CR_SUCCESS
;
2014 DWORD dwDeviceIdListSize
;
2015 DWORD dwNewDeviceIdSize
;
2016 WCHAR
* pszDeviceIdList
= NULL
;
2018 UNREFERENCED_PARAMETER(hBinding
);
2020 DPRINT("PNP_AddID() called\n");
2021 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2022 DPRINT(" DeviceId: %S\n", pszID
);
2023 DPRINT(" Flags: %lx\n", ulFlags
);
2025 if (RegOpenKeyExW(hEnumKey
,
2028 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2029 &hDeviceKey
) != ERROR_SUCCESS
)
2031 DPRINT("Failed to open the device key!\n");
2032 return CR_INVALID_DEVNODE
;
2035 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2037 if (RegQueryValueExW(hDeviceKey
,
2042 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2044 DPRINT("Failed to query the desired ID string!\n");
2045 ret
= CR_REGISTRY_ERROR
;
2049 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2050 if (!dwNewDeviceIdSize
)
2052 ret
= CR_INVALID_POINTER
;
2056 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2058 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2059 if (!pszDeviceIdList
)
2061 DPRINT("Failed to allocate memory for the desired ID string!\n");
2062 ret
= CR_OUT_OF_MEMORY
;
2066 if (RegQueryValueExW(hDeviceKey
,
2070 (LPBYTE
)pszDeviceIdList
,
2071 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2073 DPRINT("Failed to query the desired ID string!\n");
2074 ret
= CR_REGISTRY_ERROR
;
2078 /* Check whether the device ID is already in use */
2079 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2081 DPRINT("Device ID was found in the ID string!\n");
2086 /* Append the Device ID */
2087 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2089 if (RegSetValueExW(hDeviceKey
,
2093 (LPBYTE
)pszDeviceIdList
,
2094 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2096 DPRINT("Failed to set the desired ID string!\n");
2097 ret
= CR_REGISTRY_ERROR
;
2101 RegCloseKey(hDeviceKey
);
2102 if (pszDeviceIdList
)
2103 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2105 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2120 return CR_CALL_NOT_IMPLEMENTED
;
2130 PPNP_VETO_TYPE pVetoType
,
2136 return CR_CALL_NOT_IMPLEMENTED
;
2143 PNP_RequestDeviceEject(
2146 PPNP_VETO_TYPE pVetoType
,
2152 return CR_CALL_NOT_IMPLEMENTED
;
2159 PNP_IsDockStationPresent(
2167 CONFIGRET ret
= CR_SUCCESS
;
2169 UNREFERENCED_PARAMETER(hBinding
);
2171 DPRINT1("PNP_IsDockStationPresent() called\n");
2175 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2179 &hKey
) != ERROR_SUCCESS
)
2180 return CR_REGISTRY_ERROR
;
2182 dwSize
= sizeof(DWORD
);
2183 if (RegQueryValueExW(hKey
,
2188 &dwSize
) != ERROR_SUCCESS
)
2189 ret
= CR_REGISTRY_ERROR
;
2193 if (ret
== CR_SUCCESS
)
2195 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2197 ret
= CR_REGISTRY_ERROR
;
2199 else if (dwValue
!= 0)
2205 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2218 return CR_CALL_NOT_IMPLEMENTED
;
2231 PPNP_VETO_TYPE pVetoType
,
2236 CONFIGRET ret
= CR_SUCCESS
;
2237 WCHAR szKeyName
[MAX_PATH
];
2242 UNREFERENCED_PARAMETER(hBinding
);
2244 DPRINT("PNP_HwProfFlags() called\n");
2249 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2254 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2258 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2262 &hKey
) != ERROR_SUCCESS
)
2263 return CR_REGISTRY_ERROR
;
2265 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2267 if (RegOpenKeyExW(hKey
,
2271 &hDeviceKey
) != ERROR_SUCCESS
)
2277 dwSize
= sizeof(DWORD
);
2278 if (!RegQueryValueExW(hDeviceKey
,
2283 &dwSize
) != ERROR_SUCCESS
)
2288 RegCloseKey(hDeviceKey
);
2291 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2293 /* FIXME: not implemented yet */
2294 ret
= CR_CALL_NOT_IMPLEMENTED
;
2309 HWPROFILEINFO
*pHWProfileInfo
,
2310 DWORD ulProfileInfoSize
,
2313 WCHAR szProfileName
[5];
2314 HKEY hKeyConfig
= NULL
;
2315 HKEY hKeyProfiles
= NULL
;
2316 HKEY hKeyProfile
= NULL
;
2317 DWORD dwDisposition
;
2320 CONFIGRET ret
= CR_SUCCESS
;
2322 UNREFERENCED_PARAMETER(hBinding
);
2324 DPRINT("PNP_GetHwProfInfo() called\n");
2326 if (ulProfileInfoSize
== 0)
2328 ret
= CR_INVALID_DATA
;
2334 ret
= CR_INVALID_FLAG
;
2338 /* Initialize the profile information */
2339 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2340 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2341 pHWProfileInfo
->HWPI_dwFlags
= 0;
2343 /* Open the 'IDConfigDB' key */
2344 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2345 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2348 REG_OPTION_NON_VOLATILE
,
2353 if (lError
!= ERROR_SUCCESS
)
2355 ret
= CR_REGISTRY_ERROR
;
2359 /* Open the 'Hardware Profiles' subkey */
2360 lError
= RegCreateKeyExW(hKeyConfig
,
2361 L
"Hardware Profiles",
2364 REG_OPTION_NON_VOLATILE
,
2365 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2369 if (lError
!= ERROR_SUCCESS
)
2371 ret
= CR_REGISTRY_ERROR
;
2375 if (ulIndex
== (ULONG
)-1)
2377 dwSize
= sizeof(ULONG
);
2378 lError
= RegQueryValueExW(hKeyConfig
,
2382 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2384 if (lError
!= ERROR_SUCCESS
)
2386 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2387 ret
= CR_REGISTRY_ERROR
;
2393 /* FIXME: not implemented yet */
2394 ret
= CR_CALL_NOT_IMPLEMENTED
;
2398 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2400 lError
= RegOpenKeyExW(hKeyProfiles
,
2405 if (lError
!= ERROR_SUCCESS
)
2407 ret
= CR_REGISTRY_ERROR
;
2411 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2412 lError
= RegQueryValueExW(hKeyProfile
,
2416 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2418 if (lError
!= ERROR_SUCCESS
)
2420 ret
= CR_REGISTRY_ERROR
;
2425 if (hKeyProfile
!= NULL
)
2426 RegCloseKey(hKeyProfile
);
2428 if (hKeyProfiles
!= NULL
)
2429 RegCloseKey(hKeyProfiles
);
2431 if (hKeyConfig
!= NULL
)
2432 RegCloseKey(hKeyConfig
);
2441 PNP_AddEmptyLogConf(
2445 DWORD
*pulLogConfTag
,
2449 return CR_CALL_NOT_IMPLEMENTED
;
2459 DWORD ulLogConfType
,
2464 return CR_CALL_NOT_IMPLEMENTED
;
2471 PNP_GetFirstLogConf(
2474 DWORD ulLogConfType
,
2475 DWORD
*pulLogConfTag
,
2479 return CR_CALL_NOT_IMPLEMENTED
;
2489 DWORD ulLogConfType
,
2495 return CR_CALL_NOT_IMPLEMENTED
;
2502 PNP_GetLogConfPriority(
2511 return CR_CALL_NOT_IMPLEMENTED
;
2522 DWORD ulLogConfType
,
2523 RESOURCEID ResourceID
,
2524 DWORD
*pulResourceTag
,
2526 PNP_RPC_BUFFER_SIZE ResourceLen
,
2530 return CR_CALL_NOT_IMPLEMENTED
;
2541 DWORD ulLogConfType
,
2542 RESOURCEID ResourceID
,
2543 DWORD ulResourceTag
,
2544 DWORD
*pulPreviousResType
,
2545 DWORD
*pulPreviousResTag
,
2549 return CR_CALL_NOT_IMPLEMENTED
;
2560 DWORD ulLogConfType
,
2561 RESOURCEID ResourceID
,
2562 DWORD ulResourceTag
,
2563 DWORD
*pulNextResType
,
2564 DWORD
*pulNextResTag
,
2568 return CR_CALL_NOT_IMPLEMENTED
;
2579 DWORD ulLogConfType
,
2580 RESOURCEID ResourceID
,
2581 DWORD ulResourceTag
,
2583 PNP_RPC_BUFFER_SIZE BufferLen
,
2587 return CR_CALL_NOT_IMPLEMENTED
;
2594 PNP_GetResDesDataSize(
2598 DWORD ulLogConfType
,
2599 RESOURCEID ResourceID
,
2600 DWORD ulResourceTag
,
2605 return CR_CALL_NOT_IMPLEMENTED
;
2616 DWORD ulLogConfType
,
2617 RESOURCEID CurrentResourceID
,
2618 RESOURCEID NewResourceID
,
2619 DWORD ulResourceTag
,
2621 PNP_RPC_BUFFER_SIZE ResourceLen
,
2625 return CR_CALL_NOT_IMPLEMENTED
;
2632 PNP_DetectResourceConflict(
2635 RESOURCEID ResourceID
,
2637 PNP_RPC_BUFFER_SIZE ResourceLen
,
2638 BOOL
*pbConflictDetected
,
2642 return CR_CALL_NOT_IMPLEMENTED
;
2649 PNP_QueryResConfList(
2652 RESOURCEID ResourceID
,
2654 PNP_RPC_BUFFER_SIZE ResourceLen
,
2656 PNP_RPC_BUFFER_SIZE BufferLen
,
2660 return CR_CALL_NOT_IMPLEMENTED
;
2669 DWORD ulHardwareProfile
,
2673 return CR_CALL_NOT_IMPLEMENTED
;
2680 PNP_QueryArbitratorFreeData(
2685 RESOURCEID ResourceID
,
2689 return CR_CALL_NOT_IMPLEMENTED
;
2696 PNP_QueryArbitratorFreeSize(
2700 RESOURCEID ResourceID
,
2704 return CR_CALL_NOT_IMPLEMENTED
;
2715 return CR_CALL_NOT_IMPLEMENTED
;
2722 PNP_RegisterNotification(
2726 return CR_CALL_NOT_IMPLEMENTED
;
2733 PNP_UnregisterNotification(
2737 return CR_CALL_NOT_IMPLEMENTED
;
2744 PNP_GetCustomDevProp(
2747 LPWSTR CustomPropName
,
2748 DWORD
*pulRegDataType
,
2750 PNP_RPC_STRING_LEN
*pulTransferLen
,
2751 PNP_RPC_STRING_LEN
*pulLength
,
2754 HKEY hDeviceKey
= NULL
;
2755 HKEY hParamKey
= NULL
;
2757 CONFIGRET ret
= CR_SUCCESS
;
2759 UNREFERENCED_PARAMETER(hBinding
);
2761 DPRINT("PNP_GetCustomDevProp() called\n");
2763 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2765 ret
= CR_INVALID_POINTER
;
2769 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2771 ret
= CR_INVALID_FLAG
;
2775 if (*pulLength
< *pulTransferLen
)
2776 *pulLength
= *pulTransferLen
;
2778 *pulTransferLen
= 0;
2780 lError
= RegOpenKeyExW(hEnumKey
,
2785 if (lError
!= ERROR_SUCCESS
)
2787 ret
= CR_REGISTRY_ERROR
;
2791 lError
= RegOpenKeyExW(hDeviceKey
,
2792 L
"Device Parameters",
2796 if (lError
!= ERROR_SUCCESS
)
2798 ret
= CR_REGISTRY_ERROR
;
2802 lError
= RegQueryValueExW(hParamKey
,
2808 if (lError
!= ERROR_SUCCESS
)
2810 if (lError
== ERROR_MORE_DATA
)
2812 ret
= CR_BUFFER_SMALL
;
2817 ret
= CR_NO_SUCH_VALUE
;
2822 if (ret
== CR_SUCCESS
)
2823 *pulTransferLen
= *pulLength
;
2825 if (hParamKey
!= NULL
)
2826 RegCloseKey(hParamKey
);
2828 if (hDeviceKey
!= NULL
)
2829 RegCloseKey(hDeviceKey
);
2831 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
2840 PNP_GetVersionInternal(
2852 PNP_GetBlockedDriverInfo(
2855 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
2856 PNP_RPC_BUFFER_SIZE
*pulLength
,
2860 return CR_CALL_NOT_IMPLEMENTED
;
2867 PNP_GetServerSideDeviceInstallFlags(
2869 DWORD
*pulSSDIFlags
,
2873 return CR_CALL_NOT_IMPLEMENTED
;
2880 PNP_GetObjectPropKeys(
2884 LPWSTR PropertyCultureName
,
2885 PNP_PROP_COUNT
*PropertyCount
,
2886 PNP_PROP_COUNT
*TransferLen
,
2887 DEVPROPKEY
*PropertyKeys
,
2891 return CR_CALL_NOT_IMPLEMENTED
;
2902 LPWSTR PropertyCultureName
,
2903 const DEVPROPKEY
*PropertyKey
,
2904 DEVPROPTYPE
*PropertyType
,
2905 PNP_PROP_SIZE
*PropertySize
,
2906 PNP_PROP_SIZE
*TransferLen
,
2907 BYTE
*PropertyBuffer
,
2911 return CR_CALL_NOT_IMPLEMENTED
;
2922 LPWSTR PropertyCultureName
,
2923 const DEVPROPKEY
*PropertyKey
,
2924 DEVPROPTYPE PropertyType
,
2925 PNP_PROP_SIZE PropertySize
,
2926 BYTE
*PropertyBuffer
,
2930 return CR_CALL_NOT_IMPLEMENTED
;
2941 return CR_CALL_NOT_IMPLEMENTED
;
2948 PNP_ApplyPowerSettings(
2952 return CR_CALL_NOT_IMPLEMENTED
;
2959 PNP_DriverStoreAddDriverPackage(
2963 return CR_CALL_NOT_IMPLEMENTED
;
2970 PNP_DriverStoreDeleteDriverPackage(
2974 return CR_CALL_NOT_IMPLEMENTED
;
2981 PNP_RegisterServiceNotification(
2985 return CR_CALL_NOT_IMPLEMENTED
;
2992 PNP_SetActiveService(
2998 return CR_CALL_NOT_IMPLEMENTED
;
3005 PNP_DeleteServiceDevices(
3009 return CR_CALL_NOT_IMPLEMENTED
;
3014 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3016 BOOL DeviceInstalled
= FALSE
;
3019 HANDLE hInstallEvent
;
3020 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3021 LPVOID Environment
= NULL
;
3022 PROCESS_INFORMATION ProcessInfo
;
3023 STARTUPINFOW StartupInfo
;
3027 /* The following lengths are constant (see below), they cannot overflow */
3028 WCHAR CommandLine
[116];
3029 WCHAR InstallEventName
[73];
3031 WCHAR UuidString
[39];
3033 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3035 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3037 if (RegOpenKeyExW(hEnumKey
,
3041 &DeviceKey
) == ERROR_SUCCESS
)
3043 if (RegQueryValueExW(DeviceKey
,
3048 NULL
) == ERROR_SUCCESS
)
3050 DPRINT("No need to install: %S\n", DeviceInstance
);
3051 RegCloseKey(DeviceKey
);
3055 RegCloseKey(DeviceKey
);
3058 DPRINT1("Installing: %S\n", DeviceInstance
);
3060 /* Create a random UUID for the named pipe & event*/
3061 UuidCreate(&RandomUuid
);
3062 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3063 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3064 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3065 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3066 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3068 /* Create the event */
3069 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3070 wcscat(InstallEventName
, UuidString
);
3071 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3074 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3078 /* Create the named pipe */
3079 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3080 wcscat(PipeName
, UuidString
);
3081 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3082 if (hPipe
== INVALID_HANDLE_VALUE
)
3084 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3088 /* Launch rundll32 to call ClientSideInstallW */
3089 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3090 wcscat(CommandLine
, PipeName
);
3092 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3093 StartupInfo
.cb
= sizeof(StartupInfo
);
3097 /* newdev has to run under the environment of the current user */
3098 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3100 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3104 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3106 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3112 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3114 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3115 (ShowWizard is only set to FALSE for these two modes) */
3116 ASSERT(!ShowWizard
);
3118 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3120 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3125 /* Wait for the function to connect to our pipe */
3126 if (!ConnectNamedPipe(hPipe
, NULL
))
3128 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3130 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3135 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3136 Value
= sizeof(InstallEventName
);
3137 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3138 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3140 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3141 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3142 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3144 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3145 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3146 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3148 /* Wait for newdev.dll to finish processing */
3149 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3151 /* If the event got signalled, this is success */
3152 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3156 CloseHandle(hInstallEvent
);
3158 if (hPipe
!= INVALID_HANDLE_VALUE
)
3162 DestroyEnvironmentBlock(Environment
);
3164 if (ProcessInfo
.hProcess
)
3165 CloseHandle(ProcessInfo
.hProcess
);
3167 if (ProcessInfo
.hThread
)
3168 CloseHandle(ProcessInfo
.hThread
);
3170 if (!DeviceInstalled
)
3172 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3175 return DeviceInstalled
;
3191 return ERROR_INVALID_PARAMETER
;
3194 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3195 if (rc
!= ERROR_SUCCESS
)
3197 if (dwType
!= REG_SZ
)
3198 return ERROR_FILE_NOT_FOUND
;
3199 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3201 return ERROR_NOT_ENOUGH_MEMORY
;
3202 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3203 if (rc
!= ERROR_SUCCESS
)
3205 HeapFree(GetProcessHeap(), 0, Value
);
3208 /* NULL-terminate the string */
3209 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3212 return ERROR_SUCCESS
;
3220 DWORD regType
, active
, size
;
3224 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3225 if (rc
!= ERROR_SUCCESS
)
3228 size
= sizeof(DWORD
);
3229 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3230 if (rc
!= ERROR_SUCCESS
)
3232 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3235 ret
= (active
!= 0);
3241 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3250 HKEY ControlKey
= NULL
;
3251 LPWSTR SystemStartOptions
= NULL
;
3252 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3253 BOOL ConsoleBoot
= FALSE
;
3258 L
"SYSTEM\\CurrentControlSet\\Control",
3263 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3264 if (rc
!= ERROR_SUCCESS
)
3267 /* Check for CONSOLE switch in SystemStartOptions */
3268 CurrentOption
= SystemStartOptions
;
3269 while (CurrentOption
)
3271 NextOption
= wcschr(CurrentOption
, L
' ');
3273 *NextOption
= L
'\0';
3274 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3276 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3280 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3284 if (ControlKey
!= NULL
)
3285 RegCloseKey(ControlKey
);
3286 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3291 /* Loop to install all queued devices installations */
3293 DeviceInstallThread(LPVOID lpParameter
)
3295 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3296 PSLIST_ENTRY ListEntry
;
3298 PLIST_ENTRY ListEntry
;
3300 DeviceInstallParams
* Params
;
3303 UNREFERENCED_PARAMETER(lpParameter
);
3305 WaitForSingleObject(hInstallEvent
, INFINITE
);
3307 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3311 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3312 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3314 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3317 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3319 if (ListEntry
== NULL
)
3321 SetEvent(hNoPendingInstalls
);
3322 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3326 ResetEvent(hNoPendingInstalls
);
3327 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3328 InstallDevice(Params
->DeviceIds
, showWizard
);
3337 PnpEventThread(LPVOID lpParameter
)
3339 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3342 RPC_STATUS RpcStatus
;
3344 UNREFERENCED_PARAMETER(lpParameter
);
3346 PnpEventSize
= 0x1000;
3347 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3348 if (PnpEvent
== NULL
)
3349 return ERROR_OUTOFMEMORY
;
3353 DPRINT("Calling NtGetPlugPlayEvent()\n");
3355 /* Wait for the next pnp event */
3356 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3358 /* Resize the buffer for the PnP event if it's too small. */
3359 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3361 PnpEventSize
+= 0x400;
3362 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3363 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3364 if (PnpEvent
== NULL
)
3365 return ERROR_OUTOFMEMORY
;
3369 if (!NT_SUCCESS(Status
))
3371 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3375 /* Process the pnp event */
3376 DPRINT("Received PnP Event\n");
3377 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3379 DeviceInstallParams
* Params
;
3381 DWORD DeviceIdLength
;
3383 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3385 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3388 /* Queue device install (will be dequeued by DeviceInstallThread */
3389 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3390 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3393 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3394 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3395 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3397 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3399 SetEvent(hDeviceInstallListNotEmpty
);
3403 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3405 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3408 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3410 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3412 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3414 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3416 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3418 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3420 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3422 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3424 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3426 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3428 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3430 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3434 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3435 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3436 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3437 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3438 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3441 /* Dequeue the current pnp event and signal the next one */
3442 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3445 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3447 return ERROR_SUCCESS
;
3452 UpdateServiceStatus(DWORD dwState
)
3454 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3455 ServiceStatus
.dwCurrentState
= dwState
;
3456 ServiceStatus
.dwControlsAccepted
= 0;
3457 ServiceStatus
.dwWin32ExitCode
= 0;
3458 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3459 ServiceStatus
.dwCheckPoint
= 0;
3461 if (dwState
== SERVICE_START_PENDING
||
3462 dwState
== SERVICE_STOP_PENDING
||
3463 dwState
== SERVICE_PAUSE_PENDING
||
3464 dwState
== SERVICE_CONTINUE_PENDING
)
3465 ServiceStatus
.dwWaitHint
= 10000;
3467 ServiceStatus
.dwWaitHint
= 0;
3469 SetServiceStatus(ServiceStatusHandle
,
3475 ServiceControlHandler(DWORD dwControl
,
3480 DPRINT1("ServiceControlHandler() called\n");
3484 case SERVICE_CONTROL_STOP
:
3485 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3486 /* Stop listening to RPC Messages */
3487 RpcMgmtStopServerListening(NULL
);
3488 UpdateServiceStatus(SERVICE_STOPPED
);
3489 return ERROR_SUCCESS
;
3491 case SERVICE_CONTROL_PAUSE
:
3492 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3493 UpdateServiceStatus(SERVICE_PAUSED
);
3494 return ERROR_SUCCESS
;
3496 case SERVICE_CONTROL_CONTINUE
:
3497 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3498 UpdateServiceStatus(SERVICE_RUNNING
);
3499 return ERROR_SUCCESS
;
3501 case SERVICE_CONTROL_INTERROGATE
:
3502 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3503 SetServiceStatus(ServiceStatusHandle
,
3505 return ERROR_SUCCESS
;
3507 case SERVICE_CONTROL_SHUTDOWN
:
3508 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3509 /* Stop listening to RPC Messages */
3510 RpcMgmtStopServerListening(NULL
);
3511 UpdateServiceStatus(SERVICE_STOPPED
);
3512 return ERROR_SUCCESS
;
3515 DPRINT1(" Control %lu received\n");
3516 return ERROR_CALL_NOT_IMPLEMENTED
;
3522 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3527 UNREFERENCED_PARAMETER(argc
);
3528 UNREFERENCED_PARAMETER(argv
);
3530 DPRINT("ServiceMain() called\n");
3532 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3533 ServiceControlHandler
,
3535 if (!ServiceStatusHandle
)
3537 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3541 UpdateServiceStatus(SERVICE_START_PENDING
);
3543 hThread
= CreateThread(NULL
,
3549 if (hThread
!= NULL
)
3550 CloseHandle(hThread
);
3552 hThread
= CreateThread(NULL
,
3558 if (hThread
!= NULL
)
3559 CloseHandle(hThread
);
3561 hThread
= CreateThread(NULL
,
3563 DeviceInstallThread
,
3567 if (hThread
!= NULL
)
3568 CloseHandle(hThread
);
3570 UpdateServiceStatus(SERVICE_RUNNING
);
3572 DPRINT("ServiceMain() done\n");
3576 InitializePnPManager(VOID
)
3581 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3583 /* We need this privilege for using CreateProcessAsUserW */
3584 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3586 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3587 if (hInstallEvent
== NULL
)
3589 dwError
= GetLastError();
3590 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3594 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3595 if (hDeviceInstallListNotEmpty
== NULL
)
3597 dwError
= GetLastError();
3598 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3602 hNoPendingInstalls
= CreateEventW(NULL
,
3605 L
"Global\\PnP_No_Pending_Install_Events");
3606 if (hNoPendingInstalls
== NULL
)
3608 dwError
= GetLastError();
3609 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3613 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3614 InitializeSListHead(&DeviceInstallListHead
);
3616 InitializeListHead(&DeviceInstallListHead
);
3619 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3620 L
"System\\CurrentControlSet\\Enum",
3624 if (dwError
!= ERROR_SUCCESS
)
3626 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3630 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3631 L
"System\\CurrentControlSet\\Control\\Class",
3635 if (dwError
!= ERROR_SUCCESS
)
3637 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3641 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3647 DllMain(HINSTANCE hinstDLL
,
3653 case DLL_PROCESS_ATTACH
:
3654 DisableThreadLibraryCalls(hinstDLL
);
3655 InitializePnPManager();
3658 case DLL_PROCESS_DETACH
: