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)
28 /* INCLUDES *****************************************************************/
29 //#define HAVE_SLIST_ENTRY_IMPLEMENTED
30 #define WIN32_NO_STATUS
35 #include <umpnpmgr/sysguid.h>
47 /* GLOBALS ******************************************************************/
50 ServiceMain(DWORD argc
, LPTSTR
*argv
);
52 static SERVICE_TABLE_ENTRY ServiceTable
[2] =
54 {TEXT("PlugPlay"), ServiceMain
},
58 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
60 static HKEY hEnumKey
= NULL
;
61 static HKEY hClassKey
= NULL
;
63 static HANDLE hUserToken
= NULL
;
64 static HANDLE hInstallEvent
= NULL
;
65 static HANDLE hNoPendingInstalls
= NULL
;
67 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
68 static SLIST_HEADER DeviceInstallListHead
;
70 static LIST_ENTRY DeviceInstallListHead
;
72 static HANDLE hDeviceInstallListNotEmpty
;
76 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
77 SLIST_ENTRY ListEntry
;
82 } DeviceInstallParams
;
84 /* FUNCTIONS *****************************************************************/
87 RpcServerThread(LPVOID lpParameter
)
91 UNREFERENCED_PARAMETER(lpParameter
);
93 DPRINT("RpcServerThread() called\n");
95 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
98 NULL
); // Security descriptor
99 if (Status
!= RPC_S_OK
)
101 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
105 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
108 if (Status
!= RPC_S_OK
)
110 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
114 Status
= RpcServerListen(1,
117 if (Status
!= RPC_S_OK
)
119 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
123 /* ROS HACK (this should never happen...) */
124 DPRINT1("*** Other devices won't be installed correctly. If something\n");
125 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
127 DPRINT("RpcServerThread() done\n");
133 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
135 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
139 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
141 HeapFree(GetProcessHeap(), 0, ptr
);
145 static CONFIGRET WINAPI
146 NtStatusToCrError(NTSTATUS Status
)
150 case STATUS_NO_SUCH_DEVICE
:
151 return CR_NO_SUCH_DEVINST
;
154 /* FIXME: add more mappings */
155 DPRINT1("Unable to map status 0x%08lx\n", Status
);
163 PNP_GetVersion(handle_t BindingHandle
,
164 unsigned short *Version
)
166 UNREFERENCED_PARAMETER(BindingHandle
);
175 PNP_GetGlobalState(handle_t BindingHandle
,
176 unsigned long *State
,
179 UNREFERENCED_PARAMETER(BindingHandle
);
180 UNREFERENCED_PARAMETER(Flags
);
182 *State
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
189 PNP_InitDetection(handle_t BindingHandle
)
191 UNREFERENCED_PARAMETER(BindingHandle
);
193 DPRINT("PNP_InitDetection() called\n");
200 PNP_ReportLogOn(handle_t BindingHandle
,
206 UNREFERENCED_PARAMETER(BindingHandle
);
208 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
210 if (hInstallEvent
!= NULL
)
211 SetEvent(hInstallEvent
);
213 /* Get the users token */
214 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
,
217 if (hProcess
!= NULL
)
219 if (hUserToken
!= NULL
)
221 CloseHandle(hUserToken
);
225 OpenProcessToken(hProcess
,
228 CloseHandle(hProcess
);
231 /* Trigger the installer thread */
232 /*if (hInstallEvent != NULL)
233 SetEvent(hInstallEvent);*/
241 PNP_ValidateDeviceInstance(handle_t BindingHandle
,
242 wchar_t *DeviceInstance
,
245 CONFIGRET ret
= CR_SUCCESS
;
246 HKEY hDeviceKey
= NULL
;
248 UNREFERENCED_PARAMETER(BindingHandle
);
250 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
251 DeviceInstance
, Flags
);
253 if (RegOpenKeyExW(hEnumKey
,
259 DPRINT("Could not open the Device Key!\n");
260 ret
= CR_NO_SUCH_DEVNODE
;
264 /* FIXME: add more tests */
267 if (hDeviceKey
!= NULL
)
268 RegCloseKey(hDeviceKey
);
270 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
278 PNP_GetRootDeviceInstance(handle_t BindingHandle
,
279 wchar_t *DeviceInstance
,
282 CONFIGRET ret
= CR_SUCCESS
;
284 UNREFERENCED_PARAMETER(BindingHandle
);
286 DPRINT("PNP_GetRootDeviceInstance() called\n");
288 if (Length
< lstrlenW(szRootDeviceId
) + 1)
290 ret
= CR_BUFFER_SMALL
;
294 lstrcpyW(DeviceInstance
,
298 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
306 PNP_GetRelatedDeviceInstance(handle_t BindingHandle
,
309 wchar_t *RelatedDeviceId
,
313 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
314 CONFIGRET ret
= CR_SUCCESS
;
317 UNREFERENCED_PARAMETER(BindingHandle
);
318 UNREFERENCED_PARAMETER(Flags
);
320 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
321 DPRINT(" Relationship %ld\n", Relationship
);
322 DPRINT(" DeviceId %S\n", DeviceId
);
324 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
327 PlugPlayData
.Relation
= Relationship
;
329 PlugPlayData
.RelatedDeviceInstanceLength
= Length
;
330 PlugPlayData
.RelatedDeviceInstance
= RelatedDeviceId
;
332 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
333 (PVOID
)&PlugPlayData
,
334 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
335 if (!NT_SUCCESS(Status
))
337 ret
= NtStatusToCrError(Status
);
340 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
341 if (ret
== CR_SUCCESS
)
343 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
352 PNP_EnumerateSubKeys(handle_t BindingHandle
,
357 DWORD
*RequiredLength
,
360 CONFIGRET ret
= CR_SUCCESS
;
364 UNREFERENCED_PARAMETER(BindingHandle
);
365 UNREFERENCED_PARAMETER(Flags
);
367 DPRINT("PNP_EnumerateSubKeys() called\n");
371 case PNP_BRANCH_ENUM
:
375 case PNP_BRANCH_CLASS
:
383 *RequiredLength
= Length
;
384 dwError
= RegEnumKeyExW(hKey
,
392 if (dwError
!= ERROR_SUCCESS
)
394 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
401 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
409 PNP_GetDeviceListSize(handle_t BindingHandle
,
411 unsigned long *Length
,
414 UNREFERENCED_PARAMETER(BindingHandle
);
415 UNREFERENCED_PARAMETER(Filter
);
416 UNREFERENCED_PARAMETER(Flags
);
418 DPRINT("PNP_GetDeviceListSize() called\n");
429 PNP_GetDepth(handle_t BindingHandle
,
430 wchar_t *DeviceInstance
,
431 unsigned long *Depth
,
434 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
435 CONFIGRET ret
= CR_SUCCESS
;
438 UNREFERENCED_PARAMETER(BindingHandle
);
439 UNREFERENCED_PARAMETER(Flags
);
441 DPRINT("PNP_GetDepth() called\n");
443 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
446 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
447 (PVOID
)&PlugPlayData
,
448 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
449 if (NT_SUCCESS(Status
))
451 *Depth
= PlugPlayData
.Depth
;
455 ret
= NtStatusToCrError(Status
);
458 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
466 PNP_GetDeviceRegProp(handle_t BindingHandle
,
467 wchar_t *DeviceInstance
,
475 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
476 CONFIGRET ret
= CR_SUCCESS
;
477 LPWSTR lpValueName
= NULL
;
481 UNREFERENCED_PARAMETER(BindingHandle
);
482 UNREFERENCED_PARAMETER(Flags
);
484 DPRINT("PNP_GetDeviceRegProp() called\n");
488 case CM_DRP_DEVICEDESC
:
489 lpValueName
= L
"DeviceDesc";
492 case CM_DRP_HARDWAREID
:
493 lpValueName
= L
"HardwareID";
496 case CM_DRP_COMPATIBLEIDS
:
497 lpValueName
= L
"CompatibleIDs";
501 lpValueName
= L
"Service";
505 lpValueName
= L
"Class";
508 case CM_DRP_CLASSGUID
:
509 lpValueName
= L
"ClassGUID";
513 lpValueName
= L
"Driver";
516 case CM_DRP_CONFIGFLAGS
:
517 lpValueName
= L
"ConfigFlags";
521 lpValueName
= L
"Mfg";
524 case CM_DRP_FRIENDLYNAME
:
525 lpValueName
= L
"FriendlyName";
528 case CM_DRP_LOCATION_INFORMATION
:
529 lpValueName
= L
"LocationInformation";
532 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
536 case CM_DRP_CAPABILITIES
:
537 lpValueName
= L
"Capabilities";
540 case CM_DRP_UI_NUMBER
:
544 case CM_DRP_UPPERFILTERS
:
545 lpValueName
= L
"UpperFilters";
548 case CM_DRP_LOWERFILTERS
:
549 lpValueName
= L
"LowerFilters";
552 case CM_DRP_BUSTYPEGUID
:
556 case CM_DRP_LEGACYBUSTYPE
:
560 case CM_DRP_BUSNUMBER
:
564 case CM_DRP_ENUMERATOR_NAME
:
569 return CR_INVALID_PROPERTY
;
572 DPRINT("Value name: %S\n", lpValueName
);
576 /* Retrieve information from the Registry */
577 if (RegOpenKeyExW(hEnumKey
,
582 return CR_INVALID_DEVNODE
;
584 if (RegQueryValueExW(hKey
,
590 ret
= CR_REGISTRY_ERROR
;
592 /* FIXME: Check buffer size */
598 /* Retrieve information from the Device Node */
599 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
601 PlugPlayData
.Buffer
= Buffer
;
602 PlugPlayData
.BufferSize
= *TransferLen
;
607 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
608 PlugPlayData
.Property
= DevicePropertyPhysicalDeviceObjectName
;
611 case CM_DRP_UI_NUMBER
:
612 PlugPlayData
.Property
= DevicePropertyUINumber
;
615 case CM_DRP_BUSTYPEGUID
:
616 PlugPlayData
.Property
= DevicePropertyBusTypeGuid
;
619 case CM_DRP_LEGACYBUSTYPE
:
620 PlugPlayData
.Property
= DevicePropertyLegacyBusType
;
623 case CM_DRP_BUSNUMBER
:
624 PlugPlayData
.Property
= DevicePropertyBusNumber
;
627 case CM_DRP_ENUMERATOR_NAME
:
628 PlugPlayData
.Property
= DevicePropertyEnumeratorName
;
633 return CR_INVALID_PROPERTY
;
636 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
637 (PVOID
)&PlugPlayData
,
638 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
639 if (NT_SUCCESS(Status
))
641 *Length
= PlugPlayData
.BufferSize
;
645 ret
= NtStatusToCrError(Status
);
649 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
657 PNP_SetDeviceRegProp(handle_t BindingHandle
,
659 unsigned long Property
,
660 unsigned long DataType
,
662 unsigned long Length
,
665 CONFIGRET ret
= CR_SUCCESS
;
666 LPWSTR lpValueName
= NULL
;
669 UNREFERENCED_PARAMETER(BindingHandle
);
670 UNREFERENCED_PARAMETER(Flags
);
672 DPRINT("PNP_SetDeviceRegProp() called\n");
674 DPRINT("DeviceId: %S\n", DeviceId
);
675 DPRINT("Property: %lu\n", Property
);
676 DPRINT("DataType: %lu\n", DataType
);
677 DPRINT("Length: %lu\n", Length
);
681 case CM_DRP_DEVICEDESC
:
682 lpValueName
= L
"DeviceDesc";
685 case CM_DRP_HARDWAREID
:
686 lpValueName
= L
"HardwareID";
689 case CM_DRP_COMPATIBLEIDS
:
690 lpValueName
= L
"CompatibleIDs";
694 lpValueName
= L
"Service";
698 lpValueName
= L
"Class";
701 case CM_DRP_CLASSGUID
:
702 lpValueName
= L
"ClassGUID";
706 lpValueName
= L
"Driver";
709 case CM_DRP_CONFIGFLAGS
:
710 lpValueName
= L
"ConfigFlags";
714 lpValueName
= L
"Mfg";
717 case CM_DRP_FRIENDLYNAME
:
718 lpValueName
= L
"FriendlyName";
721 case CM_DRP_LOCATION_INFORMATION
:
722 lpValueName
= L
"LocationInformation";
725 case CM_DRP_UPPERFILTERS
:
726 lpValueName
= L
"UpperFilters";
729 case CM_DRP_LOWERFILTERS
:
730 lpValueName
= L
"LowerFilters";
734 return CR_INVALID_PROPERTY
;
737 DPRINT("Value name: %S\n", lpValueName
);
739 if (RegOpenKeyExW(hEnumKey
,
744 return CR_INVALID_DEVNODE
;
748 if (RegDeleteValueW(hKey
,
750 ret
= CR_REGISTRY_ERROR
;
754 if (RegSetValueExW(hKey
,
760 ret
= CR_REGISTRY_ERROR
;
765 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
773 PNP_GetClassInstance(handle_t BindingHandle
,
774 wchar_t *DeviceId
, /* in */
775 wchar_t *Buffer
, /* out */
776 unsigned long Length
)
778 CONFIGRET ret
= CR_SUCCESS
;
780 UNREFERENCED_PARAMETER(BindingHandle
);
781 UNREFERENCED_PARAMETER(DeviceId
);
782 UNREFERENCED_PARAMETER(Buffer
);
783 UNREFERENCED_PARAMETER(Length
);
785 DPRINT("PNP_Get_Class_Instance() called\n");
787 DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret
);
795 PNP_CreateKey(handle_t BindingHandle
,
797 unsigned long samDesired
,
800 CONFIGRET ret
= CR_SUCCESS
;
802 UNREFERENCED_PARAMETER(BindingHandle
);
803 UNREFERENCED_PARAMETER(SubKey
);
804 UNREFERENCED_PARAMETER(samDesired
);
805 UNREFERENCED_PARAMETER(Flags
);
807 DPRINT("PNP_CreateKey() called\n");
809 DPRINT("PNP_CreateKey() done (returns %lx)\n", ret
);
817 PNP_DeleteRegistryKey(handle_t BindingHandle
,
823 CONFIGRET ret
= CR_SUCCESS
;
825 UNREFERENCED_PARAMETER(BindingHandle
);
826 UNREFERENCED_PARAMETER(DeviceId
);
827 UNREFERENCED_PARAMETER(ParentKey
);
828 UNREFERENCED_PARAMETER(ChildKey
);
829 UNREFERENCED_PARAMETER(Flags
);
831 DPRINT("PNP_DeleteRegistryKey() called\n");
833 DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret
);
842 PNP_GetClassCount(handle_t BindingHandle
,
843 unsigned long *ClassCount
,
849 UNREFERENCED_PARAMETER(BindingHandle
);
851 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
856 if (dwError
!= ERROR_SUCCESS
)
857 return CR_INVALID_DATA
;
859 dwError
= RegQueryInfoKeyW(hKey
,
872 if (dwError
!= ERROR_SUCCESS
)
873 return CR_INVALID_DATA
;
882 PNP_GetClassName(handle_t BindingHandle
,
885 unsigned long *Length
,
888 WCHAR szKeyName
[MAX_PATH
];
889 CONFIGRET ret
= CR_SUCCESS
;
893 UNREFERENCED_PARAMETER(BindingHandle
);
894 UNREFERENCED_PARAMETER(Flags
);
896 DPRINT("PNP_GetClassName() called\n");
898 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class");
899 lstrcatW(szKeyName
, L
"\\");
900 if(lstrlenW(ClassGuid
) < sizeof(szKeyName
)/sizeof(WCHAR
)-lstrlenW(szKeyName
))
901 lstrcatW(szKeyName
, ClassGuid
);
902 else return CR_INVALID_DATA
;
904 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
909 return CR_REGISTRY_ERROR
;
911 dwSize
= *Length
* sizeof(WCHAR
);
912 if (RegQueryValueExW(hKey
,
920 ret
= CR_REGISTRY_ERROR
;
924 *Length
= dwSize
/ sizeof(WCHAR
);
929 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
937 PNP_DeleteClassKey(handle_t BindingHandle
,
941 CONFIGRET ret
= CR_SUCCESS
;
943 UNREFERENCED_PARAMETER(BindingHandle
);
945 DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid
, Flags
);
947 if (Flags
& CM_DELETE_CLASS_SUBKEYS
)
949 if (RegDeleteTreeW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
950 ret
= CR_REGISTRY_ERROR
;
954 if (RegDeleteKeyW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
955 ret
= CR_REGISTRY_ERROR
;
958 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
966 PNP_CreateDevInst(handle_t BindingHandle
,
967 wchar_t *DeviceId
, /* [in, out, string, size_is(Length)] */
968 wchar_t *ParentDeviceId
, /* [in, string] */
969 unsigned long Length
, /* [in] */
970 unsigned long Flags
) /* [in] */
972 CONFIGRET ret
= CR_CALL_NOT_IMPLEMENTED
;
974 UNREFERENCED_PARAMETER(BindingHandle
);
975 UNREFERENCED_PARAMETER(DeviceId
);
976 UNREFERENCED_PARAMETER(ParentDeviceId
);
977 UNREFERENCED_PARAMETER(Length
);
978 UNREFERENCED_PARAMETER(Flags
);
980 DPRINT1("PNP_CreateDevInst() called\n");
982 DPRINT1("PNP_CreateDevInst() done (returns %lx)\n", ret
);
990 PNP_DeviceInstanceAction(handle_t BindingHandle
,
991 unsigned long MajorAction
,
992 unsigned long MinorAction
,
993 wchar_t *DeviceInstance1
,
994 wchar_t *DeviceInstance2
)
996 CONFIGRET ret
= CR_SUCCESS
;
998 UNREFERENCED_PARAMETER(BindingHandle
);
999 UNREFERENCED_PARAMETER(MinorAction
);
1000 UNREFERENCED_PARAMETER(DeviceInstance1
);
1001 UNREFERENCED_PARAMETER(DeviceInstance2
);
1003 DPRINT("PNP_DeviceInstanceAction() called\n");
1005 switch (MajorAction
)
1008 DPRINT("Move device instance\n");
1010 ret
= CR_CALL_NOT_IMPLEMENTED
;
1014 DPRINT("Setup device instance\n");
1016 ret
= CR_CALL_NOT_IMPLEMENTED
;
1020 DPRINT("Enable device instance\n");
1022 ret
= CR_CALL_NOT_IMPLEMENTED
;
1026 DPRINT("Disable device instance\n");
1028 ret
= CR_CALL_NOT_IMPLEMENTED
;
1032 DPRINT("Reenumerate device instance\n");
1034 ret
= CR_CALL_NOT_IMPLEMENTED
;
1038 DPRINT1("Unknown function %lu\n", MajorAction
);
1039 ret
= CR_CALL_NOT_IMPLEMENTED
;
1042 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1050 PNP_GetDeviceStatus(handle_t BindingHandle
,
1051 wchar_t *DeviceInstance
,
1052 unsigned long *pStatus
,
1053 unsigned long *pProblem
,
1056 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1057 CONFIGRET ret
= CR_SUCCESS
;
1060 UNREFERENCED_PARAMETER(BindingHandle
);
1061 UNREFERENCED_PARAMETER(Flags
);
1063 DPRINT("PNP_GetDeviceStatus() called\n");
1065 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1067 PlugPlayData
.Operation
= 0; /* Get status */
1069 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1070 (PVOID
)&PlugPlayData
,
1071 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1072 if (NT_SUCCESS(Status
))
1074 *pStatus
= PlugPlayData
.DeviceStatus
;
1075 *pProblem
= PlugPlayData
.DeviceProblem
;
1079 ret
= NtStatusToCrError(Status
);
1082 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1090 PNP_SetDeviceProblem(handle_t BindingHandle
,
1091 wchar_t *DeviceInstance
,
1092 unsigned long Problem
,
1095 CONFIGRET ret
= CR_SUCCESS
;
1097 UNREFERENCED_PARAMETER(BindingHandle
);
1098 UNREFERENCED_PARAMETER(DeviceInstance
);
1099 UNREFERENCED_PARAMETER(Problem
);
1100 UNREFERENCED_PARAMETER(Flags
);
1102 DPRINT1("PNP_SetDeviceProblem() called\n");
1106 DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret
);
1114 PNP_UninstallDevInst(handle_t BindingHandle
,
1115 wchar_t *DeviceInstance
,
1118 CONFIGRET ret
= CR_SUCCESS
;
1120 UNREFERENCED_PARAMETER(BindingHandle
);
1121 UNREFERENCED_PARAMETER(DeviceInstance
);
1122 UNREFERENCED_PARAMETER(Flags
);
1124 DPRINT1("PNP_UninstallDevInst() called\n");
1128 DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret
);
1135 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1141 lpPtr
= lpDeviceIdList
;
1144 dwLength
= wcslen(lpPtr
);
1145 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1148 lpPtr
+= (dwLength
+ 1);
1156 AppendDeviceId(LPWSTR lpDeviceIdList
,
1157 LPDWORD lpDeviceIdListSize
,
1163 dwLen
= wcslen(lpDeviceId
);
1164 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1166 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1168 dwPos
+= (dwLen
+ 1);
1170 lpDeviceIdList
[dwPos
] = 0;
1172 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1178 PNP_AddID(handle_t BindingHandle
,
1179 wchar_t *DeviceInstance
,
1183 CONFIGRET ret
= CR_SUCCESS
;
1186 DWORD dwDeviceIdListSize
;
1187 WCHAR szDeviceIdList
[512];
1189 UNREFERENCED_PARAMETER(BindingHandle
);
1191 DPRINT("PNP_AddID() called\n");
1192 DPRINT(" DeviceInstance: %S\n", DeviceInstance
);
1193 DPRINT(" DeviceId: %S\n", DeviceId
);
1194 DPRINT(" Flags: %lx\n", Flags
);
1196 if (RegOpenKeyExW(hEnumKey
,
1199 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1200 &hDeviceKey
) != ERROR_SUCCESS
)
1202 DPRINT("Failed to open the device key!\n");
1203 return CR_INVALID_DEVNODE
;
1206 pszSubKey
= (Flags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1208 dwDeviceIdListSize
= 512 * sizeof(WCHAR
);
1209 if (RegQueryValueExW(hDeviceKey
,
1213 (LPBYTE
)szDeviceIdList
,
1214 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1216 DPRINT("Failed to query the desired ID string!\n");
1217 ret
= CR_REGISTRY_ERROR
;
1221 /* Check whether the device ID is already in use */
1222 if (CheckForDeviceId(szDeviceIdList
, DeviceId
))
1224 DPRINT("Device ID was found in the ID string!\n");
1229 /* Append the Device ID */
1230 AppendDeviceId(szDeviceIdList
, &dwDeviceIdListSize
, DeviceId
);
1232 if (RegSetValueExW(hDeviceKey
,
1236 (LPBYTE
)szDeviceIdList
,
1237 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1239 DPRINT("Failed to set the desired ID string!\n");
1240 ret
= CR_REGISTRY_ERROR
;
1244 RegCloseKey(hDeviceKey
);
1246 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1254 PNP_IsDockStationPresent(handle_t BindingHandle
,
1255 unsigned long *Present
)
1261 CONFIGRET ret
= CR_SUCCESS
;
1263 UNREFERENCED_PARAMETER(BindingHandle
);
1265 DPRINT1("PNP_IsDockStationPresent() called\n");
1269 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
1273 &hKey
) != ERROR_SUCCESS
)
1274 return CR_REGISTRY_ERROR
;
1276 dwSize
= sizeof(DWORD
);
1277 if (RegQueryValueExW(hKey
,
1282 &dwSize
) != ERROR_SUCCESS
)
1283 ret
= CR_REGISTRY_ERROR
;
1287 if (ret
== CR_SUCCESS
)
1289 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
1291 ret
= CR_REGISTRY_ERROR
;
1293 else if (dwValue
!= 0)
1299 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
1307 PNP_RequestEjectPC(handle_t BindingHandle
)
1309 CONFIGRET ret
= CR_SUCCESS
;
1311 UNREFERENCED_PARAMETER(BindingHandle
);
1313 DPRINT1("PNP_RequestEjectPC() called\n");
1315 ret
= CR_FAILURE
; /* FIXME */
1317 DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret
);
1325 PNP_HwProfFlags(handle_t BindingHandle
,
1329 DWORD
*Value
, // out
1332 CONFIGRET ret
= CR_SUCCESS
;
1334 UNREFERENCED_PARAMETER(BindingHandle
);
1335 UNREFERENCED_PARAMETER(Action
);
1336 UNREFERENCED_PARAMETER(DeviceId
);
1337 UNREFERENCED_PARAMETER(ProfileId
);
1338 UNREFERENCED_PARAMETER(Value
);
1339 UNREFERENCED_PARAMETER(Flags
);
1341 DPRINT1("PNP_HwProfFlags() called\n");
1343 ret
= CR_CALL_NOT_IMPLEMENTED
; /* FIXME */
1345 DPRINT1("PNP_HwProfFlags() done (returns %lx)\n", ret
);
1353 PNP_AddEmptyLogConf(handle_t BindingHandle
,
1354 wchar_t *DeviceInstance
,
1355 unsigned long ulPriority
,
1356 unsigned long *pulLogConfTag
,
1357 unsigned long ulFlags
)
1359 CONFIGRET ret
= CR_SUCCESS
;
1361 UNREFERENCED_PARAMETER(BindingHandle
);
1362 UNREFERENCED_PARAMETER(DeviceInstance
);
1363 UNREFERENCED_PARAMETER(ulPriority
);
1364 UNREFERENCED_PARAMETER(ulFlags
);
1366 DPRINT1("PNP_AddEmptyLogConf() called\n");
1368 *pulLogConfTag
= 0; /* FIXME */
1370 DPRINT1("PNP_AddEmptyLogConf() done (returns %lx)\n", ret
);
1378 PNP_FreeLogConf(handle_t BindingHandle
,
1379 wchar_t *DeviceInstance
,
1380 unsigned long ulType
,
1381 unsigned long ulLogConfTag
,
1382 unsigned long ulFlags
)
1384 CONFIGRET ret
= CR_SUCCESS
;
1386 UNREFERENCED_PARAMETER(BindingHandle
);
1387 UNREFERENCED_PARAMETER(DeviceInstance
);
1388 UNREFERENCED_PARAMETER(ulType
);
1389 UNREFERENCED_PARAMETER(ulLogConfTag
);
1390 UNREFERENCED_PARAMETER(ulFlags
);
1392 DPRINT1("PNP_FreeLogConf() called\n");
1395 DPRINT1("PNP_FreeLogConf() done (returns %lx)\n", ret
);
1403 PNP_GetFirstLogConf(handle_t BindingHandle
,
1404 wchar_t *DeviceInstance
,
1405 unsigned long ulPriority
,
1406 unsigned long *pulLogConfTag
,
1407 unsigned long ulFlags
)
1409 CONFIGRET ret
= CR_SUCCESS
;
1411 UNREFERENCED_PARAMETER(BindingHandle
);
1412 UNREFERENCED_PARAMETER(DeviceInstance
);
1413 UNREFERENCED_PARAMETER(ulPriority
);
1414 UNREFERENCED_PARAMETER(ulFlags
);
1416 DPRINT1("PNP_GetFirstLogConf() called\n");
1418 *pulLogConfTag
= 0; /* FIXME */
1420 DPRINT1("PNP_GetFirstLogConf() done (returns %lx)\n", ret
);
1428 PNP_GetNextLogConf(handle_t BindingHandle
,
1429 wchar_t *DeviceInstance
,
1430 unsigned long ulLogConfType
,
1431 unsigned long ulCurrentTag
,
1432 unsigned long *pulNextTag
,
1433 unsigned long ulFlags
)
1435 CONFIGRET ret
= CR_SUCCESS
;
1437 UNREFERENCED_PARAMETER(BindingHandle
);
1438 UNREFERENCED_PARAMETER(DeviceInstance
);
1439 UNREFERENCED_PARAMETER(ulLogConfType
);
1440 UNREFERENCED_PARAMETER(ulCurrentTag
);
1441 UNREFERENCED_PARAMETER(ulFlags
);
1443 DPRINT1("PNP_GetNextLogConf() called\n");
1445 *pulNextTag
= 0; /* FIXME */
1447 DPRINT1("PNP_GetNextLogConf() done (returns %lx)\n", ret
);
1455 PNP_GetLogConfPriority(handle_t BindingHandle
,
1456 wchar_t *DeviceInstance
,
1457 unsigned long ulLogConfType
,
1458 unsigned long ulCurrentTag
,
1459 unsigned long *pPriority
,
1460 unsigned long ulFlags
)
1462 CONFIGRET ret
= CR_SUCCESS
;
1464 UNREFERENCED_PARAMETER(BindingHandle
);
1465 UNREFERENCED_PARAMETER(DeviceInstance
);
1466 UNREFERENCED_PARAMETER(ulLogConfType
);
1467 UNREFERENCED_PARAMETER(ulCurrentTag
);
1468 UNREFERENCED_PARAMETER(ulFlags
);
1470 DPRINT1("PNP_GetLogConfPriority() called\n");
1472 *pPriority
= 0; /* FIXME */
1474 DPRINT1("PNP_GetLogConfPriority() done (returns %lx)\n", ret
);
1482 PNP_RunDetection(handle_t BindingHandle
,
1483 unsigned long Flags
)
1485 UNREFERENCED_PARAMETER(BindingHandle
);
1486 UNREFERENCED_PARAMETER(Flags
);
1488 DPRINT("PNP_RunDetection() called\n");
1489 return CR_CALL_NOT_IMPLEMENTED
;
1493 typedef BOOL (WINAPI
*PDEV_INSTALL_W
)(HWND
, HINSTANCE
, LPCWSTR
, INT
);
1496 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
1498 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1499 HMODULE hNewDev
= NULL
;
1500 PDEV_INSTALL_W DevInstallW
;
1502 BOOL DeviceInstalled
= FALSE
;
1504 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
1506 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1508 PlugPlayData
.Operation
= 0; /* Get status */
1510 /* Get device status */
1511 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1512 (PVOID
)&PlugPlayData
,
1513 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1514 if (!NT_SUCCESS(Status
))
1516 DPRINT1("NtPlugPlayControl('%S') failed with status 0x%08lx\n", DeviceInstance
, Status
);
1520 if ((PlugPlayData
.DeviceStatus
& (DNF_STARTED
| DNF_START_FAILED
)) != 0)
1522 /* Device is already started, or disabled due to some problem. Don't install it */
1523 DPRINT("No need to install '%S'\n", DeviceInstance
);
1527 /* Install device */
1528 SetEnvironmentVariableW(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1530 hNewDev
= LoadLibraryW(L
"newdev.dll");
1533 DPRINT1("Unable to load newdev.dll\n");
1537 DevInstallW
= (PDEV_INSTALL_W
)GetProcAddress(hNewDev
, (LPCSTR
)"DevInstallW");
1540 DPRINT1("'DevInstallW' not found in newdev.dll\n");
1544 if (!DevInstallW(NULL
, NULL
, DeviceInstance
, ShowWizard
? SW_SHOWNOACTIVATE
: SW_HIDE
))
1546 DPRINT1("DevInstallW('%S') failed\n", DeviceInstance
);
1550 DeviceInstalled
= TRUE
;
1553 if (hNewDev
!= NULL
)
1554 FreeLibrary(hNewDev
);
1556 return DeviceInstalled
;
1572 return ERROR_INVALID_PARAMETER
;
1575 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
1576 if (rc
!= ERROR_SUCCESS
)
1578 if (dwType
!= REG_SZ
)
1579 return ERROR_FILE_NOT_FOUND
;
1580 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
1582 return ERROR_NOT_ENOUGH_MEMORY
;
1583 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
1584 if (rc
!= ERROR_SUCCESS
)
1586 HeapFree(GetProcessHeap(), 0, Value
);
1589 /* NULL-terminate the string */
1590 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
1593 return ERROR_SUCCESS
;
1601 DWORD regType
, active
, size
;
1605 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
1606 if (rc
!= ERROR_SUCCESS
)
1609 size
= sizeof(DWORD
);
1610 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
1611 if (rc
!= ERROR_SUCCESS
)
1613 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
1616 ret
= (active
!= 0);
1622 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
1631 HKEY ControlKey
= NULL
;
1632 LPWSTR SystemStartOptions
= NULL
;
1633 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
1634 BOOL ConsoleBoot
= FALSE
;
1639 L
"SYSTEM\\CurrentControlSet\\Control",
1644 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
1645 if (rc
!= ERROR_SUCCESS
)
1648 /* Check for CMDCONS in SystemStartOptions */
1649 CurrentOption
= SystemStartOptions
;
1650 while (CurrentOption
)
1652 NextOption
= wcschr(CurrentOption
, L
' ');
1654 *NextOption
= L
'\0';
1655 if (wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
1657 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
1661 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
1665 if (ControlKey
!= NULL
)
1666 RegCloseKey(ControlKey
);
1667 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
1672 /* Loop to install all queued devices installations */
1674 DeviceInstallThread(LPVOID lpParameter
)
1676 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1677 PSLIST_ENTRY ListEntry
;
1679 PLIST_ENTRY ListEntry
;
1681 DeviceInstallParams
* Params
;
1684 UNREFERENCED_PARAMETER(lpParameter
);
1686 WaitForSingleObject(hInstallEvent
, INFINITE
);
1688 showWizard
= !SetupIsActive() && !IsConsoleBoot();
1692 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1693 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
1695 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
1698 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
1700 if (ListEntry
== NULL
)
1702 SetEvent(hNoPendingInstalls
);
1703 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
1707 ResetEvent(hNoPendingInstalls
);
1708 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
1709 InstallDevice(Params
->DeviceIds
, showWizard
);
1718 PnpEventThread(LPVOID lpParameter
)
1720 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
1723 RPC_STATUS RpcStatus
;
1725 UNREFERENCED_PARAMETER(lpParameter
);
1727 PnpEventSize
= 0x1000;
1728 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
1729 if (PnpEvent
== NULL
)
1730 return ERROR_OUTOFMEMORY
;
1734 DPRINT("Calling NtGetPlugPlayEvent()\n");
1736 /* Wait for the next pnp event */
1737 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
1739 /* Resize the buffer for the PnP event if it's too small. */
1740 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1742 PnpEventSize
+= 0x400;
1743 PnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
1744 if (PnpEvent
== NULL
)
1745 return ERROR_OUTOFMEMORY
;
1749 if (!NT_SUCCESS(Status
))
1751 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
1755 /* Process the pnp event */
1756 DPRINT("Received PnP Event\n");
1757 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
1759 DeviceInstallParams
* Params
;
1762 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
1764 /* Queue device install (will be dequeued by DeviceInstallThread */
1765 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
)
1766 + wcslen(PnpEvent
->TargetDevice
.DeviceIds
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
1767 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
1770 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
1771 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1772 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
1774 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
1776 SetEvent(hDeviceInstallListNotEmpty
);
1781 DPRINT1("Unknown event\n");
1784 /* Dequeue the current pnp event and signal the next one */
1785 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
1788 HeapFree(GetProcessHeap(), 0, PnpEvent
);
1790 return ERROR_SUCCESS
;
1794 static VOID CALLBACK
1795 ServiceMain(DWORD argc
, LPTSTR
*argv
)
1800 UNREFERENCED_PARAMETER(argc
);
1801 UNREFERENCED_PARAMETER(argv
);
1803 DPRINT("ServiceMain() called\n");
1805 hNoPendingInstalls
= CreateEventW(NULL
,
1808 L
"Global\\PnP_No_Pending_Install_Events");
1810 hThread
= CreateThread(NULL
,
1816 if (hThread
!= NULL
)
1817 CloseHandle(hThread
);
1819 hThread
= CreateThread(NULL
,
1821 DeviceInstallThread
,
1825 if (hThread
!= NULL
)
1826 CloseHandle(hThread
);
1828 hThread
= CreateThread(NULL
,
1834 if (hThread
!= NULL
)
1835 CloseHandle(hThread
);
1837 DPRINT("ServiceMain() done\n");
1842 main(int argc
, char *argv
[])
1846 UNREFERENCED_PARAMETER(argc
);
1847 UNREFERENCED_PARAMETER(argv
);
1849 DPRINT("Umpnpmgr: main() started\n");
1851 hInstallEvent
= CreateEvent(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
1852 if (hInstallEvent
== NULL
)
1854 dwError
= GetLastError();
1855 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
1859 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1860 if (hDeviceInstallListNotEmpty
== NULL
)
1862 dwError
= GetLastError();
1863 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
1867 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1868 InitializeSListHead(&DeviceInstallListHead
);
1870 InitializeListHead(&DeviceInstallListHead
);
1873 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1874 L
"System\\CurrentControlSet\\Enum",
1878 if (dwError
!= ERROR_SUCCESS
)
1880 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
1884 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1885 L
"System\\CurrentControlSet\\Control\\Class",
1889 if (dwError
!= ERROR_SUCCESS
)
1891 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
1895 StartServiceCtrlDispatcher(ServiceTable
);
1897 DPRINT("Umpnpmgr: main() done\n");