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 hPipe
= INVALID_HANDLE_VALUE
;
3020 LPVOID Environment
= NULL
;
3021 PROCESS_INFORMATION ProcessInfo
;
3022 STARTUPINFOW StartupInfo
;
3026 /* The following lengths are constant (see below), they cannot overflow */
3027 WCHAR CommandLine
[116];
3028 WCHAR InstallEventName
[73];
3030 WCHAR UuidString
[39];
3032 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3034 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3036 if (RegOpenKeyExW(hEnumKey
,
3040 &DeviceKey
) == ERROR_SUCCESS
)
3042 if (RegQueryValueExW(DeviceKey
,
3047 NULL
) == ERROR_SUCCESS
)
3049 DPRINT("No need to install: %S\n", DeviceInstance
);
3050 RegCloseKey(DeviceKey
);
3054 RegCloseKey(DeviceKey
);
3057 DPRINT1("Installing: %S\n", DeviceInstance
);
3059 /* Create a random UUID for the named pipe */
3060 UuidCreate(&RandomUuid
);
3061 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3062 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3063 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3064 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3065 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3067 /* Create the named pipe */
3068 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3069 wcscat(PipeName
, UuidString
);
3070 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3072 if (hPipe
== INVALID_HANDLE_VALUE
)
3074 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3078 /* Launch rundll32 to call ClientSideInstallW */
3079 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3080 wcscat(CommandLine
, PipeName
);
3082 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3083 StartupInfo
.cb
= sizeof(StartupInfo
);
3087 /* newdev has to run under the environment of the current user */
3088 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3090 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3094 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3096 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3102 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3104 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3105 (ShowWizard is only set to FALSE for these two modes) */
3106 ASSERT(!ShowWizard
);
3108 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3110 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3115 /* Wait for the function to connect to our pipe */
3116 if (!ConnectNamedPipe(hPipe
, NULL
))
3118 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3120 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3125 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3126 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3127 wcscat(InstallEventName
, UuidString
);
3129 Value
= sizeof(InstallEventName
);
3130 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3131 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3133 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3134 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3135 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3137 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3138 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3139 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3141 /* Wait for newdev.dll to finish processing */
3142 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3144 /* The following check for success is probably not compatible to Windows, but should do its job */
3145 if (!GetExitCodeProcess(ProcessInfo
.hProcess
, &Value
))
3147 DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
3151 DeviceInstalled
= Value
;
3154 if (hPipe
!= INVALID_HANDLE_VALUE
)
3158 DestroyEnvironmentBlock(Environment
);
3160 if (ProcessInfo
.hProcess
)
3161 CloseHandle(ProcessInfo
.hProcess
);
3163 if (ProcessInfo
.hThread
)
3164 CloseHandle(ProcessInfo
.hThread
);
3166 if (!DeviceInstalled
)
3168 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3171 return DeviceInstalled
;
3187 return ERROR_INVALID_PARAMETER
;
3190 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3191 if (rc
!= ERROR_SUCCESS
)
3193 if (dwType
!= REG_SZ
)
3194 return ERROR_FILE_NOT_FOUND
;
3195 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3197 return ERROR_NOT_ENOUGH_MEMORY
;
3198 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3199 if (rc
!= ERROR_SUCCESS
)
3201 HeapFree(GetProcessHeap(), 0, Value
);
3204 /* NULL-terminate the string */
3205 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3208 return ERROR_SUCCESS
;
3216 DWORD regType
, active
, size
;
3220 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3221 if (rc
!= ERROR_SUCCESS
)
3224 size
= sizeof(DWORD
);
3225 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3226 if (rc
!= ERROR_SUCCESS
)
3228 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3231 ret
= (active
!= 0);
3237 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3246 HKEY ControlKey
= NULL
;
3247 LPWSTR SystemStartOptions
= NULL
;
3248 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3249 BOOL ConsoleBoot
= FALSE
;
3254 L
"SYSTEM\\CurrentControlSet\\Control",
3259 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3260 if (rc
!= ERROR_SUCCESS
)
3263 /* Check for CONSOLE switch in SystemStartOptions */
3264 CurrentOption
= SystemStartOptions
;
3265 while (CurrentOption
)
3267 NextOption
= wcschr(CurrentOption
, L
' ');
3269 *NextOption
= L
'\0';
3270 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3272 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3276 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3280 if (ControlKey
!= NULL
)
3281 RegCloseKey(ControlKey
);
3282 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3287 /* Loop to install all queued devices installations */
3289 DeviceInstallThread(LPVOID lpParameter
)
3291 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3292 PSLIST_ENTRY ListEntry
;
3294 PLIST_ENTRY ListEntry
;
3296 DeviceInstallParams
* Params
;
3299 UNREFERENCED_PARAMETER(lpParameter
);
3301 WaitForSingleObject(hInstallEvent
, INFINITE
);
3303 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3307 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3308 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3310 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3313 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3315 if (ListEntry
== NULL
)
3317 SetEvent(hNoPendingInstalls
);
3318 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3322 ResetEvent(hNoPendingInstalls
);
3323 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3324 InstallDevice(Params
->DeviceIds
, showWizard
);
3333 PnpEventThread(LPVOID lpParameter
)
3335 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3338 RPC_STATUS RpcStatus
;
3340 UNREFERENCED_PARAMETER(lpParameter
);
3342 PnpEventSize
= 0x1000;
3343 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3344 if (PnpEvent
== NULL
)
3345 return ERROR_OUTOFMEMORY
;
3349 DPRINT("Calling NtGetPlugPlayEvent()\n");
3351 /* Wait for the next pnp event */
3352 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3354 /* Resize the buffer for the PnP event if it's too small. */
3355 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3357 PnpEventSize
+= 0x400;
3358 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3359 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3360 if (PnpEvent
== NULL
)
3361 return ERROR_OUTOFMEMORY
;
3365 if (!NT_SUCCESS(Status
))
3367 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3371 /* Process the pnp event */
3372 DPRINT("Received PnP Event\n");
3373 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3375 DeviceInstallParams
* Params
;
3377 DWORD DeviceIdLength
;
3379 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3381 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3384 /* Queue device install (will be dequeued by DeviceInstallThread */
3385 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3386 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3389 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3390 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3391 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3393 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3395 SetEvent(hDeviceInstallListNotEmpty
);
3399 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3401 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3404 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3406 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3408 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3410 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3412 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3414 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3416 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3418 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3420 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3422 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3424 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3426 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3430 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3431 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3432 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3433 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3434 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3437 /* Dequeue the current pnp event and signal the next one */
3438 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3441 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3443 return ERROR_SUCCESS
;
3448 UpdateServiceStatus(DWORD dwState
)
3450 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3451 ServiceStatus
.dwCurrentState
= dwState
;
3452 ServiceStatus
.dwControlsAccepted
= 0;
3453 ServiceStatus
.dwWin32ExitCode
= 0;
3454 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3455 ServiceStatus
.dwCheckPoint
= 0;
3457 if (dwState
== SERVICE_START_PENDING
||
3458 dwState
== SERVICE_STOP_PENDING
||
3459 dwState
== SERVICE_PAUSE_PENDING
||
3460 dwState
== SERVICE_CONTINUE_PENDING
)
3461 ServiceStatus
.dwWaitHint
= 10000;
3463 ServiceStatus
.dwWaitHint
= 0;
3465 SetServiceStatus(ServiceStatusHandle
,
3471 ServiceControlHandler(DWORD dwControl
,
3476 DPRINT1("ServiceControlHandler() called\n");
3480 case SERVICE_CONTROL_STOP
:
3481 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3482 /* Stop listening to RPC Messages */
3483 RpcMgmtStopServerListening(NULL
);
3484 UpdateServiceStatus(SERVICE_STOPPED
);
3485 return ERROR_SUCCESS
;
3487 case SERVICE_CONTROL_PAUSE
:
3488 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3489 UpdateServiceStatus(SERVICE_PAUSED
);
3490 return ERROR_SUCCESS
;
3492 case SERVICE_CONTROL_CONTINUE
:
3493 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3494 UpdateServiceStatus(SERVICE_RUNNING
);
3495 return ERROR_SUCCESS
;
3497 case SERVICE_CONTROL_INTERROGATE
:
3498 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3499 SetServiceStatus(ServiceStatusHandle
,
3501 return ERROR_SUCCESS
;
3503 case SERVICE_CONTROL_SHUTDOWN
:
3504 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3505 /* Stop listening to RPC Messages */
3506 RpcMgmtStopServerListening(NULL
);
3507 UpdateServiceStatus(SERVICE_STOPPED
);
3508 return ERROR_SUCCESS
;
3511 DPRINT1(" Control %lu received\n");
3512 return ERROR_CALL_NOT_IMPLEMENTED
;
3518 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3523 UNREFERENCED_PARAMETER(argc
);
3524 UNREFERENCED_PARAMETER(argv
);
3526 DPRINT("ServiceMain() called\n");
3528 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3529 ServiceControlHandler
,
3531 if (!ServiceStatusHandle
)
3533 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3537 UpdateServiceStatus(SERVICE_START_PENDING
);
3539 hThread
= CreateThread(NULL
,
3545 if (hThread
!= NULL
)
3546 CloseHandle(hThread
);
3548 hThread
= CreateThread(NULL
,
3554 if (hThread
!= NULL
)
3555 CloseHandle(hThread
);
3557 hThread
= CreateThread(NULL
,
3559 DeviceInstallThread
,
3563 if (hThread
!= NULL
)
3564 CloseHandle(hThread
);
3566 UpdateServiceStatus(SERVICE_RUNNING
);
3568 DPRINT("ServiceMain() done\n");
3572 InitializePnPManager(VOID
)
3577 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3579 /* We need this privilege for using CreateProcessAsUserW */
3580 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3582 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3583 if (hInstallEvent
== NULL
)
3585 dwError
= GetLastError();
3586 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3590 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3591 if (hDeviceInstallListNotEmpty
== NULL
)
3593 dwError
= GetLastError();
3594 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3598 hNoPendingInstalls
= CreateEventW(NULL
,
3601 L
"Global\\PnP_No_Pending_Install_Events");
3602 if (hNoPendingInstalls
== NULL
)
3604 dwError
= GetLastError();
3605 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3609 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3610 InitializeSListHead(&DeviceInstallListHead
);
3612 InitializeListHead(&DeviceInstallListHead
);
3615 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3616 L
"System\\CurrentControlSet\\Enum",
3620 if (dwError
!= ERROR_SUCCESS
)
3622 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3626 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3627 L
"System\\CurrentControlSet\\Control\\Class",
3631 if (dwError
!= ERROR_SUCCESS
)
3633 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3637 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3643 DllMain(HINSTANCE hinstDLL
,
3649 case DLL_PROCESS_ATTACH
:
3650 DisableThreadLibraryCalls(hinstDLL
);
3651 InitializePnPManager();
3654 case DLL_PROCESS_DETACH
: