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 *****************************************************************/
30 //#define HAVE_SLIST_ENTRY_IMPLEMENTED
31 #define WIN32_NO_STATUS
38 #include <umpnpmgr/sysguid.h>
52 /* GLOBALS ******************************************************************/
55 ServiceMain(DWORD argc
, LPTSTR
*argv
);
57 static SERVICE_TABLE_ENTRY ServiceTable
[2] =
59 {TEXT("PlugPlay"), ServiceMain
},
63 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
65 static HKEY hEnumKey
= NULL
;
66 static HKEY hClassKey
= NULL
;
68 static HANDLE hUserToken
= NULL
;
69 static HANDLE hInstallEvent
= NULL
;
70 static HANDLE hNoPendingInstalls
= NULL
;
72 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
73 static SLIST_HEADER DeviceInstallListHead
;
75 static LIST_ENTRY DeviceInstallListHead
;
77 static HANDLE hDeviceInstallListNotEmpty
;
81 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
82 SLIST_ENTRY ListEntry
;
87 } DeviceInstallParams
;
89 /* FUNCTIONS *****************************************************************/
92 RpcServerThread(LPVOID lpParameter
)
96 UNREFERENCED_PARAMETER(lpParameter
);
98 DPRINT("RpcServerThread() called\n");
100 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
103 NULL
); // Security descriptor
104 if (Status
!= RPC_S_OK
)
106 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
110 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
113 if (Status
!= RPC_S_OK
)
115 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
119 Status
= RpcServerListen(1,
122 if (Status
!= RPC_S_OK
)
124 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
128 /* ROS HACK (this should never happen...) */
129 DPRINT1("*** Other devices won't be installed correctly. If something\n");
130 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
132 DPRINT("RpcServerThread() done\n");
138 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
140 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
144 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
146 HeapFree(GetProcessHeap(), 0, ptr
);
150 static CONFIGRET WINAPI
151 NtStatusToCrError(NTSTATUS Status
)
155 case STATUS_NO_SUCH_DEVICE
:
156 return CR_NO_SUCH_DEVINST
;
159 /* FIXME: add more mappings */
160 DPRINT1("Unable to map status 0x%08lx\n", Status
);
167 DWORD
PNP_Disconnect(
170 UNREFERENCED_PARAMETER(hBinding
);
172 return CR_CALL_NOT_IMPLEMENTED
;
180 UNREFERENCED_PARAMETER(hBinding
);
182 return CR_CALL_NOT_IMPLEMENTED
;
187 DWORD
PNP_GetVersion(
191 UNREFERENCED_PARAMETER(hBinding
);
199 DWORD
PNP_GetGlobalState(
204 UNREFERENCED_PARAMETER(hBinding
);
205 UNREFERENCED_PARAMETER(ulFlags
);
207 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
213 DWORD
PNP_InitDetection(
216 UNREFERENCED_PARAMETER(hBinding
);
218 DPRINT("PNP_InitDetection() called\n");
224 DWORD
PNP_ReportLogOn(
229 DWORD ReturnValue
= CR_FAILURE
;
232 UNREFERENCED_PARAMETER(hBinding
);
233 UNREFERENCED_PARAMETER(Admin
);
235 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
237 /* Get the users token */
238 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
242 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
248 CloseHandle(hUserToken
);
252 if(!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
254 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
258 /* Trigger the installer thread */
260 SetEvent(hInstallEvent
);
262 ReturnValue
= CR_SUCCESS
;
266 CloseHandle(hProcess
);
273 DWORD
PNP_ValidateDeviceInstance(
278 CONFIGRET ret
= CR_SUCCESS
;
279 HKEY hDeviceKey
= NULL
;
281 UNREFERENCED_PARAMETER(hBinding
);
282 UNREFERENCED_PARAMETER(ulFlags
);
284 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
287 if (RegOpenKeyExW(hEnumKey
,
293 DPRINT("Could not open the Device Key!\n");
294 ret
= CR_NO_SUCH_DEVNODE
;
298 /* FIXME: add more tests */
301 if (hDeviceKey
!= NULL
)
302 RegCloseKey(hDeviceKey
);
304 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
311 DWORD
PNP_GetRootDeviceInstance(
314 PNP_RPC_STRING_LEN ulLength
)
316 CONFIGRET ret
= CR_SUCCESS
;
318 UNREFERENCED_PARAMETER(hBinding
);
320 DPRINT("PNP_GetRootDeviceInstance() called\n");
324 ret
= CR_INVALID_POINTER
;
327 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
329 ret
= CR_BUFFER_SMALL
;
337 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
344 DWORD
PNP_GetRelatedDeviceInstance(
346 DWORD ulRelationship
,
348 LPWSTR pRelatedDeviceId
,
349 PNP_RPC_STRING_LEN
*pulLength
,
352 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
353 CONFIGRET ret
= CR_SUCCESS
;
356 UNREFERENCED_PARAMETER(hBinding
);
357 UNREFERENCED_PARAMETER(ulFlags
);
359 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
360 DPRINT(" Relationship %ld\n", ulRelationship
);
361 DPRINT(" DeviceId %S\n", pDeviceID
);
363 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
366 PlugPlayData
.Relation
= ulRelationship
;
368 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
369 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
371 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
372 (PVOID
)&PlugPlayData
,
373 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
374 if (!NT_SUCCESS(Status
))
376 ret
= NtStatusToCrError(Status
);
379 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
380 if (ret
== CR_SUCCESS
)
382 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
390 DWORD
PNP_EnumerateSubKeys(
395 PNP_RPC_STRING_LEN ulLength
,
396 PNP_RPC_STRING_LEN
*pulRequiredLen
,
399 CONFIGRET ret
= CR_SUCCESS
;
403 UNREFERENCED_PARAMETER(hBinding
);
404 UNREFERENCED_PARAMETER(ulFlags
);
406 DPRINT("PNP_EnumerateSubKeys() called\n");
410 case PNP_ENUMERATOR_SUBKEYS
:
414 case PNP_CLASS_SUBKEYS
:
422 *pulRequiredLen
= ulLength
;
423 dwError
= RegEnumKeyExW(hKey
,
431 if (dwError
!= ERROR_SUCCESS
)
433 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
440 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
447 DWORD
PNP_GetDeviceList(
451 PNP_RPC_STRING_LEN
*pulLength
,
455 return CR_CALL_NOT_IMPLEMENTED
;
460 DWORD
PNP_GetDeviceListSize(
463 PNP_RPC_BUFFER_SIZE
*pulLen
,
467 return CR_CALL_NOT_IMPLEMENTED
;
478 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
479 CONFIGRET ret
= CR_SUCCESS
;
482 UNREFERENCED_PARAMETER(hBinding
);
483 UNREFERENCED_PARAMETER(ulFlags
);
485 DPRINT("PNP_GetDepth() called\n");
487 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
490 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
491 (PVOID
)&PlugPlayData
,
492 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
493 if (NT_SUCCESS(Status
))
495 *pulDepth
= PlugPlayData
.Depth
;
499 ret
= NtStatusToCrError(Status
);
502 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
509 DWORD
PNP_GetDeviceRegProp(
513 DWORD
*pulRegDataType
,
515 PNP_PROP_SIZE
*pulTransferLen
,
516 PNP_PROP_SIZE
*pulLength
,
519 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
520 CONFIGRET ret
= CR_SUCCESS
;
521 LPWSTR lpValueName
= NULL
;
525 UNREFERENCED_PARAMETER(hBinding
);
526 UNREFERENCED_PARAMETER(ulFlags
);
528 DPRINT("PNP_GetDeviceRegProp() called\n");
532 case CM_DRP_DEVICEDESC
:
533 lpValueName
= L
"DeviceDesc";
536 case CM_DRP_HARDWAREID
:
537 lpValueName
= L
"HardwareID";
540 case CM_DRP_COMPATIBLEIDS
:
541 lpValueName
= L
"CompatibleIDs";
545 lpValueName
= L
"Service";
549 lpValueName
= L
"Class";
552 case CM_DRP_CLASSGUID
:
553 lpValueName
= L
"ClassGUID";
557 lpValueName
= L
"Driver";
560 case CM_DRP_CONFIGFLAGS
:
561 lpValueName
= L
"ConfigFlags";
565 lpValueName
= L
"Mfg";
568 case CM_DRP_FRIENDLYNAME
:
569 lpValueName
= L
"FriendlyName";
572 case CM_DRP_LOCATION_INFORMATION
:
573 lpValueName
= L
"LocationInformation";
576 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
580 case CM_DRP_CAPABILITIES
:
581 lpValueName
= L
"Capabilities";
584 case CM_DRP_UI_NUMBER
:
588 case CM_DRP_UPPERFILTERS
:
589 lpValueName
= L
"UpperFilters";
592 case CM_DRP_LOWERFILTERS
:
593 lpValueName
= L
"LowerFilters";
596 case CM_DRP_BUSTYPEGUID
:
600 case CM_DRP_LEGACYBUSTYPE
:
604 case CM_DRP_BUSNUMBER
:
608 case CM_DRP_ENUMERATOR_NAME
:
613 return CR_INVALID_PROPERTY
;
616 DPRINT("Value name: %S\n", lpValueName
);
620 /* Retrieve information from the Registry */
621 if (RegOpenKeyExW(hEnumKey
,
626 return CR_INVALID_DEVNODE
;
628 if (RegQueryValueExW(hKey
,
634 ret
= CR_REGISTRY_ERROR
;
636 /* FIXME: Check buffer size */
642 /* Retrieve information from the Device Node */
643 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
645 PlugPlayData
.Buffer
= Buffer
;
646 PlugPlayData
.BufferSize
= *pulTransferLen
;
651 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
652 PlugPlayData
.Property
= DevicePropertyPhysicalDeviceObjectName
;
655 case CM_DRP_UI_NUMBER
:
656 PlugPlayData
.Property
= DevicePropertyUINumber
;
659 case CM_DRP_BUSTYPEGUID
:
660 PlugPlayData
.Property
= DevicePropertyBusTypeGuid
;
663 case CM_DRP_LEGACYBUSTYPE
:
664 PlugPlayData
.Property
= DevicePropertyLegacyBusType
;
667 case CM_DRP_BUSNUMBER
:
668 PlugPlayData
.Property
= DevicePropertyBusNumber
;
671 case CM_DRP_ENUMERATOR_NAME
:
672 PlugPlayData
.Property
= DevicePropertyEnumeratorName
;
677 return CR_INVALID_PROPERTY
;
680 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
681 (PVOID
)&PlugPlayData
,
682 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
683 if (NT_SUCCESS(Status
))
685 *pulLength
= PlugPlayData
.BufferSize
;
689 ret
= NtStatusToCrError(Status
);
693 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
700 DWORD
PNP_SetDeviceRegProp(
706 PNP_PROP_SIZE ulLength
,
709 CONFIGRET ret
= CR_SUCCESS
;
710 LPWSTR lpValueName
= NULL
;
713 UNREFERENCED_PARAMETER(hBinding
);
714 UNREFERENCED_PARAMETER(ulFlags
);
716 DPRINT("PNP_SetDeviceRegProp() called\n");
718 DPRINT("DeviceId: %S\n", pDeviceId
);
719 DPRINT("Property: %lu\n", ulProperty
);
720 DPRINT("DataType: %lu\n", ulDataType
);
721 DPRINT("Length: %lu\n", ulLength
);
725 case CM_DRP_DEVICEDESC
:
726 lpValueName
= L
"DeviceDesc";
729 case CM_DRP_HARDWAREID
:
730 lpValueName
= L
"HardwareID";
733 case CM_DRP_COMPATIBLEIDS
:
734 lpValueName
= L
"CompatibleIDs";
738 lpValueName
= L
"Service";
742 lpValueName
= L
"Class";
745 case CM_DRP_CLASSGUID
:
746 lpValueName
= L
"ClassGUID";
750 lpValueName
= L
"Driver";
753 case CM_DRP_CONFIGFLAGS
:
754 lpValueName
= L
"ConfigFlags";
758 lpValueName
= L
"Mfg";
761 case CM_DRP_FRIENDLYNAME
:
762 lpValueName
= L
"FriendlyName";
765 case CM_DRP_LOCATION_INFORMATION
:
766 lpValueName
= L
"LocationInformation";
769 case CM_DRP_UPPERFILTERS
:
770 lpValueName
= L
"UpperFilters";
773 case CM_DRP_LOWERFILTERS
:
774 lpValueName
= L
"LowerFilters";
778 return CR_INVALID_PROPERTY
;
781 DPRINT("Value name: %S\n", lpValueName
);
783 if (RegOpenKeyExW(hEnumKey
,
786 KEY_ALL_ACCESS
, /* FIXME: so much? */
788 return CR_INVALID_DEVNODE
;
792 if (RegDeleteValueW(hKey
,
794 ret
= CR_REGISTRY_ERROR
;
798 if (RegSetValueExW(hKey
,
804 ret
= CR_REGISTRY_ERROR
;
809 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
816 DWORD
PNP_GetClassInstance(
819 LPWSTR pszClassInstance
,
820 PNP_RPC_STRING_LEN ulLength
)
823 return CR_CALL_NOT_IMPLEMENTED
;
835 return CR_CALL_NOT_IMPLEMENTED
;
840 DWORD
PNP_DeleteRegistryKey(
848 return CR_CALL_NOT_IMPLEMENTED
;
853 DWORD
PNP_GetClassCount(
855 DWORD
*pulClassCount
,
861 UNREFERENCED_PARAMETER(hBinding
);
862 UNREFERENCED_PARAMETER(ulFlags
);
864 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
869 if (dwError
!= ERROR_SUCCESS
)
870 return CR_INVALID_DATA
;
872 dwError
= RegQueryInfoKeyW(hKey
,
885 if (dwError
!= ERROR_SUCCESS
)
886 return CR_INVALID_DATA
;
893 DWORD
PNP_GetClassName(
897 PNP_RPC_STRING_LEN
*pulLength
,
900 WCHAR szKeyName
[MAX_PATH
];
901 CONFIGRET ret
= CR_SUCCESS
;
905 UNREFERENCED_PARAMETER(hBinding
);
906 UNREFERENCED_PARAMETER(ulFlags
);
908 DPRINT("PNP_GetClassName() called\n");
910 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
911 if(lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
912 lstrcatW(szKeyName
, pszClassGuid
);
913 else return CR_INVALID_DATA
;
915 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
920 return CR_REGISTRY_ERROR
;
922 dwSize
= *pulLength
* sizeof(WCHAR
);
923 if (RegQueryValueExW(hKey
,
931 ret
= CR_REGISTRY_ERROR
;
935 *pulLength
= dwSize
/ sizeof(WCHAR
);
940 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
947 DWORD
PNP_DeleteClassKey(
952 CONFIGRET ret
= CR_SUCCESS
;
954 UNREFERENCED_PARAMETER(hBinding
);
956 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
958 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
960 if (RegDeleteTreeW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
961 ret
= CR_REGISTRY_ERROR
;
965 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
966 ret
= CR_REGISTRY_ERROR
;
969 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
976 DWORD
PNP_GetInterfaceDeviceAlias(
978 LPWSTR pszInterfaceDevice
,
979 GUID
*AliasInterfaceGuid
,
980 LPWSTR pszAliasInterfaceDevice
,
981 PNP_RPC_STRING_LEN
*pulLength
,
982 PNP_RPC_STRING_LEN
*pulTransferLen
,
986 return CR_CALL_NOT_IMPLEMENTED
;
991 DWORD
PNP_GetInterfaceDeviceList(
996 PNP_RPC_BUFFER_SIZE
*pulLength
,
1000 return CR_CALL_NOT_IMPLEMENTED
;
1005 DWORD
PNP_GetInterfaceDeviceListSize(
1007 PNP_RPC_BUFFER_SIZE
*pulLen
,
1008 GUID
*InterfaceGuid
,
1013 return CR_CALL_NOT_IMPLEMENTED
;
1018 DWORD
PNP_RegisterDeviceClassAssociation(
1021 GUID
*InterfaceGuid
,
1022 LPWSTR pszReference
,
1024 PNP_RPC_STRING_LEN
*pulLength
,
1025 PNP_RPC_STRING_LEN
*pulTransferLen
,
1029 return CR_CALL_NOT_IMPLEMENTED
;
1034 DWORD
PNP_UnregisterDeviceClassAssociation(
1036 LPWSTR pszInterfaceDevice
,
1040 return CR_CALL_NOT_IMPLEMENTED
;
1045 DWORD
PNP_GetClassRegProp(
1047 LPWSTR pszClassGuid
,
1049 DWORD
*pulRegDataType
,
1051 PNP_RPC_STRING_LEN
*pulTransferLen
,
1052 PNP_RPC_STRING_LEN
*pulLength
,
1056 return CR_CALL_NOT_IMPLEMENTED
;
1061 DWORD
PNP_SetClassRegProp(
1063 LPWSTR
*pszClassGuid
,
1067 PNP_PROP_SIZE ulLength
,
1071 return CR_CALL_NOT_IMPLEMENTED
;
1076 DWORD
PNP_CreateDevInst(
1079 LPWSTR pszParentDeviceID
,
1080 PNP_RPC_STRING_LEN ulLength
,
1084 return CR_CALL_NOT_IMPLEMENTED
;
1089 #define PNP_DEVINST_SETUP 0x3
1090 #define PNP_DEVINST_ENABLE 0x4
1091 #define PNP_DEVINST_REENUMERATE 0x7
1092 DWORD
PNP_DeviceInstanceAction(
1094 DWORD ulMajorAction
,
1095 DWORD ulMinorAction
,
1096 LPWSTR pszDeviceInstance1
,
1097 LPWSTR pszDeviceInstance2
)
1099 CONFIGRET ret
= CR_SUCCESS
;
1102 UNREFERENCED_PARAMETER(hBinding
);
1103 UNREFERENCED_PARAMETER(ulMinorAction
);
1104 UNREFERENCED_PARAMETER(pszDeviceInstance2
);
1106 DPRINT("PNP_DeviceInstanceAction() called\n");
1108 switch (ulMajorAction
)
1110 case PNP_DEVINST_SETUP
:
1111 DPRINT("Setup device instance\n");
1113 ret
= CR_CALL_NOT_IMPLEMENTED
;
1116 case PNP_DEVINST_ENABLE
:
1118 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1119 DPRINT("Enable device instance\n");
1120 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance1
);
1121 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1122 if (!NT_SUCCESS(Status
))
1123 ret
= NtStatusToCrError(Status
);
1127 case PNP_DEVINST_REENUMERATE
:
1128 DPRINT("Reenumerate device instance\n");
1130 ret
= CR_CALL_NOT_IMPLEMENTED
;
1134 DPRINT1("Unknown function %lu\n", ulMajorAction
);
1135 ret
= CR_CALL_NOT_IMPLEMENTED
;
1138 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1145 DWORD
PNP_GetDeviceStatus(
1152 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1153 CONFIGRET ret
= CR_SUCCESS
;
1156 UNREFERENCED_PARAMETER(hBinding
);
1157 UNREFERENCED_PARAMETER(ulFlags
);
1159 DPRINT("PNP_GetDeviceStatus() called\n");
1161 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1163 PlugPlayData
.Operation
= 0; /* Get status */
1165 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1166 (PVOID
)&PlugPlayData
,
1167 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1168 if (NT_SUCCESS(Status
))
1170 *pulStatus
= PlugPlayData
.DeviceStatus
;
1171 *pulProblem
= PlugPlayData
.DeviceProblem
;
1175 ret
= NtStatusToCrError(Status
);
1178 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1185 DWORD
PNP_SetDeviceProblem(
1192 return CR_CALL_NOT_IMPLEMENTED
;
1197 DWORD
PNP_DisableDevInst(
1200 PPNP_VETO_TYPE pVetoType
,
1206 return CR_CALL_NOT_IMPLEMENTED
;
1210 DWORD
PNP_UninstallDevInst(
1216 return CR_CALL_NOT_IMPLEMENTED
;
1221 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1227 lpPtr
= lpDeviceIdList
;
1230 dwLength
= wcslen(lpPtr
);
1231 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1234 lpPtr
+= (dwLength
+ 1);
1242 AppendDeviceId(LPWSTR lpDeviceIdList
,
1243 LPDWORD lpDeviceIdListSize
,
1249 dwLen
= wcslen(lpDeviceId
);
1250 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1252 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1254 dwPos
+= (dwLen
+ 1);
1256 lpDeviceIdList
[dwPos
] = 0;
1258 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1269 CONFIGRET ret
= CR_SUCCESS
;
1272 DWORD dwDeviceIdListSize
;
1273 DWORD dwNewDeviceIdSize
;
1274 WCHAR
* pszDeviceIdList
= NULL
;
1276 UNREFERENCED_PARAMETER(hBinding
);
1278 DPRINT("PNP_AddID() called\n");
1279 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
1280 DPRINT(" DeviceId: %S\n", pszID
);
1281 DPRINT(" Flags: %lx\n", ulFlags
);
1283 if (RegOpenKeyExW(hEnumKey
,
1286 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1287 &hDeviceKey
) != ERROR_SUCCESS
)
1289 DPRINT("Failed to open the device key!\n");
1290 return CR_INVALID_DEVNODE
;
1293 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1295 if (RegQueryValueExW(hDeviceKey
,
1300 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1302 DPRINT("Failed to query the desired ID string!\n");
1303 ret
= CR_REGISTRY_ERROR
;
1307 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
1308 if (!dwNewDeviceIdSize
)
1310 ret
= CR_INVALID_POINTER
;
1314 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
1316 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
1317 if (!pszDeviceIdList
)
1319 DPRINT("Failed to allocate memory for the desired ID string!\n");
1320 ret
= CR_OUT_OF_MEMORY
;
1324 if (RegQueryValueExW(hDeviceKey
,
1328 (LPBYTE
)pszDeviceIdList
,
1329 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1331 DPRINT("Failed to query the desired ID string!\n");
1332 ret
= CR_REGISTRY_ERROR
;
1336 /* Check whether the device ID is already in use */
1337 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
1339 DPRINT("Device ID was found in the ID string!\n");
1344 /* Append the Device ID */
1345 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
1347 if (RegSetValueExW(hDeviceKey
,
1351 (LPBYTE
)pszDeviceIdList
,
1352 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1354 DPRINT("Failed to set the desired ID string!\n");
1355 ret
= CR_REGISTRY_ERROR
;
1359 RegCloseKey(hDeviceKey
);
1360 if (pszDeviceIdList
)
1361 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
1363 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1370 DWORD
PNP_RegisterDriver(
1376 return CR_CALL_NOT_IMPLEMENTED
;
1381 DWORD
PNP_QueryRemove(
1384 PPNP_VETO_TYPE pVetoType
,
1390 return CR_CALL_NOT_IMPLEMENTED
;
1395 DWORD
PNP_RequestDeviceEject(
1398 PPNP_VETO_TYPE pVetoType
,
1404 return CR_CALL_NOT_IMPLEMENTED
;
1409 PNP_IsDockStationPresent(handle_t hBinding
,
1416 CONFIGRET ret
= CR_SUCCESS
;
1418 UNREFERENCED_PARAMETER(hBinding
);
1420 DPRINT1("PNP_IsDockStationPresent() called\n");
1424 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
1428 &hKey
) != ERROR_SUCCESS
)
1429 return CR_REGISTRY_ERROR
;
1431 dwSize
= sizeof(DWORD
);
1432 if (RegQueryValueExW(hKey
,
1437 &dwSize
) != ERROR_SUCCESS
)
1438 ret
= CR_REGISTRY_ERROR
;
1442 if (ret
== CR_SUCCESS
)
1444 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
1446 ret
= CR_REGISTRY_ERROR
;
1448 else if (dwValue
!= 0)
1454 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
1461 DWORD
PNP_RequestEjectPC(
1465 return CR_CALL_NOT_IMPLEMENTED
;
1470 DWORD
PNP_HwProfFlags(
1476 PPNP_VETO_TYPE pVetoType
,
1482 return CR_CALL_NOT_IMPLEMENTED
;
1487 DWORD
PNP_GetHwProfInfo(
1490 HWPROFILEINFO
*pHWProfileInfo
,
1491 DWORD ulProfileInfoSize
,
1495 return CR_CALL_NOT_IMPLEMENTED
;
1500 DWORD
PNP_AddEmptyLogConf(
1504 DWORD
*pulLogConfTag
,
1508 return CR_CALL_NOT_IMPLEMENTED
;
1513 DWORD
PNP_FreeLogConf(
1516 DWORD ulLogConfType
,
1521 return CR_CALL_NOT_IMPLEMENTED
;
1526 DWORD
PNP_GetFirstLogConf(
1529 DWORD ulLogConfType
,
1530 DWORD
*pulLogConfTag
,
1534 return CR_CALL_NOT_IMPLEMENTED
;
1539 DWORD
PNP_GetNextLogConf(
1542 DWORD ulLogConfType
,
1548 return CR_CALL_NOT_IMPLEMENTED
;
1553 DWORD
PNP_GetLogConfPriority(
1562 return CR_CALL_NOT_IMPLEMENTED
;
1567 DWORD
PNP_AddResDes(
1571 DWORD ulLogConfType
,
1572 RESOURCEID ResourceID
,
1573 DWORD
*pulResourceTag
,
1575 PNP_RPC_BUFFER_SIZE ResourceLen
,
1579 return CR_CALL_NOT_IMPLEMENTED
;
1584 DWORD
PNP_FreeResDes(
1588 DWORD ulLogConfType
,
1589 RESOURCEID ResourceID
,
1590 DWORD ulResourceTag
,
1591 DWORD
*pulPreviousResType
,
1592 DWORD
*pulPreviousResTag
,
1596 return CR_CALL_NOT_IMPLEMENTED
;
1601 DWORD
PNP_GetNextResDes(
1605 DWORD ulLogConfType
,
1606 RESOURCEID ResourceID
,
1607 DWORD ulResourceTag
,
1608 DWORD
*pulNextResType
,
1609 DWORD
*pulNextResTag
,
1613 return CR_CALL_NOT_IMPLEMENTED
;
1618 DWORD
PNP_GetResDesData(
1622 DWORD ulLogConfType
,
1623 RESOURCEID ResourceID
,
1624 DWORD ulResourceTag
,
1626 PNP_RPC_BUFFER_SIZE BufferLen
,
1630 return CR_CALL_NOT_IMPLEMENTED
;
1635 DWORD
PNP_GetResDesDataSize(
1639 DWORD ulLogConfType
,
1640 RESOURCEID ResourceID
,
1641 DWORD ulResourceTag
,
1646 return CR_CALL_NOT_IMPLEMENTED
;
1651 DWORD
PNP_ModifyResDes(
1655 DWORD ulLogConfType
,
1656 RESOURCEID CurrentResourceID
,
1657 RESOURCEID NewResourceID
,
1658 DWORD ulResourceTag
,
1660 PNP_RPC_BUFFER_SIZE ResourceLen
,
1664 return CR_CALL_NOT_IMPLEMENTED
;
1669 DWORD
PNP_DetectResourceConflict(
1672 RESOURCEID ResourceID
,
1674 PNP_RPC_BUFFER_SIZE ResourceLen
,
1675 BOOL
*pbConflictDetected
,
1679 return CR_CALL_NOT_IMPLEMENTED
;
1684 DWORD
PNP_QueryResConfList(
1687 RESOURCEID ResourceID
,
1689 PNP_RPC_BUFFER_SIZE ResourceLen
,
1691 PNP_RPC_BUFFER_SIZE BufferLen
,
1695 return CR_CALL_NOT_IMPLEMENTED
;
1700 DWORD
PNP_SetHwProf(
1704 return CR_CALL_NOT_IMPLEMENTED
;
1709 DWORD
PNP_QueryArbitratorFreeData(
1713 return CR_CALL_NOT_IMPLEMENTED
;
1718 DWORD
PNP_QueryArbitratorFreeSize(
1722 return CR_CALL_NOT_IMPLEMENTED
;
1733 return CR_CALL_NOT_IMPLEMENTED
;
1738 DWORD
PNP_RegisterNotification(
1742 return CR_CALL_NOT_IMPLEMENTED
;
1747 DWORD
PNP_UnregisterNotification(
1751 return CR_CALL_NOT_IMPLEMENTED
;
1756 DWORD
PNP_GetCustomDevProp(
1759 LPWSTR CustomPropName
,
1760 DWORD
*pulRegDataType
,
1762 PNP_RPC_STRING_LEN
*pulTransferLen
,
1763 PNP_RPC_STRING_LEN
*pulLength
,
1767 return CR_CALL_NOT_IMPLEMENTED
;
1772 DWORD
PNP_GetVersionInternal(
1777 return CR_CALL_NOT_IMPLEMENTED
;
1782 DWORD
PNP_GetBlockedDriverInfo(
1785 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
1786 PNP_RPC_BUFFER_SIZE
*pulLength
,
1790 return CR_CALL_NOT_IMPLEMENTED
;
1795 DWORD
PNP_GetServerSideDeviceInstallFlags(
1797 DWORD
*pulSSDIFlags
,
1801 return CR_CALL_NOT_IMPLEMENTED
;
1806 DWORD
PNP_GetObjectPropKeys(
1810 LPWSTR PropertyCultureName
,
1811 PNP_PROP_COUNT
*PropertyCount
,
1812 PNP_PROP_COUNT
*TransferLen
,
1813 DEVPROPKEY
*PropertyKeys
,
1817 return CR_CALL_NOT_IMPLEMENTED
;
1822 DWORD
PNP_GetObjectProp(
1826 LPWSTR PropertyCultureName
,
1827 const DEVPROPKEY
*PropertyKey
,
1828 DEVPROPTYPE
*PropertyType
,
1829 PNP_PROP_SIZE
*PropertySize
,
1830 PNP_PROP_SIZE
*TransferLen
,
1831 BYTE
*PropertyBuffer
,
1835 return CR_CALL_NOT_IMPLEMENTED
;
1840 DWORD
PNP_SetObjectProp(
1844 LPWSTR PropertyCultureName
,
1845 const DEVPROPKEY
*PropertyKey
,
1846 DEVPROPTYPE PropertyType
,
1847 PNP_PROP_SIZE PropertySize
,
1848 BYTE
*PropertyBuffer
,
1852 return CR_CALL_NOT_IMPLEMENTED
;
1857 DWORD
PNP_InstallDevInst(
1861 return CR_CALL_NOT_IMPLEMENTED
;
1866 DWORD
PNP_ApplyPowerSettings(
1870 return CR_CALL_NOT_IMPLEMENTED
;
1875 DWORD
PNP_DriverStoreAddDriverPackage(
1879 return CR_CALL_NOT_IMPLEMENTED
;
1884 DWORD
PNP_DriverStoreDeleteDriverPackage(
1888 return CR_CALL_NOT_IMPLEMENTED
;
1893 DWORD
PNP_RegisterServiceNotification(
1897 return CR_CALL_NOT_IMPLEMENTED
;
1902 DWORD
PNP_SetActiveService(
1906 return CR_CALL_NOT_IMPLEMENTED
;
1911 DWORD
PNP_DeleteServiceDevices(
1915 return CR_CALL_NOT_IMPLEMENTED
;
1920 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
1922 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1924 BOOL DeviceInstalled
= FALSE
;
1927 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
1928 LPVOID Environment
= NULL
;
1929 PROCESS_INFORMATION ProcessInfo
;
1930 STARTUPINFOW StartupInfo
;
1933 /* The following lengths are constant (see below), they cannot overflow */
1934 WCHAR CommandLine
[116];
1935 WCHAR InstallEventName
[73];
1937 WCHAR UuidString
[39];
1939 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
1941 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
1943 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1945 PlugPlayData
.Operation
= 0; /* Get status */
1947 /* Get device status */
1948 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1949 (PVOID
)&PlugPlayData
,
1950 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1951 if (!NT_SUCCESS(Status
))
1953 DPRINT1("NtPlugPlayControl('%S') failed with status 0x%08lx\n", DeviceInstance
, Status
);
1957 if ((PlugPlayData
.DeviceStatus
& (DNF_STARTED
| DNF_START_FAILED
)) != 0)
1959 /* Device is already started, or disabled due to some problem. Don't install it */
1960 DPRINT("No need to install '%S'\n", DeviceInstance
);
1964 /* Create a random UUID for the named pipe */
1965 UuidCreate(&RandomUuid
);
1966 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
1967 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
1968 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
1969 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
1970 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
1972 /* Create the named pipe */
1973 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
1974 wcscat(PipeName
, UuidString
);
1975 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
1977 if(hPipe
== INVALID_HANDLE_VALUE
)
1979 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
1983 /* Launch rundll32 to call ClientSideInstallW */
1984 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
1985 wcscat(CommandLine
, PipeName
);
1987 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
1988 StartupInfo
.cb
= sizeof(StartupInfo
);
1992 /* newdev has to run under the environment of the current user */
1993 if(!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
1995 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
1999 if(!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
2001 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
2007 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
2009 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
2010 (ShowWizard is only set to FALSE for these two modes) */
2011 ASSERT(!ShowWizard
);
2013 if(!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
2015 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
2020 /* Wait for the function to connect to our pipe */
2021 if(!ConnectNamedPipe(hPipe
, NULL
))
2023 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
2027 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
2028 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
2029 wcscat(InstallEventName
, UuidString
);
2031 Value
= sizeof(InstallEventName
);
2032 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2033 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
2035 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
2036 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
2037 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
2039 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
2040 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2041 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
2043 /* Wait for newdev.dll to finish processing */
2044 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
2046 /* The following check for success is probably not compatible to Windows, but should do its job */
2047 if(!GetExitCodeProcess(ProcessInfo
.hProcess
, &Value
))
2049 DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
2053 DeviceInstalled
= Value
;
2056 if(hPipe
!= INVALID_HANDLE_VALUE
)
2060 DestroyEnvironmentBlock(Environment
);
2062 if(ProcessInfo
.hProcess
)
2063 CloseHandle(ProcessInfo
.hProcess
);
2065 if(ProcessInfo
.hThread
)
2066 CloseHandle(ProcessInfo
.hThread
);
2068 return DeviceInstalled
;
2084 return ERROR_INVALID_PARAMETER
;
2087 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
2088 if (rc
!= ERROR_SUCCESS
)
2090 if (dwType
!= REG_SZ
)
2091 return ERROR_FILE_NOT_FOUND
;
2092 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
2094 return ERROR_NOT_ENOUGH_MEMORY
;
2095 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
2096 if (rc
!= ERROR_SUCCESS
)
2098 HeapFree(GetProcessHeap(), 0, Value
);
2101 /* NULL-terminate the string */
2102 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
2105 return ERROR_SUCCESS
;
2113 DWORD regType
, active
, size
;
2117 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
2118 if (rc
!= ERROR_SUCCESS
)
2121 size
= sizeof(DWORD
);
2122 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
2123 if (rc
!= ERROR_SUCCESS
)
2125 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
2128 ret
= (active
!= 0);
2134 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
2143 HKEY ControlKey
= NULL
;
2144 LPWSTR SystemStartOptions
= NULL
;
2145 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
2146 BOOL ConsoleBoot
= FALSE
;
2151 L
"SYSTEM\\CurrentControlSet\\Control",
2156 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
2157 if (rc
!= ERROR_SUCCESS
)
2160 /* Check for CMDCONS in SystemStartOptions */
2161 CurrentOption
= SystemStartOptions
;
2162 while (CurrentOption
)
2164 NextOption
= wcschr(CurrentOption
, L
' ');
2166 *NextOption
= L
'\0';
2167 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
2169 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
2173 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
2177 if (ControlKey
!= NULL
)
2178 RegCloseKey(ControlKey
);
2179 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
2184 /* Loop to install all queued devices installations */
2186 DeviceInstallThread(LPVOID lpParameter
)
2188 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2189 PSLIST_ENTRY ListEntry
;
2191 PLIST_ENTRY ListEntry
;
2193 DeviceInstallParams
* Params
;
2196 UNREFERENCED_PARAMETER(lpParameter
);
2198 WaitForSingleObject(hInstallEvent
, INFINITE
);
2200 showWizard
= !SetupIsActive() && !IsConsoleBoot();
2204 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2205 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
2207 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
2210 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
2212 if (ListEntry
== NULL
)
2214 SetEvent(hNoPendingInstalls
);
2215 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
2219 ResetEvent(hNoPendingInstalls
);
2220 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
2221 InstallDevice(Params
->DeviceIds
, showWizard
);
2230 PnpEventThread(LPVOID lpParameter
)
2232 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
2235 RPC_STATUS RpcStatus
;
2237 UNREFERENCED_PARAMETER(lpParameter
);
2239 PnpEventSize
= 0x1000;
2240 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
2241 if (PnpEvent
== NULL
)
2242 return ERROR_OUTOFMEMORY
;
2246 DPRINT("Calling NtGetPlugPlayEvent()\n");
2248 /* Wait for the next pnp event */
2249 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
2251 /* Resize the buffer for the PnP event if it's too small. */
2252 if (Status
== STATUS_BUFFER_TOO_SMALL
)
2254 PnpEventSize
+= 0x400;
2255 HeapFree(GetProcessHeap(), 0, PnpEvent
);
2256 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
2257 if (PnpEvent
== NULL
)
2258 return ERROR_OUTOFMEMORY
;
2262 if (!NT_SUCCESS(Status
))
2264 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
2268 /* Process the pnp event */
2269 DPRINT("Received PnP Event\n");
2270 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
2272 DeviceInstallParams
* Params
;
2274 DWORD DeviceIdLength
;
2276 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
2278 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
2281 /* Queue device install (will be dequeued by DeviceInstallThread */
2282 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
2283 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
2286 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
2287 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2288 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
2290 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
2292 SetEvent(hDeviceInstallListNotEmpty
);
2298 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
2299 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
2300 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
2301 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
2302 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
2305 /* Dequeue the current pnp event and signal the next one */
2306 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
2309 HeapFree(GetProcessHeap(), 0, PnpEvent
);
2311 return ERROR_SUCCESS
;
2315 static VOID CALLBACK
2316 ServiceMain(DWORD argc
, LPTSTR
*argv
)
2321 UNREFERENCED_PARAMETER(argc
);
2322 UNREFERENCED_PARAMETER(argv
);
2324 DPRINT("ServiceMain() called\n");
2326 hThread
= CreateThread(NULL
,
2332 if (hThread
!= NULL
)
2333 CloseHandle(hThread
);
2335 hThread
= CreateThread(NULL
,
2341 if (hThread
!= NULL
)
2342 CloseHandle(hThread
);
2344 hThread
= CreateThread(NULL
,
2346 DeviceInstallThread
,
2350 if (hThread
!= NULL
)
2351 CloseHandle(hThread
);
2353 DPRINT("ServiceMain() done\n");
2358 wmain(int argc
, WCHAR
*argv
[])
2363 UNREFERENCED_PARAMETER(argc
);
2364 UNREFERENCED_PARAMETER(argv
);
2366 DPRINT("Umpnpmgr: main() started\n");
2368 /* We need this privilege for using CreateProcessAsUserW */
2369 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
2371 hInstallEvent
= CreateEvent(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
2372 if (hInstallEvent
== NULL
)
2374 dwError
= GetLastError();
2375 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
2379 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2380 if (hDeviceInstallListNotEmpty
== NULL
)
2382 dwError
= GetLastError();
2383 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
2387 hNoPendingInstalls
= CreateEventW(NULL
,
2390 L
"Global\\PnP_No_Pending_Install_Events");
2391 if (hNoPendingInstalls
== NULL
)
2393 dwError
= GetLastError();
2394 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
2398 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2399 InitializeSListHead(&DeviceInstallListHead
);
2401 InitializeListHead(&DeviceInstallListHead
);
2404 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2405 L
"System\\CurrentControlSet\\Enum",
2409 if (dwError
!= ERROR_SUCCESS
)
2411 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
2415 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2416 L
"System\\CurrentControlSet\\Control\\Class",
2420 if (dwError
!= ERROR_SUCCESS
)
2422 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
2426 StartServiceCtrlDispatcher(ServiceTable
);
2428 DPRINT("Umpnpmgr: main() done\n");