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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 if (hInstallEvent
!= NULL
)
238 SetEvent(hInstallEvent
);
240 /* Get the users token */
241 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
245 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
251 CloseHandle(hUserToken
);
255 if(!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
257 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
261 /* Trigger the installer thread */
262 /*if (hInstallEvent != NULL)
263 SetEvent(hInstallEvent);*/
265 ReturnValue
= CR_SUCCESS
;
269 CloseHandle(hProcess
);
276 DWORD
PNP_ValidateDeviceInstance(
281 CONFIGRET ret
= CR_SUCCESS
;
282 HKEY hDeviceKey
= NULL
;
284 UNREFERENCED_PARAMETER(hBinding
);
285 UNREFERENCED_PARAMETER(ulFlags
);
287 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
290 if (RegOpenKeyExW(hEnumKey
,
296 DPRINT("Could not open the Device Key!\n");
297 ret
= CR_NO_SUCH_DEVNODE
;
301 /* FIXME: add more tests */
304 if (hDeviceKey
!= NULL
)
305 RegCloseKey(hDeviceKey
);
307 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
314 DWORD
PNP_GetRootDeviceInstance(
317 PNP_RPC_STRING_LEN ulLength
)
319 CONFIGRET ret
= CR_SUCCESS
;
321 UNREFERENCED_PARAMETER(hBinding
);
323 DPRINT("PNP_GetRootDeviceInstance() called\n");
327 ret
= CR_INVALID_POINTER
;
330 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
332 ret
= CR_BUFFER_SMALL
;
340 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
347 DWORD
PNP_GetRelatedDeviceInstance(
349 DWORD ulRelationship
,
351 LPWSTR pRelatedDeviceId
,
352 PNP_RPC_STRING_LEN
*pulLength
,
355 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
356 CONFIGRET ret
= CR_SUCCESS
;
359 UNREFERENCED_PARAMETER(hBinding
);
360 UNREFERENCED_PARAMETER(ulFlags
);
362 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
363 DPRINT(" Relationship %ld\n", ulRelationship
);
364 DPRINT(" DeviceId %S\n", pDeviceID
);
366 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
369 PlugPlayData
.Relation
= ulRelationship
;
371 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
372 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
374 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
375 (PVOID
)&PlugPlayData
,
376 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
377 if (!NT_SUCCESS(Status
))
379 ret
= NtStatusToCrError(Status
);
382 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
383 if (ret
== CR_SUCCESS
)
385 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
393 DWORD
PNP_EnumerateSubKeys(
398 PNP_RPC_STRING_LEN ulLength
,
399 PNP_RPC_STRING_LEN
*pulRequiredLen
,
402 CONFIGRET ret
= CR_SUCCESS
;
406 UNREFERENCED_PARAMETER(hBinding
);
407 UNREFERENCED_PARAMETER(ulFlags
);
409 DPRINT("PNP_EnumerateSubKeys() called\n");
413 case PNP_ENUMERATOR_SUBKEYS
:
417 case PNP_CLASS_SUBKEYS
:
425 *pulRequiredLen
= ulLength
;
426 dwError
= RegEnumKeyExW(hKey
,
434 if (dwError
!= ERROR_SUCCESS
)
436 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
443 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
450 DWORD
PNP_GetDeviceList(
454 PNP_RPC_STRING_LEN
*pulLength
,
458 return CR_CALL_NOT_IMPLEMENTED
;
463 DWORD
PNP_GetDeviceListSize(
466 PNP_RPC_BUFFER_SIZE
*pulLen
,
470 return CR_CALL_NOT_IMPLEMENTED
;
481 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
482 CONFIGRET ret
= CR_SUCCESS
;
485 UNREFERENCED_PARAMETER(hBinding
);
486 UNREFERENCED_PARAMETER(ulFlags
);
488 DPRINT("PNP_GetDepth() called\n");
490 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
493 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
494 (PVOID
)&PlugPlayData
,
495 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
496 if (NT_SUCCESS(Status
))
498 *pulDepth
= PlugPlayData
.Depth
;
502 ret
= NtStatusToCrError(Status
);
505 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
512 DWORD
PNP_GetDeviceRegProp(
516 DWORD
*pulRegDataType
,
518 PNP_PROP_SIZE
*pulTransferLen
,
519 PNP_PROP_SIZE
*pulLength
,
522 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
523 CONFIGRET ret
= CR_SUCCESS
;
524 LPWSTR lpValueName
= NULL
;
528 UNREFERENCED_PARAMETER(hBinding
);
529 UNREFERENCED_PARAMETER(ulFlags
);
531 DPRINT("PNP_GetDeviceRegProp() called\n");
535 case CM_DRP_DEVICEDESC
:
536 lpValueName
= L
"DeviceDesc";
539 case CM_DRP_HARDWAREID
:
540 lpValueName
= L
"HardwareID";
543 case CM_DRP_COMPATIBLEIDS
:
544 lpValueName
= L
"CompatibleIDs";
548 lpValueName
= L
"Service";
552 lpValueName
= L
"Class";
555 case CM_DRP_CLASSGUID
:
556 lpValueName
= L
"ClassGUID";
560 lpValueName
= L
"Driver";
563 case CM_DRP_CONFIGFLAGS
:
564 lpValueName
= L
"ConfigFlags";
568 lpValueName
= L
"Mfg";
571 case CM_DRP_FRIENDLYNAME
:
572 lpValueName
= L
"FriendlyName";
575 case CM_DRP_LOCATION_INFORMATION
:
576 lpValueName
= L
"LocationInformation";
579 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
583 case CM_DRP_CAPABILITIES
:
584 lpValueName
= L
"Capabilities";
587 case CM_DRP_UI_NUMBER
:
591 case CM_DRP_UPPERFILTERS
:
592 lpValueName
= L
"UpperFilters";
595 case CM_DRP_LOWERFILTERS
:
596 lpValueName
= L
"LowerFilters";
599 case CM_DRP_BUSTYPEGUID
:
603 case CM_DRP_LEGACYBUSTYPE
:
607 case CM_DRP_BUSNUMBER
:
611 case CM_DRP_ENUMERATOR_NAME
:
616 return CR_INVALID_PROPERTY
;
619 DPRINT("Value name: %S\n", lpValueName
);
623 /* Retrieve information from the Registry */
624 if (RegOpenKeyExW(hEnumKey
,
629 return CR_INVALID_DEVNODE
;
631 if (RegQueryValueExW(hKey
,
637 ret
= CR_REGISTRY_ERROR
;
639 /* FIXME: Check buffer size */
645 /* Retrieve information from the Device Node */
646 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
648 PlugPlayData
.Buffer
= Buffer
;
649 PlugPlayData
.BufferSize
= *pulTransferLen
;
654 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
655 PlugPlayData
.Property
= DevicePropertyPhysicalDeviceObjectName
;
658 case CM_DRP_UI_NUMBER
:
659 PlugPlayData
.Property
= DevicePropertyUINumber
;
662 case CM_DRP_BUSTYPEGUID
:
663 PlugPlayData
.Property
= DevicePropertyBusTypeGuid
;
666 case CM_DRP_LEGACYBUSTYPE
:
667 PlugPlayData
.Property
= DevicePropertyLegacyBusType
;
670 case CM_DRP_BUSNUMBER
:
671 PlugPlayData
.Property
= DevicePropertyBusNumber
;
674 case CM_DRP_ENUMERATOR_NAME
:
675 PlugPlayData
.Property
= DevicePropertyEnumeratorName
;
680 return CR_INVALID_PROPERTY
;
683 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
684 (PVOID
)&PlugPlayData
,
685 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
686 if (NT_SUCCESS(Status
))
688 *pulLength
= PlugPlayData
.BufferSize
;
692 ret
= NtStatusToCrError(Status
);
696 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
703 DWORD
PNP_SetDeviceRegProp(
709 PNP_PROP_SIZE ulLength
,
712 CONFIGRET ret
= CR_SUCCESS
;
713 LPWSTR lpValueName
= NULL
;
716 UNREFERENCED_PARAMETER(hBinding
);
717 UNREFERENCED_PARAMETER(ulFlags
);
719 DPRINT("PNP_SetDeviceRegProp() called\n");
721 DPRINT("DeviceId: %S\n", pDeviceId
);
722 DPRINT("Property: %lu\n", ulProperty
);
723 DPRINT("DataType: %lu\n", ulDataType
);
724 DPRINT("Length: %lu\n", ulLength
);
728 case CM_DRP_DEVICEDESC
:
729 lpValueName
= L
"DeviceDesc";
732 case CM_DRP_HARDWAREID
:
733 lpValueName
= L
"HardwareID";
736 case CM_DRP_COMPATIBLEIDS
:
737 lpValueName
= L
"CompatibleIDs";
741 lpValueName
= L
"Service";
745 lpValueName
= L
"Class";
748 case CM_DRP_CLASSGUID
:
749 lpValueName
= L
"ClassGUID";
753 lpValueName
= L
"Driver";
756 case CM_DRP_CONFIGFLAGS
:
757 lpValueName
= L
"ConfigFlags";
761 lpValueName
= L
"Mfg";
764 case CM_DRP_FRIENDLYNAME
:
765 lpValueName
= L
"FriendlyName";
768 case CM_DRP_LOCATION_INFORMATION
:
769 lpValueName
= L
"LocationInformation";
772 case CM_DRP_UPPERFILTERS
:
773 lpValueName
= L
"UpperFilters";
776 case CM_DRP_LOWERFILTERS
:
777 lpValueName
= L
"LowerFilters";
781 return CR_INVALID_PROPERTY
;
784 DPRINT("Value name: %S\n", lpValueName
);
786 if (RegOpenKeyExW(hEnumKey
,
789 KEY_ALL_ACCESS
, /* FIXME: so much? */
791 return CR_INVALID_DEVNODE
;
795 if (RegDeleteValueW(hKey
,
797 ret
= CR_REGISTRY_ERROR
;
801 if (RegSetValueExW(hKey
,
807 ret
= CR_REGISTRY_ERROR
;
812 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
819 DWORD
PNP_GetClassInstance(
822 LPWSTR pszClassInstance
,
823 PNP_RPC_STRING_LEN ulLength
)
826 return CR_CALL_NOT_IMPLEMENTED
;
838 return CR_CALL_NOT_IMPLEMENTED
;
843 DWORD
PNP_DeleteRegistryKey(
851 return CR_CALL_NOT_IMPLEMENTED
;
856 DWORD
PNP_GetClassCount(
858 DWORD
*pulClassCount
,
864 UNREFERENCED_PARAMETER(hBinding
);
865 UNREFERENCED_PARAMETER(ulFlags
);
867 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
872 if (dwError
!= ERROR_SUCCESS
)
873 return CR_INVALID_DATA
;
875 dwError
= RegQueryInfoKeyW(hKey
,
888 if (dwError
!= ERROR_SUCCESS
)
889 return CR_INVALID_DATA
;
896 DWORD
PNP_GetClassName(
900 PNP_RPC_STRING_LEN
*pulLength
,
903 WCHAR szKeyName
[MAX_PATH
];
904 CONFIGRET ret
= CR_SUCCESS
;
908 UNREFERENCED_PARAMETER(hBinding
);
909 UNREFERENCED_PARAMETER(ulFlags
);
911 DPRINT("PNP_GetClassName() called\n");
913 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
914 if(lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
915 lstrcatW(szKeyName
, pszClassGuid
);
916 else return CR_INVALID_DATA
;
918 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
923 return CR_REGISTRY_ERROR
;
925 dwSize
= *pulLength
* sizeof(WCHAR
);
926 if (RegQueryValueExW(hKey
,
934 ret
= CR_REGISTRY_ERROR
;
938 *pulLength
= dwSize
/ sizeof(WCHAR
);
943 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
950 DWORD
PNP_DeleteClassKey(
955 CONFIGRET ret
= CR_SUCCESS
;
957 UNREFERENCED_PARAMETER(hBinding
);
959 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
961 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
963 if (RegDeleteTreeW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
964 ret
= CR_REGISTRY_ERROR
;
968 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
969 ret
= CR_REGISTRY_ERROR
;
972 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
979 DWORD
PNP_GetInterfaceDeviceAlias(
981 LPWSTR pszInterfaceDevice
,
982 GUID
*AliasInterfaceGuid
,
983 LPWSTR pszAliasInterfaceDevice
,
984 PNP_RPC_STRING_LEN
*pulLength
,
985 PNP_RPC_STRING_LEN
*pulTransferLen
,
989 return CR_CALL_NOT_IMPLEMENTED
;
994 DWORD
PNP_GetInterfaceDeviceList(
999 PNP_RPC_BUFFER_SIZE
*pulLength
,
1003 return CR_CALL_NOT_IMPLEMENTED
;
1008 DWORD
PNP_GetInterfaceDeviceListSize(
1010 PNP_RPC_BUFFER_SIZE
*pulLen
,
1011 GUID
*InterfaceGuid
,
1016 return CR_CALL_NOT_IMPLEMENTED
;
1021 DWORD
PNP_RegisterDeviceClassAssociation(
1024 GUID
*InterfaceGuid
,
1025 LPWSTR pszReference
,
1027 PNP_RPC_STRING_LEN
*pulLength
,
1028 PNP_RPC_STRING_LEN
*pulTransferLen
,
1032 return CR_CALL_NOT_IMPLEMENTED
;
1037 DWORD
PNP_UnregisterDeviceClassAssociation(
1039 LPWSTR pszInterfaceDevice
,
1043 return CR_CALL_NOT_IMPLEMENTED
;
1048 DWORD
PNP_GetClassRegProp(
1050 LPWSTR pszClassGuid
,
1052 DWORD
*pulRegDataType
,
1054 PNP_RPC_STRING_LEN
*pulTransferLen
,
1055 PNP_RPC_STRING_LEN
*pulLength
,
1059 return CR_CALL_NOT_IMPLEMENTED
;
1064 DWORD
PNP_SetClassRegProp(
1066 LPWSTR
*pszClassGuid
,
1070 PNP_PROP_SIZE ulLength
,
1074 return CR_CALL_NOT_IMPLEMENTED
;
1079 DWORD
PNP_CreateDevInst(
1082 LPWSTR pszParentDeviceID
,
1083 PNP_RPC_STRING_LEN ulLength
,
1087 return CR_CALL_NOT_IMPLEMENTED
;
1092 #define PNP_DEVINST_SETUP 0x3
1093 #define PNP_DEVINST_ENABLE 0x4
1094 #define PNP_DEVINST_REENUMERATE 0x7
1095 DWORD
PNP_DeviceInstanceAction(
1097 DWORD ulMajorAction
,
1098 DWORD ulMinorAction
,
1099 LPWSTR pszDeviceInstance1
,
1100 LPWSTR pszDeviceInstance2
)
1102 CONFIGRET ret
= CR_SUCCESS
;
1104 UNREFERENCED_PARAMETER(hBinding
);
1105 UNREFERENCED_PARAMETER(ulMinorAction
);
1106 UNREFERENCED_PARAMETER(pszDeviceInstance1
);
1107 UNREFERENCED_PARAMETER(pszDeviceInstance2
);
1109 DPRINT("PNP_DeviceInstanceAction() called\n");
1111 switch (ulMajorAction
)
1113 case PNP_DEVINST_SETUP
:
1114 DPRINT("Setup device instance\n");
1116 ret
= CR_CALL_NOT_IMPLEMENTED
;
1119 case PNP_DEVINST_ENABLE
:
1120 DPRINT("Enable device instance\n");
1122 ret
= CR_CALL_NOT_IMPLEMENTED
;
1125 case PNP_DEVINST_REENUMERATE
:
1126 DPRINT("Reenumerate device instance\n");
1128 ret
= CR_CALL_NOT_IMPLEMENTED
;
1132 DPRINT1("Unknown function %lu\n", ulMajorAction
);
1133 ret
= CR_CALL_NOT_IMPLEMENTED
;
1136 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1143 DWORD
PNP_GetDeviceStatus(
1150 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1151 CONFIGRET ret
= CR_SUCCESS
;
1154 UNREFERENCED_PARAMETER(hBinding
);
1155 UNREFERENCED_PARAMETER(ulFlags
);
1157 DPRINT("PNP_GetDeviceStatus() called\n");
1159 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1161 PlugPlayData
.Operation
= 0; /* Get status */
1163 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1164 (PVOID
)&PlugPlayData
,
1165 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1166 if (NT_SUCCESS(Status
))
1168 *pulStatus
= PlugPlayData
.DeviceStatus
;
1169 *pulProblem
= PlugPlayData
.DeviceProblem
;
1173 ret
= NtStatusToCrError(Status
);
1176 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1183 DWORD
PNP_SetDeviceProblem(
1190 return CR_CALL_NOT_IMPLEMENTED
;
1195 DWORD
PNP_DisableDevInst(
1198 PPNP_VETO_TYPE pVetoType
,
1204 return CR_CALL_NOT_IMPLEMENTED
;
1208 DWORD
PNP_UninstallDevInst(
1214 return CR_CALL_NOT_IMPLEMENTED
;
1219 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1225 lpPtr
= lpDeviceIdList
;
1228 dwLength
= wcslen(lpPtr
);
1229 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1232 lpPtr
+= (dwLength
+ 1);
1240 AppendDeviceId(LPWSTR lpDeviceIdList
,
1241 LPDWORD lpDeviceIdListSize
,
1247 dwLen
= wcslen(lpDeviceId
);
1248 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1250 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1252 dwPos
+= (dwLen
+ 1);
1254 lpDeviceIdList
[dwPos
] = 0;
1256 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1267 CONFIGRET ret
= CR_SUCCESS
;
1270 DWORD dwDeviceIdListSize
;
1271 DWORD dwNewDeviceIdSize
;
1272 WCHAR
* pszDeviceIdList
= NULL
;
1274 UNREFERENCED_PARAMETER(hBinding
);
1276 DPRINT("PNP_AddID() called\n");
1277 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
1278 DPRINT(" DeviceId: %S\n", pszID
);
1279 DPRINT(" Flags: %lx\n", ulFlags
);
1281 if (RegOpenKeyExW(hEnumKey
,
1284 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1285 &hDeviceKey
) != ERROR_SUCCESS
)
1287 DPRINT("Failed to open the device key!\n");
1288 return CR_INVALID_DEVNODE
;
1291 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1293 if (RegQueryValueExW(hDeviceKey
,
1298 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1300 DPRINT("Failed to query the desired ID string!\n");
1301 ret
= CR_REGISTRY_ERROR
;
1305 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
1306 if (!dwNewDeviceIdSize
)
1308 ret
= CR_INVALID_POINTER
;
1312 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
1314 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
1315 if (!pszDeviceIdList
)
1317 DPRINT("Failed to allocate memory for the desired ID string!\n");
1318 ret
= CR_OUT_OF_MEMORY
;
1322 if (RegQueryValueExW(hDeviceKey
,
1326 (LPBYTE
)pszDeviceIdList
,
1327 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1329 DPRINT("Failed to query the desired ID string!\n");
1330 ret
= CR_REGISTRY_ERROR
;
1334 /* Check whether the device ID is already in use */
1335 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
1337 DPRINT("Device ID was found in the ID string!\n");
1342 /* Append the Device ID */
1343 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
1345 if (RegSetValueExW(hDeviceKey
,
1349 (LPBYTE
)pszDeviceIdList
,
1350 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1352 DPRINT("Failed to set the desired ID string!\n");
1353 ret
= CR_REGISTRY_ERROR
;
1357 RegCloseKey(hDeviceKey
);
1358 if (pszDeviceIdList
)
1359 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
1361 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1368 DWORD
PNP_RegisterDriver(
1374 return CR_CALL_NOT_IMPLEMENTED
;
1379 DWORD
PNP_QueryRemove(
1382 PPNP_VETO_TYPE pVetoType
,
1388 return CR_CALL_NOT_IMPLEMENTED
;
1393 DWORD
PNP_RequestDeviceEject(
1396 PPNP_VETO_TYPE pVetoType
,
1402 return CR_CALL_NOT_IMPLEMENTED
;
1407 PNP_IsDockStationPresent(handle_t hBinding
,
1414 CONFIGRET ret
= CR_SUCCESS
;
1416 UNREFERENCED_PARAMETER(hBinding
);
1418 DPRINT1("PNP_IsDockStationPresent() called\n");
1422 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
1426 &hKey
) != ERROR_SUCCESS
)
1427 return CR_REGISTRY_ERROR
;
1429 dwSize
= sizeof(DWORD
);
1430 if (RegQueryValueExW(hKey
,
1435 &dwSize
) != ERROR_SUCCESS
)
1436 ret
= CR_REGISTRY_ERROR
;
1440 if (ret
== CR_SUCCESS
)
1442 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
1444 ret
= CR_REGISTRY_ERROR
;
1446 else if (dwValue
!= 0)
1452 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
1459 DWORD
PNP_RequestEjectPC(
1463 return CR_CALL_NOT_IMPLEMENTED
;
1468 DWORD
PNP_HwProfFlags(
1474 PPNP_VETO_TYPE pVetoType
,
1480 return CR_CALL_NOT_IMPLEMENTED
;
1485 DWORD
PNP_GetHwProfInfo(
1488 HWPROFILEINFO
*pHWProfileInfo
,
1489 DWORD ulProfileInfoSize
,
1493 return CR_CALL_NOT_IMPLEMENTED
;
1498 DWORD
PNP_AddEmptyLogConf(
1502 DWORD
*pulLogConfTag
,
1506 return CR_CALL_NOT_IMPLEMENTED
;
1511 DWORD
PNP_FreeLogConf(
1514 DWORD ulLogConfType
,
1519 return CR_CALL_NOT_IMPLEMENTED
;
1524 DWORD
PNP_GetFirstLogConf(
1527 DWORD ulLogConfType
,
1528 DWORD
*pulLogConfTag
,
1532 return CR_CALL_NOT_IMPLEMENTED
;
1537 DWORD
PNP_GetNextLogConf(
1540 DWORD ulLogConfType
,
1546 return CR_CALL_NOT_IMPLEMENTED
;
1551 DWORD
PNP_GetLogConfPriority(
1560 return CR_CALL_NOT_IMPLEMENTED
;
1565 DWORD
PNP_AddResDes(
1569 DWORD ulLogConfType
,
1570 RESOURCEID ResourceID
,
1571 DWORD
*pulResourceTag
,
1573 PNP_RPC_BUFFER_SIZE ResourceLen
,
1577 return CR_CALL_NOT_IMPLEMENTED
;
1582 DWORD
PNP_FreeResDes(
1586 DWORD ulLogConfType
,
1587 RESOURCEID ResourceID
,
1588 DWORD ulResourceTag
,
1589 DWORD
*pulPreviousResType
,
1590 DWORD
*pulPreviousResTag
,
1594 return CR_CALL_NOT_IMPLEMENTED
;
1599 DWORD
PNP_GetNextResDes(
1603 DWORD ulLogConfType
,
1604 RESOURCEID ResourceID
,
1605 DWORD ulResourceTag
,
1606 DWORD
*pulNextResType
,
1607 DWORD
*pulNextResTag
,
1611 return CR_CALL_NOT_IMPLEMENTED
;
1616 DWORD
PNP_GetResDesData(
1620 DWORD ulLogConfType
,
1621 RESOURCEID ResourceID
,
1622 DWORD ulResourceTag
,
1624 PNP_RPC_BUFFER_SIZE BufferLen
,
1628 return CR_CALL_NOT_IMPLEMENTED
;
1633 DWORD
PNP_GetResDesDataSize(
1637 DWORD ulLogConfType
,
1638 RESOURCEID ResourceID
,
1639 DWORD ulResourceTag
,
1644 return CR_CALL_NOT_IMPLEMENTED
;
1649 DWORD
PNP_ModifyResDes(
1653 DWORD ulLogConfType
,
1654 RESOURCEID CurrentResourceID
,
1655 RESOURCEID NewResourceID
,
1656 DWORD ulResourceTag
,
1658 PNP_RPC_BUFFER_SIZE ResourceLen
,
1662 return CR_CALL_NOT_IMPLEMENTED
;
1667 DWORD
PNP_DetectResourceConflict(
1670 RESOURCEID ResourceID
,
1672 PNP_RPC_BUFFER_SIZE ResourceLen
,
1673 BOOL
*pbConflictDetected
,
1677 return CR_CALL_NOT_IMPLEMENTED
;
1682 DWORD
PNP_QueryResConfList(
1685 RESOURCEID ResourceID
,
1687 PNP_RPC_BUFFER_SIZE ResourceLen
,
1689 PNP_RPC_BUFFER_SIZE BufferLen
,
1693 return CR_CALL_NOT_IMPLEMENTED
;
1698 DWORD
PNP_SetHwProf(
1702 return CR_CALL_NOT_IMPLEMENTED
;
1707 DWORD
PNP_QueryArbitratorFreeData(
1711 return CR_CALL_NOT_IMPLEMENTED
;
1716 DWORD
PNP_QueryArbitratorFreeSize(
1720 return CR_CALL_NOT_IMPLEMENTED
;
1731 return CR_CALL_NOT_IMPLEMENTED
;
1736 DWORD
PNP_RegisterNotification(
1740 return CR_CALL_NOT_IMPLEMENTED
;
1745 DWORD
PNP_UnregisterNotification(
1749 return CR_CALL_NOT_IMPLEMENTED
;
1754 DWORD
PNP_GetCustomDevProp(
1757 LPWSTR CustomPropName
,
1758 DWORD
*pulRegDataType
,
1760 PNP_RPC_STRING_LEN
*pulTransferLen
,
1761 PNP_RPC_STRING_LEN
*pulLength
,
1765 return CR_CALL_NOT_IMPLEMENTED
;
1770 DWORD
PNP_GetVersionInternal(
1775 return CR_CALL_NOT_IMPLEMENTED
;
1780 DWORD
PNP_GetBlockedDriverInfo(
1783 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
1784 PNP_RPC_BUFFER_SIZE
*pulLength
,
1788 return CR_CALL_NOT_IMPLEMENTED
;
1793 DWORD
PNP_GetServerSideDeviceInstallFlags(
1795 DWORD
*pulSSDIFlags
,
1799 return CR_CALL_NOT_IMPLEMENTED
;
1804 DWORD
PNP_GetObjectPropKeys(
1808 LPWSTR PropertyCultureName
,
1809 PNP_PROP_COUNT
*PropertyCount
,
1810 PNP_PROP_COUNT
*TransferLen
,
1811 DEVPROPKEY
*PropertyKeys
,
1815 return CR_CALL_NOT_IMPLEMENTED
;
1820 DWORD
PNP_GetObjectProp(
1824 LPWSTR PropertyCultureName
,
1825 const DEVPROPKEY
*PropertyKey
,
1826 DEVPROPTYPE
*PropertyType
,
1827 PNP_PROP_SIZE
*PropertySize
,
1828 PNP_PROP_SIZE
*TransferLen
,
1829 BYTE
*PropertyBuffer
,
1833 return CR_CALL_NOT_IMPLEMENTED
;
1838 DWORD
PNP_SetObjectProp(
1842 LPWSTR PropertyCultureName
,
1843 const DEVPROPKEY
*PropertyKey
,
1844 DEVPROPTYPE PropertyType
,
1845 PNP_PROP_SIZE PropertySize
,
1846 BYTE
*PropertyBuffer
,
1850 return CR_CALL_NOT_IMPLEMENTED
;
1855 DWORD
PNP_InstallDevInst(
1859 return CR_CALL_NOT_IMPLEMENTED
;
1864 DWORD
PNP_ApplyPowerSettings(
1868 return CR_CALL_NOT_IMPLEMENTED
;
1873 DWORD
PNP_DriverStoreAddDriverPackage(
1877 return CR_CALL_NOT_IMPLEMENTED
;
1882 DWORD
PNP_DriverStoreDeleteDriverPackage(
1886 return CR_CALL_NOT_IMPLEMENTED
;
1891 DWORD
PNP_RegisterServiceNotification(
1895 return CR_CALL_NOT_IMPLEMENTED
;
1900 DWORD
PNP_SetActiveService(
1904 return CR_CALL_NOT_IMPLEMENTED
;
1909 DWORD
PNP_DeleteServiceDevices(
1913 return CR_CALL_NOT_IMPLEMENTED
;
1918 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
1920 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1922 BOOL DeviceInstalled
= FALSE
;
1925 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
1926 LPVOID Environment
= NULL
;
1927 PROCESS_INFORMATION ProcessInfo
;
1928 STARTUPINFOW StartupInfo
;
1931 /* The following lengths are constant (see below), they cannot overflow */
1932 WCHAR CommandLine
[116];
1933 WCHAR InstallEventName
[73];
1935 WCHAR UuidString
[39];
1937 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
1939 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
1941 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1943 PlugPlayData
.Operation
= 0; /* Get status */
1945 /* Get device status */
1946 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1947 (PVOID
)&PlugPlayData
,
1948 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1949 if (!NT_SUCCESS(Status
))
1951 DPRINT1("NtPlugPlayControl('%S') failed with status 0x%08lx\n", DeviceInstance
, Status
);
1955 if ((PlugPlayData
.DeviceStatus
& (DNF_STARTED
| DNF_START_FAILED
)) != 0)
1957 /* Device is already started, or disabled due to some problem. Don't install it */
1958 DPRINT("No need to install '%S'\n", DeviceInstance
);
1962 /* Create a random UUID for the named pipe */
1963 UuidCreate(&RandomUuid
);
1964 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
1965 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
1966 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
1967 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
1968 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
1970 /* Create the named pipe */
1971 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
1972 wcscat(PipeName
, UuidString
);
1973 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
1975 if(hPipe
== INVALID_HANDLE_VALUE
)
1977 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
1981 /* Launch rundll32 to call ClientSideInstallW */
1982 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
1983 wcscat(CommandLine
, PipeName
);
1985 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
1986 StartupInfo
.cb
= sizeof(StartupInfo
);
1990 /* newdev has to run under the environment of the current user */
1991 if(!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
1993 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
1997 if(!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
1999 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
2005 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
2007 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
2008 (ShowWizard is only set to FALSE for these two modes) */
2009 ASSERT(!ShowWizard
);
2011 if(!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
2013 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
2018 /* Wait for the function to connect to our pipe */
2019 if(!ConnectNamedPipe(hPipe
, NULL
))
2021 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
2025 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
2026 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
2027 wcscat(InstallEventName
, UuidString
);
2029 Value
= sizeof(InstallEventName
);
2030 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2031 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
2033 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
2034 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
2035 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
2037 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
2038 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2039 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
2041 /* Wait for newdev.dll to finish processing */
2042 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
2044 /* The following check for success is probably not compatible to Windows, but should do its job */
2045 if(!GetExitCodeProcess(ProcessInfo
.hProcess
, &Value
))
2047 DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
2051 DeviceInstalled
= Value
;
2054 if(hPipe
!= INVALID_HANDLE_VALUE
)
2058 DestroyEnvironmentBlock(Environment
);
2060 if(ProcessInfo
.hProcess
)
2061 CloseHandle(ProcessInfo
.hProcess
);
2063 if(ProcessInfo
.hThread
)
2064 CloseHandle(ProcessInfo
.hThread
);
2066 return DeviceInstalled
;
2082 return ERROR_INVALID_PARAMETER
;
2085 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
2086 if (rc
!= ERROR_SUCCESS
)
2088 if (dwType
!= REG_SZ
)
2089 return ERROR_FILE_NOT_FOUND
;
2090 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
2092 return ERROR_NOT_ENOUGH_MEMORY
;
2093 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
2094 if (rc
!= ERROR_SUCCESS
)
2096 HeapFree(GetProcessHeap(), 0, Value
);
2099 /* NULL-terminate the string */
2100 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
2103 return ERROR_SUCCESS
;
2111 DWORD regType
, active
, size
;
2115 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
2116 if (rc
!= ERROR_SUCCESS
)
2119 size
= sizeof(DWORD
);
2120 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
2121 if (rc
!= ERROR_SUCCESS
)
2123 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
2126 ret
= (active
!= 0);
2132 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
2141 HKEY ControlKey
= NULL
;
2142 LPWSTR SystemStartOptions
= NULL
;
2143 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
2144 BOOL ConsoleBoot
= FALSE
;
2149 L
"SYSTEM\\CurrentControlSet\\Control",
2154 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
2155 if (rc
!= ERROR_SUCCESS
)
2158 /* Check for CMDCONS in SystemStartOptions */
2159 CurrentOption
= SystemStartOptions
;
2160 while (CurrentOption
)
2162 NextOption
= wcschr(CurrentOption
, L
' ');
2164 *NextOption
= L
'\0';
2165 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
2167 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
2171 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
2175 if (ControlKey
!= NULL
)
2176 RegCloseKey(ControlKey
);
2177 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
2182 /* Loop to install all queued devices installations */
2184 DeviceInstallThread(LPVOID lpParameter
)
2186 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2187 PSLIST_ENTRY ListEntry
;
2189 PLIST_ENTRY ListEntry
;
2191 DeviceInstallParams
* Params
;
2194 UNREFERENCED_PARAMETER(lpParameter
);
2196 WaitForSingleObject(hInstallEvent
, INFINITE
);
2198 showWizard
= !SetupIsActive() && !IsConsoleBoot();
2202 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2203 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
2205 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
2208 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
2210 if (ListEntry
== NULL
)
2212 SetEvent(hNoPendingInstalls
);
2213 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
2217 ResetEvent(hNoPendingInstalls
);
2218 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
2219 InstallDevice(Params
->DeviceIds
, showWizard
);
2228 PnpEventThread(LPVOID lpParameter
)
2230 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
2233 RPC_STATUS RpcStatus
;
2235 UNREFERENCED_PARAMETER(lpParameter
);
2237 PnpEventSize
= 0x1000;
2238 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
2239 if (PnpEvent
== NULL
)
2240 return ERROR_OUTOFMEMORY
;
2244 DPRINT("Calling NtGetPlugPlayEvent()\n");
2246 /* Wait for the next pnp event */
2247 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
2249 /* Resize the buffer for the PnP event if it's too small. */
2250 if (Status
== STATUS_BUFFER_TOO_SMALL
)
2252 PnpEventSize
+= 0x400;
2253 HeapFree(GetProcessHeap(), 0, PnpEvent
);
2254 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
2255 if (PnpEvent
== NULL
)
2256 return ERROR_OUTOFMEMORY
;
2260 if (!NT_SUCCESS(Status
))
2262 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
2266 /* Process the pnp event */
2267 DPRINT("Received PnP Event\n");
2268 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
2270 DeviceInstallParams
* Params
;
2272 DWORD DeviceIdLength
;
2274 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
2276 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
2279 /* Queue device install (will be dequeued by DeviceInstallThread */
2280 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
2281 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
2284 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
2285 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2286 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
2288 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
2290 SetEvent(hDeviceInstallListNotEmpty
);
2296 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
2297 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
2298 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
2299 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
2300 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
2303 /* Dequeue the current pnp event and signal the next one */
2304 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
2307 HeapFree(GetProcessHeap(), 0, PnpEvent
);
2309 return ERROR_SUCCESS
;
2313 static VOID CALLBACK
2314 ServiceMain(DWORD argc
, LPTSTR
*argv
)
2319 UNREFERENCED_PARAMETER(argc
);
2320 UNREFERENCED_PARAMETER(argv
);
2322 DPRINT("ServiceMain() called\n");
2324 hThread
= CreateThread(NULL
,
2330 if (hThread
!= NULL
)
2331 CloseHandle(hThread
);
2333 hThread
= CreateThread(NULL
,
2339 if (hThread
!= NULL
)
2340 CloseHandle(hThread
);
2342 hThread
= CreateThread(NULL
,
2344 DeviceInstallThread
,
2348 if (hThread
!= NULL
)
2349 CloseHandle(hThread
);
2351 DPRINT("ServiceMain() done\n");
2356 wmain(int argc
, WCHAR
*argv
[])
2361 UNREFERENCED_PARAMETER(argc
);
2362 UNREFERENCED_PARAMETER(argv
);
2364 DPRINT("Umpnpmgr: main() started\n");
2366 /* We need this privilege for using CreateProcessAsUserW */
2367 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
2369 hInstallEvent
= CreateEvent(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
2370 if (hInstallEvent
== NULL
)
2372 dwError
= GetLastError();
2373 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
2377 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
2378 if (hDeviceInstallListNotEmpty
== NULL
)
2380 dwError
= GetLastError();
2381 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
2385 hNoPendingInstalls
= CreateEventW(NULL
,
2388 L
"Global\\PnP_No_Pending_Install_Events");
2389 if (hNoPendingInstalls
== NULL
)
2391 dwError
= GetLastError();
2392 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
2396 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
2397 InitializeSListHead(&DeviceInstallListHead
);
2399 InitializeListHead(&DeviceInstallListHead
);
2402 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2403 L
"System\\CurrentControlSet\\Enum",
2407 if (dwError
!= ERROR_SUCCESS
)
2409 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
2413 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2414 L
"System\\CurrentControlSet\\Control\\Class",
2418 if (dwError
!= ERROR_SUCCESS
)
2420 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
2424 StartServiceCtrlDispatcher(ServiceTable
);
2426 DPRINT("Umpnpmgr: main() done\n");