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
;
174 /* FIXME: add more mappings */
175 DPRINT1("Unable to map status 0x%08lx\n", Status
);
187 UNREFERENCED_PARAMETER(hBinding
);
198 UNREFERENCED_PARAMETER(hBinding
);
210 UNREFERENCED_PARAMETER(hBinding
);
225 UNREFERENCED_PARAMETER(hBinding
);
226 UNREFERENCED_PARAMETER(ulFlags
);
228 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
239 UNREFERENCED_PARAMETER(hBinding
);
241 DPRINT("PNP_InitDetection() called\n");
254 DWORD ReturnValue
= CR_FAILURE
;
257 UNREFERENCED_PARAMETER(hBinding
);
258 UNREFERENCED_PARAMETER(Admin
);
260 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
262 /* Get the users token */
263 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
267 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
273 CloseHandle(hUserToken
);
277 if(!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
279 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
283 /* Trigger the installer thread */
285 SetEvent(hInstallEvent
);
287 ReturnValue
= CR_SUCCESS
;
291 CloseHandle(hProcess
);
300 PNP_ValidateDeviceInstance(
305 CONFIGRET ret
= CR_SUCCESS
;
306 HKEY hDeviceKey
= NULL
;
308 UNREFERENCED_PARAMETER(hBinding
);
309 UNREFERENCED_PARAMETER(ulFlags
);
311 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
314 if (RegOpenKeyExW(hEnumKey
,
320 DPRINT("Could not open the Device Key!\n");
321 ret
= CR_NO_SUCH_DEVNODE
;
325 /* FIXME: add more tests */
328 if (hDeviceKey
!= NULL
)
329 RegCloseKey(hDeviceKey
);
331 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
340 PNP_GetRootDeviceInstance(
343 PNP_RPC_STRING_LEN ulLength
)
345 CONFIGRET ret
= CR_SUCCESS
;
347 UNREFERENCED_PARAMETER(hBinding
);
349 DPRINT("PNP_GetRootDeviceInstance() called\n");
353 ret
= CR_INVALID_POINTER
;
356 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
358 ret
= CR_BUFFER_SMALL
;
366 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
375 PNP_GetRelatedDeviceInstance(
377 DWORD ulRelationship
,
379 LPWSTR pRelatedDeviceId
,
380 PNP_RPC_STRING_LEN
*pulLength
,
383 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
384 CONFIGRET ret
= CR_SUCCESS
;
387 UNREFERENCED_PARAMETER(hBinding
);
388 UNREFERENCED_PARAMETER(ulFlags
);
390 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
391 DPRINT(" Relationship %ld\n", ulRelationship
);
392 DPRINT(" DeviceId %S\n", pDeviceID
);
394 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
397 PlugPlayData
.Relation
= ulRelationship
;
399 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
400 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
402 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
403 (PVOID
)&PlugPlayData
,
404 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
405 if (!NT_SUCCESS(Status
))
407 ret
= NtStatusToCrError(Status
);
410 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
411 if (ret
== CR_SUCCESS
)
413 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
423 PNP_EnumerateSubKeys(
428 PNP_RPC_STRING_LEN ulLength
,
429 PNP_RPC_STRING_LEN
*pulRequiredLen
,
432 CONFIGRET ret
= CR_SUCCESS
;
436 UNREFERENCED_PARAMETER(hBinding
);
437 UNREFERENCED_PARAMETER(ulFlags
);
439 DPRINT("PNP_EnumerateSubKeys() called\n");
443 case PNP_ENUMERATOR_SUBKEYS
:
447 case PNP_CLASS_SUBKEYS
:
455 *pulRequiredLen
= ulLength
;
456 dwError
= RegEnumKeyExW(hKey
,
464 if (dwError
!= ERROR_SUCCESS
)
466 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
473 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
486 PNP_RPC_STRING_LEN
*pulLength
,
490 return CR_CALL_NOT_IMPLEMENTED
;
497 PNP_GetDeviceListSize(
500 PNP_RPC_BUFFER_SIZE
*pulLen
,
504 return CR_CALL_NOT_IMPLEMENTED
;
517 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
518 CONFIGRET ret
= CR_SUCCESS
;
521 UNREFERENCED_PARAMETER(hBinding
);
522 UNREFERENCED_PARAMETER(ulFlags
);
524 DPRINT("PNP_GetDepth() called\n");
526 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
529 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
530 (PVOID
)&PlugPlayData
,
531 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
532 if (NT_SUCCESS(Status
))
534 *pulDepth
= PlugPlayData
.Depth
;
538 ret
= NtStatusToCrError(Status
);
541 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
550 PNP_GetDeviceRegProp(
554 DWORD
*pulRegDataType
,
556 PNP_PROP_SIZE
*pulTransferLen
,
557 PNP_PROP_SIZE
*pulLength
,
560 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
561 CONFIGRET ret
= CR_SUCCESS
;
562 LPWSTR lpValueName
= NULL
;
567 UNREFERENCED_PARAMETER(hBinding
);
569 DPRINT("PNP_GetDeviceRegProp() called\n");
571 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
573 ret
= CR_INVALID_POINTER
;
579 ret
= CR_INVALID_FLAG
;
583 /* FIXME: Check pDeviceID */
585 if (*pulLength
< *pulTransferLen
)
586 *pulLength
= *pulTransferLen
;
592 case CM_DRP_DEVICEDESC
:
593 lpValueName
= L
"DeviceDesc";
596 case CM_DRP_HARDWAREID
:
597 lpValueName
= L
"HardwareID";
600 case CM_DRP_COMPATIBLEIDS
:
601 lpValueName
= L
"CompatibleIDs";
605 lpValueName
= L
"Service";
609 lpValueName
= L
"Class";
612 case CM_DRP_CLASSGUID
:
613 lpValueName
= L
"ClassGUID";
617 lpValueName
= L
"Driver";
620 case CM_DRP_CONFIGFLAGS
:
621 lpValueName
= L
"ConfigFlags";
625 lpValueName
= L
"Mfg";
628 case CM_DRP_FRIENDLYNAME
:
629 lpValueName
= L
"FriendlyName";
632 case CM_DRP_LOCATION_INFORMATION
:
633 lpValueName
= L
"LocationInformation";
636 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
640 case CM_DRP_CAPABILITIES
:
641 lpValueName
= L
"Capabilities";
644 case CM_DRP_UI_NUMBER
:
648 case CM_DRP_UPPERFILTERS
:
649 lpValueName
= L
"UpperFilters";
652 case CM_DRP_LOWERFILTERS
:
653 lpValueName
= L
"LowerFilters";
656 case CM_DRP_BUSTYPEGUID
:
660 case CM_DRP_LEGACYBUSTYPE
:
664 case CM_DRP_BUSNUMBER
:
668 case CM_DRP_ENUMERATOR_NAME
:
672 case CM_DRP_SECURITY
:
673 lpValueName
= L
"Security";
677 lpValueName
= L
"DeviceType";
680 case CM_DRP_EXCLUSIVE
:
681 lpValueName
= L
"Exclusive";
684 case CM_DRP_CHARACTERISTICS
:
685 lpValueName
= L
"DeviceCharacteristics";
692 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
693 lpValueName
= L
"UINumberDescFormat";
696 case CM_DRP_DEVICE_POWER_DATA
:
700 case CM_DRP_REMOVAL_POLICY
:
704 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
708 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
709 lpValueName
= L
"RemovalPolicy";
712 case CM_DRP_INSTALL_STATE
:
716 #if (WINVER >= _WIN32_WINNT_WS03)
717 case CM_DRP_LOCATION_PATHS
:
722 #if (WINVER >= _WIN32_WINNT_WIN7)
723 case CM_DRP_BASE_CONTAINERID
:
729 ret
= CR_INVALID_PROPERTY
;
733 DPRINT("Value name: %S\n", lpValueName
);
737 /* Retrieve information from the Registry */
738 lError
= RegOpenKeyExW(hEnumKey
,
743 if (lError
!= ERROR_SUCCESS
)
747 ret
= CR_INVALID_DEVNODE
;
751 lError
= RegQueryValueExW(hKey
,
757 if (lError
!= ERROR_SUCCESS
)
759 if (lError
== ERROR_MORE_DATA
)
761 ret
= CR_BUFFER_SMALL
;
766 ret
= CR_NO_SUCH_VALUE
;
772 /* Retrieve information from the Device Node */
773 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
775 PlugPlayData
.Buffer
= Buffer
;
776 PlugPlayData
.BufferSize
= *pulLength
;
780 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
781 PlugPlayData
.Property
= 0xb; // DevicePropertyPhysicalDeviceObjectName;
784 case CM_DRP_UI_NUMBER
:
785 PlugPlayData
.Property
= 0x11; // DevicePropertyUINumber;
788 case CM_DRP_BUSTYPEGUID
:
789 PlugPlayData
.Property
= 0xc; // DevicePropertyBusTypeGuid;
792 case CM_DRP_LEGACYBUSTYPE
:
793 PlugPlayData
.Property
= 0xd; // DevicePropertyLegacyBusType;
796 case CM_DRP_BUSNUMBER
:
797 PlugPlayData
.Property
= 0xe; // DevicePropertyBusNumber;
800 case CM_DRP_ENUMERATOR_NAME
:
801 PlugPlayData
.Property
= 0xf; // DevicePropertyEnumeratorName;
805 PlugPlayData
.Property
= 0x10; // DevicePropertyAddress;
809 /* FIXME: This property is not supported by IoGetDeviceProperty */
810 case CM_DRP_DEVICE_POWER_DATA
:
813 case CM_DRP_REMOVAL_POLICY
:
814 PlugPlayData
.Property
= 0x12; // DevicePropertyRemovalPolicy
818 /* FIXME: This property is not supported by IoGetDeviceProperty */
819 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
822 case CM_DRP_INSTALL_STATE
:
823 PlugPlayData
.Property
= 0x12; // DevicePropertyInstallState;
827 /* FIXME: This property is not supported by IoGetDeviceProperty */
828 #if (WINVER >= _WIN32_WINNT_WS03)
829 case CM_DRP_LOCATION_PATHS
:
833 #if (WINVER >= _WIN32_WINNT_WIN7)
834 case CM_DRP_BASE_CONTAINERID
:
835 PlugPlayData
.Property
= 0x16; // DevicePropertyContainerID;
840 return CR_INVALID_PROPERTY
;
843 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
844 (PVOID
)&PlugPlayData
,
845 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
846 if (NT_SUCCESS(Status
))
848 *pulLength
= PlugPlayData
.BufferSize
;
852 ret
= NtStatusToCrError(Status
);
857 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
862 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
871 PNP_SetDeviceRegProp(
877 PNP_PROP_SIZE ulLength
,
880 CONFIGRET ret
= CR_SUCCESS
;
881 LPWSTR lpValueName
= NULL
;
884 UNREFERENCED_PARAMETER(hBinding
);
885 UNREFERENCED_PARAMETER(ulFlags
);
887 DPRINT("PNP_SetDeviceRegProp() called\n");
889 DPRINT("DeviceId: %S\n", pDeviceId
);
890 DPRINT("Property: %lu\n", ulProperty
);
891 DPRINT("DataType: %lu\n", ulDataType
);
892 DPRINT("Length: %lu\n", ulLength
);
896 case CM_DRP_DEVICEDESC
:
897 lpValueName
= L
"DeviceDesc";
900 case CM_DRP_HARDWAREID
:
901 lpValueName
= L
"HardwareID";
904 case CM_DRP_COMPATIBLEIDS
:
905 lpValueName
= L
"CompatibleIDs";
909 lpValueName
= L
"Service";
913 lpValueName
= L
"Class";
916 case CM_DRP_CLASSGUID
:
917 lpValueName
= L
"ClassGUID";
921 lpValueName
= L
"Driver";
924 case CM_DRP_CONFIGFLAGS
:
925 lpValueName
= L
"ConfigFlags";
929 lpValueName
= L
"Mfg";
932 case CM_DRP_FRIENDLYNAME
:
933 lpValueName
= L
"FriendlyName";
936 case CM_DRP_LOCATION_INFORMATION
:
937 lpValueName
= L
"LocationInformation";
940 case CM_DRP_UPPERFILTERS
:
941 lpValueName
= L
"UpperFilters";
944 case CM_DRP_LOWERFILTERS
:
945 lpValueName
= L
"LowerFilters";
948 case CM_DRP_SECURITY
:
949 lpValueName
= L
"Security";
953 lpValueName
= L
"DeviceType";
956 case CM_DRP_EXCLUSIVE
:
957 lpValueName
= L
"Exclusive";
960 case CM_DRP_CHARACTERISTICS
:
961 lpValueName
= L
"DeviceCharacteristics";
964 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
965 lpValueName
= L
"UINumberDescFormat";
968 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
969 lpValueName
= L
"RemovalPolicy";
973 return CR_INVALID_PROPERTY
;
976 DPRINT("Value name: %S\n", lpValueName
);
978 if (RegOpenKeyExW(hEnumKey
,
983 return CR_INVALID_DEVNODE
;
987 if (RegDeleteValueW(hKey
,
989 ret
= CR_REGISTRY_ERROR
;
993 if (RegSetValueExW(hKey
,
999 ret
= CR_REGISTRY_ERROR
;
1004 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1013 PNP_GetClassInstance(
1016 LPWSTR pszClassInstance
,
1017 PNP_RPC_STRING_LEN ulLength
)
1020 return CR_CALL_NOT_IMPLEMENTED
;
1035 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1044 return CR_REGISTRY_ERROR
;
1046 /* FIXME: Set security key */
1057 PNP_DeleteRegistryKey(
1060 LPWSTR pszParentKey
,
1065 return CR_CALL_NOT_IMPLEMENTED
;
1074 DWORD
*pulClassCount
,
1080 UNREFERENCED_PARAMETER(hBinding
);
1081 UNREFERENCED_PARAMETER(ulFlags
);
1083 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1088 if (dwError
!= ERROR_SUCCESS
)
1089 return CR_INVALID_DATA
;
1091 dwError
= RegQueryInfoKeyW(hKey
,
1104 if (dwError
!= ERROR_SUCCESS
)
1105 return CR_INVALID_DATA
;
1116 LPWSTR pszClassGuid
,
1118 PNP_RPC_STRING_LEN
*pulLength
,
1121 WCHAR szKeyName
[MAX_PATH
];
1122 CONFIGRET ret
= CR_SUCCESS
;
1126 UNREFERENCED_PARAMETER(hBinding
);
1127 UNREFERENCED_PARAMETER(ulFlags
);
1129 DPRINT("PNP_GetClassName() called\n");
1131 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1132 if(lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1133 lstrcatW(szKeyName
, pszClassGuid
);
1134 else return CR_INVALID_DATA
;
1136 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1141 return CR_REGISTRY_ERROR
;
1143 dwSize
= *pulLength
* sizeof(WCHAR
);
1144 if (RegQueryValueExW(hKey
,
1152 ret
= CR_REGISTRY_ERROR
;
1156 *pulLength
= dwSize
/ sizeof(WCHAR
);
1161 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1172 LPWSTR pszClassGuid
,
1175 CONFIGRET ret
= CR_SUCCESS
;
1177 UNREFERENCED_PARAMETER(hBinding
);
1179 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1181 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1183 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1184 ret
= CR_REGISTRY_ERROR
;
1188 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1189 ret
= CR_REGISTRY_ERROR
;
1192 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1201 PNP_GetInterfaceDeviceAlias(
1203 LPWSTR pszInterfaceDevice
,
1204 GUID
*AliasInterfaceGuid
,
1205 LPWSTR pszAliasInterfaceDevice
,
1206 PNP_RPC_STRING_LEN
*pulLength
,
1207 PNP_RPC_STRING_LEN
*pulTransferLen
,
1211 return CR_CALL_NOT_IMPLEMENTED
;
1218 PNP_GetInterfaceDeviceList(
1220 GUID
*InterfaceGuid
,
1223 PNP_RPC_BUFFER_SIZE
*pulLength
,
1227 return CR_CALL_NOT_IMPLEMENTED
;
1234 PNP_GetInterfaceDeviceListSize(
1236 PNP_RPC_BUFFER_SIZE
*pulLen
,
1237 GUID
*InterfaceGuid
,
1242 return CR_CALL_NOT_IMPLEMENTED
;
1249 PNP_RegisterDeviceClassAssociation(
1252 GUID
*InterfaceGuid
,
1253 LPWSTR pszReference
,
1255 PNP_RPC_STRING_LEN
*pulLength
,
1256 PNP_RPC_STRING_LEN
*pulTransferLen
,
1260 return CR_CALL_NOT_IMPLEMENTED
;
1267 PNP_UnregisterDeviceClassAssociation(
1269 LPWSTR pszInterfaceDevice
,
1273 return CR_CALL_NOT_IMPLEMENTED
;
1280 PNP_GetClassRegProp(
1282 LPWSTR pszClassGuid
,
1284 DWORD
*pulRegDataType
,
1286 PNP_RPC_STRING_LEN
*pulTransferLen
,
1287 PNP_RPC_STRING_LEN
*pulLength
,
1290 CONFIGRET ret
= CR_SUCCESS
;
1291 LPWSTR lpValueName
= NULL
;
1292 HKEY hInstKey
= NULL
;
1293 HKEY hPropKey
= NULL
;
1296 UNREFERENCED_PARAMETER(hBinding
);
1298 DPRINT("PNP_GetClassRegProp() called\n");
1300 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1302 ret
= CR_INVALID_POINTER
;
1308 ret
= CR_INVALID_FLAG
;
1312 if (*pulLength
< *pulTransferLen
)
1313 *pulLength
= *pulTransferLen
;
1315 *pulTransferLen
= 0;
1319 case CM_CRP_SECURITY
:
1320 lpValueName
= L
"Security";
1323 case CM_CRP_DEVTYPE
:
1324 lpValueName
= L
"DeviceType";
1327 case CM_CRP_EXCLUSIVE
:
1328 lpValueName
= L
"Exclusive";
1331 case CM_CRP_CHARACTERISTICS
:
1332 lpValueName
= L
"DeviceCharacteristics";
1336 ret
= CR_INVALID_PROPERTY
;
1340 DPRINT("Value name: %S\n", lpValueName
);
1342 lError
= RegOpenKeyExW(hClassKey
,
1347 if (lError
!= ERROR_SUCCESS
)
1350 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1354 lError
= RegOpenKeyExW(hInstKey
,
1359 if (lError
!= ERROR_SUCCESS
)
1362 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1366 lError
= RegQueryValueExW(hPropKey
,
1372 if (lError
!= ERROR_SUCCESS
)
1374 if (lError
== ERROR_MORE_DATA
)
1376 ret
= CR_BUFFER_SMALL
;
1381 ret
= CR_NO_SUCH_VALUE
;
1386 if (ret
== CR_SUCCESS
)
1387 *pulTransferLen
= *pulLength
;
1389 if (hPropKey
!= NULL
)
1390 RegCloseKey(hPropKey
);
1392 if (hInstKey
!= NULL
)
1393 RegCloseKey(hInstKey
);
1395 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1404 PNP_SetClassRegProp(
1406 LPWSTR pszClassGuid
,
1410 PNP_PROP_SIZE ulLength
,
1413 CONFIGRET ret
= CR_SUCCESS
;
1414 LPWSTR lpValueName
= NULL
;
1419 UNREFERENCED_PARAMETER(hBinding
);
1421 DPRINT("PNP_SetClassRegProp() called\n");
1424 return CR_INVALID_FLAG
;
1428 case CM_CRP_SECURITY
:
1429 lpValueName
= L
"Security";
1432 case CM_CRP_DEVTYPE
:
1433 lpValueName
= L
"DeviceType";
1436 case CM_CRP_EXCLUSIVE
:
1437 lpValueName
= L
"Exclusive";
1440 case CM_CRP_CHARACTERISTICS
:
1441 lpValueName
= L
"DeviceCharacteristics";
1445 return CR_INVALID_PROPERTY
;
1448 lError
= RegOpenKeyExW(hClassKey
,
1453 if (lError
!= ERROR_SUCCESS
)
1455 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1459 /* FIXME: Set security descriptor */
1460 lError
= RegCreateKeyExW(hInstKey
,
1464 REG_OPTION_NON_VOLATILE
,
1469 if (lError
!= ERROR_SUCCESS
)
1471 ret
= CR_REGISTRY_ERROR
;
1477 if (RegDeleteValueW(hPropKey
,
1479 ret
= CR_REGISTRY_ERROR
;
1483 if (RegSetValueExW(hPropKey
,
1489 ret
= CR_REGISTRY_ERROR
;
1493 if (hPropKey
!= NULL
)
1494 RegCloseKey(hPropKey
);
1496 if (hInstKey
!= NULL
)
1497 RegCloseKey(hInstKey
);
1504 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1505 OUT LPWSTR pszEnumerator
,
1506 OUT LPWSTR pszDevice
,
1507 OUT LPWSTR pszInstance
)
1509 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1510 LPWSTR lpEnumerator
= NULL
;
1511 LPWSTR lpDevice
= NULL
;
1512 LPWSTR lpInstance
= NULL
;
1515 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1521 lpEnumerator
= szLocalDeviceInstanceID
;
1523 ptr
= wcschr(lpEnumerator
, L
'\\');
1529 ptr
= wcschr(lpDevice
, L
'\\');
1537 if (lpEnumerator
!= NULL
)
1538 wcscpy(pszEnumerator
, lpEnumerator
);
1540 if (lpDevice
!= NULL
)
1541 wcscpy(pszDevice
, lpDevice
);
1543 if (lpInstance
!= NULL
)
1544 wcscpy(pszInstance
, lpInstance
);
1549 CreateDeviceInstance(LPWSTR pszDeviceID
)
1551 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1552 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1553 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1554 HKEY hKeyEnumerator
;
1560 /* Split the instance ID */
1561 SplitDeviceInstanceID(pszDeviceID
,
1566 /* Open or create the enumerator key */
1567 lError
= RegCreateKeyExW(hEnumKey
,
1571 REG_OPTION_NON_VOLATILE
,
1576 if (lError
!= ERROR_SUCCESS
)
1578 return CR_REGISTRY_ERROR
;
1581 /* Open or create the device key */
1582 lError
= RegCreateKeyExW(hKeyEnumerator
,
1586 REG_OPTION_NON_VOLATILE
,
1592 /* Close the enumerator key */
1593 RegCloseKey(hKeyEnumerator
);
1595 if (lError
!= ERROR_SUCCESS
)
1597 return CR_REGISTRY_ERROR
;
1600 /* Try to open the instance key and fail if it exists */
1601 lError
= RegOpenKeyExW(hKeyDevice
,
1606 if (lError
== ERROR_SUCCESS
)
1608 DPRINT1("Instance %S already exists!\n", szInstance
);
1609 RegCloseKey(hKeyInstance
);
1610 RegCloseKey(hKeyDevice
);
1611 return CR_ALREADY_SUCH_DEVINST
;
1614 /* Create a new instance key */
1615 lError
= RegCreateKeyExW(hKeyDevice
,
1619 REG_OPTION_NON_VOLATILE
,
1625 /* Close the device key */
1626 RegCloseKey(hKeyDevice
);
1628 if (lError
!= ERROR_SUCCESS
)
1630 return CR_REGISTRY_ERROR
;
1633 /* Create the 'Control' sub key */
1634 lError
= RegCreateKeyExW(hKeyInstance
,
1638 REG_OPTION_NON_VOLATILE
,
1643 if (lError
== ERROR_SUCCESS
)
1645 RegCloseKey(hKeyControl
);
1648 RegCloseKey(hKeyInstance
);
1650 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1660 LPWSTR pszParentDeviceID
,
1661 PNP_RPC_STRING_LEN ulLength
,
1664 CONFIGRET ret
= CR_SUCCESS
;
1666 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1668 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1670 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1671 DWORD dwInstanceNumber
;
1673 /* Generated ID is: Root\<Device ID>\<Instance number> */
1674 dwInstanceNumber
= 0;
1677 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1678 pszDeviceID
, dwInstanceNumber
);
1680 /* Try to create a device instance with this ID */
1681 ret
= CreateDeviceInstance(szGeneratedInstance
);
1685 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1687 if (ret
== CR_SUCCESS
)
1689 /* pszDeviceID is an out parameter too for generated IDs */
1690 if (wcslen(szGeneratedInstance
) > ulLength
)
1692 ret
= CR_BUFFER_SMALL
;
1696 wcscpy(pszDeviceID
, szGeneratedInstance
);
1702 /* Create the device instance */
1703 ret
= CreateDeviceInstance(pszDeviceID
);
1706 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1713 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1714 LPWSTR pszDeviceInstanceSource
)
1716 DPRINT("MoveDeviceInstance: not implemented\n");
1718 return CR_CALL_NOT_IMPLEMENTED
;
1723 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1726 DPRINT("SetupDeviceInstance: not implemented\n");
1728 return CR_CALL_NOT_IMPLEMENTED
;
1733 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1735 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1736 CONFIGRET ret
= CR_SUCCESS
;
1739 DPRINT("Enable device instance\n");
1741 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1742 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1743 if (!NT_SUCCESS(Status
))
1744 ret
= NtStatusToCrError(Status
);
1751 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1753 DPRINT("DisableDeviceInstance: not implemented\n");
1755 return CR_CALL_NOT_IMPLEMENTED
;
1760 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1762 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1764 return CR_CALL_NOT_IMPLEMENTED
;
1771 PNP_DeviceInstanceAction(
1775 LPWSTR pszDeviceInstance1
,
1776 LPWSTR pszDeviceInstance2
)
1778 CONFIGRET ret
= CR_SUCCESS
;
1780 UNREFERENCED_PARAMETER(hBinding
);
1782 DPRINT("PNP_DeviceInstanceAction() called\n");
1786 case PNP_DEVINST_MOVE
:
1787 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1788 pszDeviceInstance2
);
1791 case PNP_DEVINST_SETUP
:
1792 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1796 case PNP_DEVINST_ENABLE
:
1797 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1800 case PNP_DEVINST_DISABLE
:
1801 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1804 case PNP_DEVINST_REENUMERATE
:
1805 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
1809 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
1810 ret
= CR_CALL_NOT_IMPLEMENTED
;
1813 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1822 PNP_GetDeviceStatus(
1829 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1830 CONFIGRET ret
= CR_SUCCESS
;
1833 UNREFERENCED_PARAMETER(hBinding
);
1834 UNREFERENCED_PARAMETER(ulFlags
);
1836 DPRINT("PNP_GetDeviceStatus() called\n");
1838 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1840 PlugPlayData
.Operation
= 0; /* Get status */
1842 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1843 (PVOID
)&PlugPlayData
,
1844 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1845 if (NT_SUCCESS(Status
))
1847 *pulStatus
= PlugPlayData
.DeviceStatus
;
1848 *pulProblem
= PlugPlayData
.DeviceProblem
;
1852 ret
= NtStatusToCrError(Status
);
1855 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1864 PNP_SetDeviceProblem(
1871 return CR_CALL_NOT_IMPLEMENTED
;
1881 PPNP_VETO_TYPE pVetoType
,
1887 return CR_CALL_NOT_IMPLEMENTED
;
1893 PNP_UninstallDevInst(
1899 return CR_CALL_NOT_IMPLEMENTED
;
1904 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1910 lpPtr
= lpDeviceIdList
;
1913 dwLength
= wcslen(lpPtr
);
1914 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1917 lpPtr
+= (dwLength
+ 1);
1925 AppendDeviceId(LPWSTR lpDeviceIdList
,
1926 LPDWORD lpDeviceIdListSize
,
1932 dwLen
= wcslen(lpDeviceId
);
1933 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1935 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1937 dwPos
+= (dwLen
+ 1);
1939 lpDeviceIdList
[dwPos
] = 0;
1941 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1954 CONFIGRET ret
= CR_SUCCESS
;
1957 DWORD dwDeviceIdListSize
;
1958 DWORD dwNewDeviceIdSize
;
1959 WCHAR
* pszDeviceIdList
= NULL
;
1961 UNREFERENCED_PARAMETER(hBinding
);
1963 DPRINT("PNP_AddID() called\n");
1964 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
1965 DPRINT(" DeviceId: %S\n", pszID
);
1966 DPRINT(" Flags: %lx\n", ulFlags
);
1968 if (RegOpenKeyExW(hEnumKey
,
1971 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1972 &hDeviceKey
) != ERROR_SUCCESS
)
1974 DPRINT("Failed to open the device key!\n");
1975 return CR_INVALID_DEVNODE
;
1978 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1980 if (RegQueryValueExW(hDeviceKey
,
1985 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1987 DPRINT("Failed to query the desired ID string!\n");
1988 ret
= CR_REGISTRY_ERROR
;
1992 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
1993 if (!dwNewDeviceIdSize
)
1995 ret
= CR_INVALID_POINTER
;
1999 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2001 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2002 if (!pszDeviceIdList
)
2004 DPRINT("Failed to allocate memory for the desired ID string!\n");
2005 ret
= CR_OUT_OF_MEMORY
;
2009 if (RegQueryValueExW(hDeviceKey
,
2013 (LPBYTE
)pszDeviceIdList
,
2014 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2016 DPRINT("Failed to query the desired ID string!\n");
2017 ret
= CR_REGISTRY_ERROR
;
2021 /* Check whether the device ID is already in use */
2022 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2024 DPRINT("Device ID was found in the ID string!\n");
2029 /* Append the Device ID */
2030 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2032 if (RegSetValueExW(hDeviceKey
,
2036 (LPBYTE
)pszDeviceIdList
,
2037 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2039 DPRINT("Failed to set the desired ID string!\n");
2040 ret
= CR_REGISTRY_ERROR
;
2044 RegCloseKey(hDeviceKey
);
2045 if (pszDeviceIdList
)
2046 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2048 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2063 return CR_CALL_NOT_IMPLEMENTED
;
2073 PPNP_VETO_TYPE pVetoType
,
2079 return CR_CALL_NOT_IMPLEMENTED
;
2086 PNP_RequestDeviceEject(
2089 PPNP_VETO_TYPE pVetoType
,
2095 return CR_CALL_NOT_IMPLEMENTED
;
2102 PNP_IsDockStationPresent(
2110 CONFIGRET ret
= CR_SUCCESS
;
2112 UNREFERENCED_PARAMETER(hBinding
);
2114 DPRINT1("PNP_IsDockStationPresent() called\n");
2118 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2122 &hKey
) != ERROR_SUCCESS
)
2123 return CR_REGISTRY_ERROR
;
2125 dwSize
= sizeof(DWORD
);
2126 if (RegQueryValueExW(hKey
,
2131 &dwSize
) != ERROR_SUCCESS
)
2132 ret
= CR_REGISTRY_ERROR
;
2136 if (ret
== CR_SUCCESS
)
2138 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2140 ret
= CR_REGISTRY_ERROR
;
2142 else if (dwValue
!= 0)
2148 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2161 return CR_CALL_NOT_IMPLEMENTED
;
2174 PPNP_VETO_TYPE pVetoType
,
2179 CONFIGRET ret
= CR_SUCCESS
;
2180 WCHAR szKeyName
[MAX_PATH
];
2185 UNREFERENCED_PARAMETER(hBinding
);
2187 DPRINT("PNP_HwProfFlags() called\n");
2192 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2197 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2201 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2205 &hKey
) != ERROR_SUCCESS
)
2206 return CR_REGISTRY_ERROR
;
2208 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2210 if (RegOpenKeyExW(hKey
,
2214 &hDeviceKey
) != ERROR_SUCCESS
)
2220 dwSize
= sizeof(DWORD
);
2221 if (!RegQueryValueExW(hDeviceKey
,
2226 &dwSize
) != ERROR_SUCCESS
)
2231 RegCloseKey(hDeviceKey
);
2234 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2236 /* FIXME: not implemented yet */
2237 ret
= CR_CALL_NOT_IMPLEMENTED
;
2252 HWPROFILEINFO
*pHWProfileInfo
,
2253 DWORD ulProfileInfoSize
,
2256 WCHAR szProfileName
[5];
2257 HKEY hKeyConfig
= NULL
;
2258 HKEY hKeyProfiles
= NULL
;
2259 HKEY hKeyProfile
= NULL
;
2260 DWORD dwDisposition
;
2263 CONFIGRET ret
= CR_SUCCESS
;
2265 UNREFERENCED_PARAMETER(hBinding
);
2267 DPRINT("PNP_GetHwProfInfo() called\n");
2269 if (ulProfileInfoSize
== 0)
2271 ret
= CR_INVALID_DATA
;
2277 ret
= CR_INVALID_FLAG
;
2281 /* Initialize the profile information */
2282 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2283 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2284 pHWProfileInfo
->HWPI_dwFlags
= 0;
2286 /* Open the 'IDConfigDB' key */
2287 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2288 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2291 REG_OPTION_NON_VOLATILE
,
2296 if (lError
!= ERROR_SUCCESS
)
2298 ret
= CR_REGISTRY_ERROR
;
2302 /* Open the 'Hardware Profiles' subkey */
2303 lError
= RegCreateKeyExW(hKeyConfig
,
2304 L
"Hardware Profiles",
2307 REG_OPTION_NON_VOLATILE
,
2308 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2312 if (lError
!= ERROR_SUCCESS
)
2314 ret
= CR_REGISTRY_ERROR
;
2318 if (ulIndex
== (ULONG
)-1)
2320 dwSize
= sizeof(ULONG
);
2321 lError
= RegQueryValueExW(hKeyConfig
,
2325 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2327 if (lError
!= ERROR_SUCCESS
)
2329 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2330 ret
= CR_REGISTRY_ERROR
;
2336 /* FIXME: not implemented yet */
2337 ret
= CR_CALL_NOT_IMPLEMENTED
;
2341 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2343 lError
= RegOpenKeyExW(hKeyProfiles
,
2348 if (lError
!= ERROR_SUCCESS
)
2350 ret
= CR_REGISTRY_ERROR
;
2354 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2355 lError
= RegQueryValueExW(hKeyProfile
,
2359 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2361 if (lError
!= ERROR_SUCCESS
)
2363 ret
= CR_REGISTRY_ERROR
;
2368 if (hKeyProfile
!= NULL
)
2369 RegCloseKey(hKeyProfile
);
2371 if (hKeyProfiles
!= NULL
)
2372 RegCloseKey(hKeyProfiles
);
2374 if (hKeyConfig
!= NULL
)
2375 RegCloseKey(hKeyConfig
);
2384 PNP_AddEmptyLogConf(
2388 DWORD
*pulLogConfTag
,
2392 return CR_CALL_NOT_IMPLEMENTED
;
2402 DWORD ulLogConfType
,
2407 return CR_CALL_NOT_IMPLEMENTED
;
2414 PNP_GetFirstLogConf(
2417 DWORD ulLogConfType
,
2418 DWORD
*pulLogConfTag
,
2422 return CR_CALL_NOT_IMPLEMENTED
;
2432 DWORD ulLogConfType
,
2438 return CR_CALL_NOT_IMPLEMENTED
;
2445 PNP_GetLogConfPriority(
2454 return CR_CALL_NOT_IMPLEMENTED
;
2465 DWORD ulLogConfType
,
2466 RESOURCEID ResourceID
,
2467 DWORD
*pulResourceTag
,
2469 PNP_RPC_BUFFER_SIZE ResourceLen
,
2473 return CR_CALL_NOT_IMPLEMENTED
;
2484 DWORD ulLogConfType
,
2485 RESOURCEID ResourceID
,
2486 DWORD ulResourceTag
,
2487 DWORD
*pulPreviousResType
,
2488 DWORD
*pulPreviousResTag
,
2492 return CR_CALL_NOT_IMPLEMENTED
;
2503 DWORD ulLogConfType
,
2504 RESOURCEID ResourceID
,
2505 DWORD ulResourceTag
,
2506 DWORD
*pulNextResType
,
2507 DWORD
*pulNextResTag
,
2511 return CR_CALL_NOT_IMPLEMENTED
;
2522 DWORD ulLogConfType
,
2523 RESOURCEID ResourceID
,
2524 DWORD ulResourceTag
,
2526 PNP_RPC_BUFFER_SIZE BufferLen
,
2530 return CR_CALL_NOT_IMPLEMENTED
;
2537 PNP_GetResDesDataSize(
2541 DWORD ulLogConfType
,
2542 RESOURCEID ResourceID
,
2543 DWORD ulResourceTag
,
2548 return CR_CALL_NOT_IMPLEMENTED
;
2559 DWORD ulLogConfType
,
2560 RESOURCEID CurrentResourceID
,
2561 RESOURCEID NewResourceID
,
2562 DWORD ulResourceTag
,
2564 PNP_RPC_BUFFER_SIZE ResourceLen
,
2568 return CR_CALL_NOT_IMPLEMENTED
;
2575 PNP_DetectResourceConflict(
2578 RESOURCEID ResourceID
,
2580 PNP_RPC_BUFFER_SIZE ResourceLen
,
2581 BOOL
*pbConflictDetected
,
2585 return CR_CALL_NOT_IMPLEMENTED
;
2592 PNP_QueryResConfList(
2595 RESOURCEID ResourceID
,
2597 PNP_RPC_BUFFER_SIZE ResourceLen
,
2599 PNP_RPC_BUFFER_SIZE BufferLen
,
2603 return CR_CALL_NOT_IMPLEMENTED
;
2612 DWORD ulHardwareProfile
,
2616 return CR_CALL_NOT_IMPLEMENTED
;
2623 PNP_QueryArbitratorFreeData(
2628 RESOURCEID ResourceID
,
2632 return CR_CALL_NOT_IMPLEMENTED
;
2639 PNP_QueryArbitratorFreeSize(
2643 RESOURCEID ResourceID
,
2647 return CR_CALL_NOT_IMPLEMENTED
;
2658 return CR_CALL_NOT_IMPLEMENTED
;
2665 PNP_RegisterNotification(
2669 return CR_CALL_NOT_IMPLEMENTED
;
2676 PNP_UnregisterNotification(
2680 return CR_CALL_NOT_IMPLEMENTED
;
2687 PNP_GetCustomDevProp(
2690 LPWSTR CustomPropName
,
2691 DWORD
*pulRegDataType
,
2693 PNP_RPC_STRING_LEN
*pulTransferLen
,
2694 PNP_RPC_STRING_LEN
*pulLength
,
2697 HKEY hDeviceKey
= NULL
;
2698 HKEY hParamKey
= NULL
;
2700 CONFIGRET ret
= CR_SUCCESS
;
2702 UNREFERENCED_PARAMETER(hBinding
);
2704 DPRINT("PNP_GetCustomDevProp() called\n");
2706 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2708 ret
= CR_INVALID_POINTER
;
2712 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2714 ret
= CR_INVALID_FLAG
;
2718 if (*pulLength
< *pulTransferLen
)
2719 *pulLength
= *pulTransferLen
;
2721 *pulTransferLen
= 0;
2723 lError
= RegOpenKeyExW(hEnumKey
,
2728 if (lError
!= ERROR_SUCCESS
)
2730 ret
= CR_REGISTRY_ERROR
;
2734 lError
= RegOpenKeyExW(hDeviceKey
,
2735 L
"Device Parameters",
2739 if (lError
!= ERROR_SUCCESS
)
2741 ret
= CR_REGISTRY_ERROR
;
2745 lError
= RegQueryValueExW(hParamKey
,
2751 if (lError
!= ERROR_SUCCESS
)
2753 if (lError
== ERROR_MORE_DATA
)
2755 ret
= CR_BUFFER_SMALL
;
2760 ret
= CR_NO_SUCH_VALUE
;
2765 if (ret
== CR_SUCCESS
)
2766 *pulTransferLen
= *pulLength
;
2768 if (hParamKey
!= NULL
)
2769 RegCloseKey(hParamKey
);
2771 if (hDeviceKey
!= NULL
)
2772 RegCloseKey(hDeviceKey
);
2774 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
2783 PNP_GetVersionInternal(
2795 PNP_GetBlockedDriverInfo(
2798 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
2799 PNP_RPC_BUFFER_SIZE
*pulLength
,
2803 return CR_CALL_NOT_IMPLEMENTED
;
2810 PNP_GetServerSideDeviceInstallFlags(
2812 DWORD
*pulSSDIFlags
,
2816 return CR_CALL_NOT_IMPLEMENTED
;
2823 PNP_GetObjectPropKeys(
2827 LPWSTR PropertyCultureName
,
2828 PNP_PROP_COUNT
*PropertyCount
,
2829 PNP_PROP_COUNT
*TransferLen
,
2830 DEVPROPKEY
*PropertyKeys
,
2834 return CR_CALL_NOT_IMPLEMENTED
;
2845 LPWSTR PropertyCultureName
,
2846 const DEVPROPKEY
*PropertyKey
,
2847 DEVPROPTYPE
*PropertyType
,
2848 PNP_PROP_SIZE
*PropertySize
,
2849 PNP_PROP_SIZE
*TransferLen
,
2850 BYTE
*PropertyBuffer
,
2854 return CR_CALL_NOT_IMPLEMENTED
;
2865 LPWSTR PropertyCultureName
,
2866 const DEVPROPKEY
*PropertyKey
,
2867 DEVPROPTYPE PropertyType
,
2868 PNP_PROP_SIZE PropertySize
,
2869 BYTE
*PropertyBuffer
,
2873 return CR_CALL_NOT_IMPLEMENTED
;
2884 return CR_CALL_NOT_IMPLEMENTED
;
2891 PNP_ApplyPowerSettings(
2895 return CR_CALL_NOT_IMPLEMENTED
;
2902 PNP_DriverStoreAddDriverPackage(
2906 return CR_CALL_NOT_IMPLEMENTED
;
2913 PNP_DriverStoreDeleteDriverPackage(
2917 return CR_CALL_NOT_IMPLEMENTED
;
2924 PNP_RegisterServiceNotification(
2928 return CR_CALL_NOT_IMPLEMENTED
;
2935 PNP_SetActiveService(
2941 return CR_CALL_NOT_IMPLEMENTED
;
2948 PNP_DeleteServiceDevices(
2952 return CR_CALL_NOT_IMPLEMENTED
;
2957 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
2959 BOOL DeviceInstalled
= FALSE
;
2962 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
2963 LPVOID Environment
= NULL
;
2964 PROCESS_INFORMATION ProcessInfo
;
2965 STARTUPINFOW StartupInfo
;
2969 /* The following lengths are constant (see below), they cannot overflow */
2970 WCHAR CommandLine
[116];
2971 WCHAR InstallEventName
[73];
2973 WCHAR UuidString
[39];
2975 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
2977 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
2979 if (RegOpenKeyExW(hEnumKey
,
2983 &DeviceKey
) == ERROR_SUCCESS
)
2985 if (RegQueryValueExW(DeviceKey
,
2990 NULL
) == ERROR_SUCCESS
)
2992 DPRINT("No need to install: %S\n", DeviceInstance
);
2993 RegCloseKey(DeviceKey
);
2997 RegCloseKey(DeviceKey
);
3000 DPRINT1("Installing: %S\n", DeviceInstance
);
3002 /* Create a random UUID for the named pipe */
3003 UuidCreate(&RandomUuid
);
3004 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3005 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3006 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3007 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3008 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3010 /* Create the named pipe */
3011 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3012 wcscat(PipeName
, UuidString
);
3013 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3015 if(hPipe
== INVALID_HANDLE_VALUE
)
3017 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3021 /* Launch rundll32 to call ClientSideInstallW */
3022 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3023 wcscat(CommandLine
, PipeName
);
3025 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3026 StartupInfo
.cb
= sizeof(StartupInfo
);
3030 /* newdev has to run under the environment of the current user */
3031 if(!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3033 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3037 if(!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3039 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3045 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3047 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3048 (ShowWizard is only set to FALSE for these two modes) */
3049 ASSERT(!ShowWizard
);
3051 if(!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3053 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3058 /* Wait for the function to connect to our pipe */
3059 if(!ConnectNamedPipe(hPipe
, NULL
))
3061 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3063 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3068 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3069 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3070 wcscat(InstallEventName
, UuidString
);
3072 Value
= sizeof(InstallEventName
);
3073 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3074 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3076 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3077 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3078 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3080 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3081 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3082 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3084 /* Wait for newdev.dll to finish processing */
3085 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3087 /* The following check for success is probably not compatible to Windows, but should do its job */
3088 if(!GetExitCodeProcess(ProcessInfo
.hProcess
, &Value
))
3090 DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
3094 DeviceInstalled
= Value
;
3097 if(hPipe
!= INVALID_HANDLE_VALUE
)
3101 DestroyEnvironmentBlock(Environment
);
3103 if(ProcessInfo
.hProcess
)
3104 CloseHandle(ProcessInfo
.hProcess
);
3106 if(ProcessInfo
.hThread
)
3107 CloseHandle(ProcessInfo
.hThread
);
3109 if (!DeviceInstalled
)
3111 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3114 return DeviceInstalled
;
3130 return ERROR_INVALID_PARAMETER
;
3133 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3134 if (rc
!= ERROR_SUCCESS
)
3136 if (dwType
!= REG_SZ
)
3137 return ERROR_FILE_NOT_FOUND
;
3138 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3140 return ERROR_NOT_ENOUGH_MEMORY
;
3141 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3142 if (rc
!= ERROR_SUCCESS
)
3144 HeapFree(GetProcessHeap(), 0, Value
);
3147 /* NULL-terminate the string */
3148 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3151 return ERROR_SUCCESS
;
3159 DWORD regType
, active
, size
;
3163 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3164 if (rc
!= ERROR_SUCCESS
)
3167 size
= sizeof(DWORD
);
3168 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3169 if (rc
!= ERROR_SUCCESS
)
3171 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3174 ret
= (active
!= 0);
3180 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3189 HKEY ControlKey
= NULL
;
3190 LPWSTR SystemStartOptions
= NULL
;
3191 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3192 BOOL ConsoleBoot
= FALSE
;
3197 L
"SYSTEM\\CurrentControlSet\\Control",
3202 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3203 if (rc
!= ERROR_SUCCESS
)
3206 /* Check for CONSOLE switch in SystemStartOptions */
3207 CurrentOption
= SystemStartOptions
;
3208 while (CurrentOption
)
3210 NextOption
= wcschr(CurrentOption
, L
' ');
3212 *NextOption
= L
'\0';
3213 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3215 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3219 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3223 if (ControlKey
!= NULL
)
3224 RegCloseKey(ControlKey
);
3225 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3230 /* Loop to install all queued devices installations */
3232 DeviceInstallThread(LPVOID lpParameter
)
3234 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3235 PSLIST_ENTRY ListEntry
;
3237 PLIST_ENTRY ListEntry
;
3239 DeviceInstallParams
* Params
;
3242 UNREFERENCED_PARAMETER(lpParameter
);
3244 WaitForSingleObject(hInstallEvent
, INFINITE
);
3246 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3250 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3251 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3253 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3256 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3258 if (ListEntry
== NULL
)
3260 SetEvent(hNoPendingInstalls
);
3261 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3265 ResetEvent(hNoPendingInstalls
);
3266 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3267 InstallDevice(Params
->DeviceIds
, showWizard
);
3276 PnpEventThread(LPVOID lpParameter
)
3278 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3281 RPC_STATUS RpcStatus
;
3283 UNREFERENCED_PARAMETER(lpParameter
);
3285 PnpEventSize
= 0x1000;
3286 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3287 if (PnpEvent
== NULL
)
3288 return ERROR_OUTOFMEMORY
;
3292 DPRINT("Calling NtGetPlugPlayEvent()\n");
3294 /* Wait for the next pnp event */
3295 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3297 /* Resize the buffer for the PnP event if it's too small. */
3298 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3300 PnpEventSize
+= 0x400;
3301 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3302 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3303 if (PnpEvent
== NULL
)
3304 return ERROR_OUTOFMEMORY
;
3308 if (!NT_SUCCESS(Status
))
3310 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3314 /* Process the pnp event */
3315 DPRINT("Received PnP Event\n");
3316 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3318 DeviceInstallParams
* Params
;
3320 DWORD DeviceIdLength
;
3322 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3324 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3327 /* Queue device install (will be dequeued by DeviceInstallThread */
3328 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3329 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3332 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3333 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3334 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3336 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3338 SetEvent(hDeviceInstallListNotEmpty
);
3342 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3344 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3347 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3349 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3351 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3353 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3355 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3357 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3359 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3361 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3363 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3365 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3367 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3369 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3373 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3374 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3375 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3376 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3377 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3380 /* Dequeue the current pnp event and signal the next one */
3381 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3384 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3386 return ERROR_SUCCESS
;
3391 UpdateServiceStatus(DWORD dwState
)
3393 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3394 ServiceStatus
.dwCurrentState
= dwState
;
3395 ServiceStatus
.dwControlsAccepted
= 0;
3396 ServiceStatus
.dwWin32ExitCode
= 0;
3397 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3398 ServiceStatus
.dwCheckPoint
= 0;
3400 if (dwState
== SERVICE_START_PENDING
||
3401 dwState
== SERVICE_STOP_PENDING
||
3402 dwState
== SERVICE_PAUSE_PENDING
||
3403 dwState
== SERVICE_CONTINUE_PENDING
)
3404 ServiceStatus
.dwWaitHint
= 10000;
3406 ServiceStatus
.dwWaitHint
= 0;
3408 SetServiceStatus(ServiceStatusHandle
,
3414 ServiceControlHandler(DWORD dwControl
,
3419 DPRINT1("ServiceControlHandler() called\n");
3423 case SERVICE_CONTROL_STOP
:
3424 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3425 /* Stop listening to RPC Messages */
3426 RpcMgmtStopServerListening(NULL
);
3427 UpdateServiceStatus(SERVICE_STOPPED
);
3428 return ERROR_SUCCESS
;
3430 case SERVICE_CONTROL_PAUSE
:
3431 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3432 UpdateServiceStatus(SERVICE_PAUSED
);
3433 return ERROR_SUCCESS
;
3435 case SERVICE_CONTROL_CONTINUE
:
3436 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3437 UpdateServiceStatus(SERVICE_RUNNING
);
3438 return ERROR_SUCCESS
;
3440 case SERVICE_CONTROL_INTERROGATE
:
3441 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3442 SetServiceStatus(ServiceStatusHandle
,
3444 return ERROR_SUCCESS
;
3446 case SERVICE_CONTROL_SHUTDOWN
:
3447 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3448 /* Stop listening to RPC Messages */
3449 RpcMgmtStopServerListening(NULL
);
3450 UpdateServiceStatus(SERVICE_STOPPED
);
3451 return ERROR_SUCCESS
;
3454 DPRINT1(" Control %lu received\n");
3455 return ERROR_CALL_NOT_IMPLEMENTED
;
3461 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3466 UNREFERENCED_PARAMETER(argc
);
3467 UNREFERENCED_PARAMETER(argv
);
3469 DPRINT("ServiceMain() called\n");
3471 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3472 ServiceControlHandler
,
3474 if (!ServiceStatusHandle
)
3476 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3480 UpdateServiceStatus(SERVICE_START_PENDING
);
3482 hThread
= CreateThread(NULL
,
3488 if (hThread
!= NULL
)
3489 CloseHandle(hThread
);
3491 hThread
= CreateThread(NULL
,
3497 if (hThread
!= NULL
)
3498 CloseHandle(hThread
);
3500 hThread
= CreateThread(NULL
,
3502 DeviceInstallThread
,
3506 if (hThread
!= NULL
)
3507 CloseHandle(hThread
);
3509 UpdateServiceStatus(SERVICE_RUNNING
);
3511 DPRINT("ServiceMain() done\n");
3515 InitializePnPManager(VOID
)
3520 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3522 /* We need this privilege for using CreateProcessAsUserW */
3523 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3525 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3526 if (hInstallEvent
== NULL
)
3528 dwError
= GetLastError();
3529 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3533 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3534 if (hDeviceInstallListNotEmpty
== NULL
)
3536 dwError
= GetLastError();
3537 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3541 hNoPendingInstalls
= CreateEventW(NULL
,
3544 L
"Global\\PnP_No_Pending_Install_Events");
3545 if (hNoPendingInstalls
== NULL
)
3547 dwError
= GetLastError();
3548 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3552 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3553 InitializeSListHead(&DeviceInstallListHead
);
3555 InitializeListHead(&DeviceInstallListHead
);
3558 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3559 L
"System\\CurrentControlSet\\Enum",
3563 if (dwError
!= ERROR_SUCCESS
)
3565 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3569 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3570 L
"System\\CurrentControlSet\\Control\\Class",
3574 if (dwError
!= ERROR_SUCCESS
)
3576 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3580 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3586 DllMain(HINSTANCE hinstDLL
,
3592 case DLL_PROCESS_ATTACH
:
3593 DisableThreadLibraryCalls(hinstDLL
);
3594 InitializePnPManager();
3597 case DLL_PROCESS_DETACH
: