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 DPRINT("RpcServerThread() done\n");
129 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
131 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
135 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
137 HeapFree(GetProcessHeap(), 0, ptr
);
141 static CONFIGRET WINAPI
142 NtStatusToCrError(NTSTATUS Status
)
146 case STATUS_NO_SUCH_DEVICE
:
147 return CR_NO_SUCH_DEVINST
;
150 /* FIXME: add more mappings */
151 DPRINT1("Unable to map status 0x%08lx\n", Status
);
159 PNP_GetVersion(handle_t BindingHandle
,
160 unsigned short *Version
)
162 UNREFERENCED_PARAMETER(BindingHandle
);
171 PNP_GetGlobalState(handle_t BindingHandle
,
172 unsigned long *State
,
175 UNREFERENCED_PARAMETER(BindingHandle
);
176 UNREFERENCED_PARAMETER(Flags
);
178 *State
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
185 PNP_InitDetection(handle_t BindingHandle
)
187 UNREFERENCED_PARAMETER(BindingHandle
);
189 DPRINT("PNP_InitDetection() called\n");
196 PNP_ReportLogOn(handle_t BindingHandle
,
202 UNREFERENCED_PARAMETER(BindingHandle
);
204 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
206 /* Get the users token */
207 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
,
210 if (hProcess
!= NULL
)
212 if (hUserToken
!= NULL
)
214 CloseHandle(hUserToken
);
218 OpenProcessToken(hProcess
,
221 CloseHandle(hProcess
);
224 /* Trigger the installer thread */
225 if (hInstallEvent
!= NULL
)
226 SetEvent(hInstallEvent
);
234 PNP_ValidateDeviceInstance(handle_t BindingHandle
,
235 wchar_t *DeviceInstance
,
238 CONFIGRET ret
= CR_SUCCESS
;
239 HKEY hDeviceKey
= NULL
;
241 UNREFERENCED_PARAMETER(BindingHandle
);
243 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
244 DeviceInstance
, Flags
);
246 if (RegOpenKeyExW(hEnumKey
,
252 DPRINT("Could not open the Device Key!\n");
253 ret
= CR_NO_SUCH_DEVNODE
;
257 /* FIXME: add more tests */
260 if (hDeviceKey
!= NULL
)
261 RegCloseKey(hDeviceKey
);
263 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
271 PNP_GetRootDeviceInstance(handle_t BindingHandle
,
272 wchar_t *DeviceInstance
,
275 CONFIGRET ret
= CR_SUCCESS
;
277 UNREFERENCED_PARAMETER(BindingHandle
);
279 DPRINT("PNP_GetRootDeviceInstance() called\n");
281 if (Length
< lstrlenW(szRootDeviceId
) + 1)
283 ret
= CR_BUFFER_SMALL
;
287 lstrcpyW(DeviceInstance
,
291 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
299 PNP_GetRelatedDeviceInstance(handle_t BindingHandle
,
302 wchar_t *RelatedDeviceId
,
306 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
307 CONFIGRET ret
= CR_SUCCESS
;
310 UNREFERENCED_PARAMETER(BindingHandle
);
311 UNREFERENCED_PARAMETER(Flags
);
313 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
314 DPRINT(" Relationship %ld\n", Relationship
);
315 DPRINT(" DeviceId %S\n", DeviceId
);
317 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
320 PlugPlayData
.Relation
= Relationship
;
322 PlugPlayData
.RelatedDeviceInstanceLength
= Length
;
323 PlugPlayData
.RelatedDeviceInstance
= RelatedDeviceId
;
325 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
326 (PVOID
)&PlugPlayData
,
327 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
328 if (!NT_SUCCESS(Status
))
330 ret
= NtStatusToCrError(Status
);
333 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
334 if (ret
== CR_SUCCESS
)
336 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
345 PNP_EnumerateSubKeys(handle_t BindingHandle
,
350 DWORD
*RequiredLength
,
353 CONFIGRET ret
= CR_SUCCESS
;
357 UNREFERENCED_PARAMETER(BindingHandle
);
358 UNREFERENCED_PARAMETER(Flags
);
360 DPRINT("PNP_EnumerateSubKeys() called\n");
364 case PNP_BRANCH_ENUM
:
368 case PNP_BRANCH_CLASS
:
376 *RequiredLength
= Length
;
377 dwError
= RegEnumKeyExW(hKey
,
385 if (dwError
!= ERROR_SUCCESS
)
387 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
394 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
402 PNP_GetDeviceListSize(handle_t BindingHandle
,
404 unsigned long *Length
,
407 UNREFERENCED_PARAMETER(BindingHandle
);
408 UNREFERENCED_PARAMETER(Filter
);
409 UNREFERENCED_PARAMETER(Flags
);
411 DPRINT("PNP_GetDeviceListSize() called\n");
422 PNP_GetDepth(handle_t BindingHandle
,
423 wchar_t *DeviceInstance
,
424 unsigned long *Depth
,
427 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
428 CONFIGRET ret
= CR_SUCCESS
;
431 UNREFERENCED_PARAMETER(BindingHandle
);
432 UNREFERENCED_PARAMETER(Flags
);
434 DPRINT("PNP_GetDepth() called\n");
436 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
439 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
440 (PVOID
)&PlugPlayData
,
441 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
442 if (NT_SUCCESS(Status
))
444 *Depth
= PlugPlayData
.Depth
;
448 ret
= NtStatusToCrError(Status
);
451 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
459 PNP_GetDeviceRegProp(handle_t BindingHandle
,
460 wchar_t *DeviceInstance
,
468 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
469 CONFIGRET ret
= CR_SUCCESS
;
470 LPWSTR lpValueName
= NULL
;
474 UNREFERENCED_PARAMETER(BindingHandle
);
475 UNREFERENCED_PARAMETER(Flags
);
477 DPRINT("PNP_GetDeviceRegProp() called\n");
481 case CM_DRP_DEVICEDESC
:
482 lpValueName
= L
"DeviceDesc";
485 case CM_DRP_HARDWAREID
:
486 lpValueName
= L
"HardwareID";
489 case CM_DRP_COMPATIBLEIDS
:
490 lpValueName
= L
"CompatibleIDs";
494 lpValueName
= L
"Service";
498 lpValueName
= L
"Class";
501 case CM_DRP_CLASSGUID
:
502 lpValueName
= L
"ClassGUID";
506 lpValueName
= L
"Driver";
509 case CM_DRP_CONFIGFLAGS
:
510 lpValueName
= L
"ConfigFlags";
514 lpValueName
= L
"Mfg";
517 case CM_DRP_FRIENDLYNAME
:
518 lpValueName
= L
"FriendlyName";
521 case CM_DRP_LOCATION_INFORMATION
:
522 lpValueName
= L
"LocationInformation";
525 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
529 case CM_DRP_CAPABILITIES
:
530 lpValueName
= L
"Capabilities";
533 case CM_DRP_UI_NUMBER
:
537 case CM_DRP_UPPERFILTERS
:
538 lpValueName
= L
"UpperFilters";
541 case CM_DRP_LOWERFILTERS
:
542 lpValueName
= L
"LowerFilters";
545 case CM_DRP_BUSTYPEGUID
:
549 case CM_DRP_LEGACYBUSTYPE
:
553 case CM_DRP_BUSNUMBER
:
557 case CM_DRP_ENUMERATOR_NAME
:
562 return CR_INVALID_PROPERTY
;
565 DPRINT("Value name: %S\n", lpValueName
);
569 /* Retrieve information from the Registry */
570 if (RegOpenKeyExW(hEnumKey
,
575 return CR_INVALID_DEVNODE
;
577 if (RegQueryValueExW(hKey
,
583 ret
= CR_REGISTRY_ERROR
;
585 /* FIXME: Check buffer size */
591 /* Retrieve information from the Device Node */
592 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
594 PlugPlayData
.Buffer
= Buffer
;
595 PlugPlayData
.BufferSize
= *TransferLen
;
600 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
601 PlugPlayData
.Property
= DevicePropertyPhysicalDeviceObjectName
;
604 case CM_DRP_UI_NUMBER
:
605 PlugPlayData
.Property
= DevicePropertyUINumber
;
608 case CM_DRP_BUSTYPEGUID
:
609 PlugPlayData
.Property
= DevicePropertyBusTypeGuid
;
612 case CM_DRP_LEGACYBUSTYPE
:
613 PlugPlayData
.Property
= DevicePropertyLegacyBusType
;
616 case CM_DRP_BUSNUMBER
:
617 PlugPlayData
.Property
= DevicePropertyBusNumber
;
620 case CM_DRP_ENUMERATOR_NAME
:
621 PlugPlayData
.Property
= DevicePropertyEnumeratorName
;
626 return CR_INVALID_PROPERTY
;
629 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
630 (PVOID
)&PlugPlayData
,
631 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
632 if (NT_SUCCESS(Status
))
634 *Length
= PlugPlayData
.BufferSize
;
638 ret
= NtStatusToCrError(Status
);
642 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
650 PNP_SetDeviceRegProp(handle_t BindingHandle
,
652 unsigned long Property
,
653 unsigned long DataType
,
655 unsigned long Length
,
658 CONFIGRET ret
= CR_SUCCESS
;
659 LPWSTR lpValueName
= NULL
;
662 UNREFERENCED_PARAMETER(BindingHandle
);
663 UNREFERENCED_PARAMETER(Flags
);
665 DPRINT("PNP_SetDeviceRegProp() called\n");
667 DPRINT("DeviceId: %S\n", DeviceId
);
668 DPRINT("Property: %lu\n", Property
);
669 DPRINT("DataType: %lu\n", DataType
);
670 DPRINT("Length: %lu\n", Length
);
674 case CM_DRP_DEVICEDESC
:
675 lpValueName
= L
"DeviceDesc";
678 case CM_DRP_HARDWAREID
:
679 lpValueName
= L
"HardwareID";
682 case CM_DRP_COMPATIBLEIDS
:
683 lpValueName
= L
"CompatibleIDs";
687 lpValueName
= L
"Service";
691 lpValueName
= L
"Class";
694 case CM_DRP_CLASSGUID
:
695 lpValueName
= L
"ClassGUID";
699 lpValueName
= L
"Driver";
702 case CM_DRP_CONFIGFLAGS
:
703 lpValueName
= L
"ConfigFlags";
707 lpValueName
= L
"Mfg";
710 case CM_DRP_FRIENDLYNAME
:
711 lpValueName
= L
"FriendlyName";
714 case CM_DRP_LOCATION_INFORMATION
:
715 lpValueName
= L
"LocationInformation";
718 case CM_DRP_UPPERFILTERS
:
719 lpValueName
= L
"UpperFilters";
722 case CM_DRP_LOWERFILTERS
:
723 lpValueName
= L
"LowerFilters";
727 return CR_INVALID_PROPERTY
;
730 DPRINT("Value name: %S\n", lpValueName
);
732 if (RegOpenKeyExW(hEnumKey
,
737 return CR_INVALID_DEVNODE
;
741 if (RegDeleteValueW(hKey
,
743 ret
= CR_REGISTRY_ERROR
;
747 if (RegSetValueExW(hKey
,
753 ret
= CR_REGISTRY_ERROR
;
758 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
766 PNP_GetClassInstance(handle_t BindingHandle
,
767 wchar_t *DeviceId
, /* in */
768 wchar_t *Buffer
, /* out */
769 unsigned long Length
)
771 CONFIGRET ret
= CR_SUCCESS
;
773 UNREFERENCED_PARAMETER(BindingHandle
);
774 UNREFERENCED_PARAMETER(DeviceId
);
775 UNREFERENCED_PARAMETER(Buffer
);
776 UNREFERENCED_PARAMETER(Length
);
778 DPRINT("PNP_Get_Class_Instance() called\n");
780 DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret
);
788 PNP_CreateKey(handle_t BindingHandle
,
790 unsigned long samDesired
,
793 CONFIGRET ret
= CR_SUCCESS
;
795 UNREFERENCED_PARAMETER(BindingHandle
);
796 UNREFERENCED_PARAMETER(SubKey
);
797 UNREFERENCED_PARAMETER(samDesired
);
798 UNREFERENCED_PARAMETER(Flags
);
800 DPRINT("PNP_CreateKey() called\n");
802 DPRINT("PNP_CreateKey() done (returns %lx)\n", ret
);
810 PNP_DeleteRegistryKey(handle_t BindingHandle
,
816 CONFIGRET ret
= CR_SUCCESS
;
818 UNREFERENCED_PARAMETER(BindingHandle
);
819 UNREFERENCED_PARAMETER(DeviceId
);
820 UNREFERENCED_PARAMETER(ParentKey
);
821 UNREFERENCED_PARAMETER(ChildKey
);
822 UNREFERENCED_PARAMETER(Flags
);
824 DPRINT("PNP_DeleteRegistryKey() called\n");
826 DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret
);
835 PNP_GetClassCount(handle_t BindingHandle
,
836 unsigned long *ClassCount
,
842 UNREFERENCED_PARAMETER(BindingHandle
);
844 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
849 if (dwError
!= ERROR_SUCCESS
)
850 return CR_INVALID_DATA
;
852 dwError
= RegQueryInfoKeyW(hKey
,
865 if (dwError
!= ERROR_SUCCESS
)
866 return CR_INVALID_DATA
;
875 PNP_GetClassName(handle_t BindingHandle
,
878 unsigned long *Length
,
881 WCHAR szKeyName
[MAX_PATH
];
882 CONFIGRET ret
= CR_SUCCESS
;
886 UNREFERENCED_PARAMETER(BindingHandle
);
887 UNREFERENCED_PARAMETER(Flags
);
889 DPRINT("PNP_GetClassName() called\n");
891 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class");
892 lstrcatW(szKeyName
, L
"\\");
893 if(lstrlenW(ClassGuid
) < sizeof(szKeyName
)/sizeof(WCHAR
)-lstrlenW(szKeyName
))
894 lstrcatW(szKeyName
, ClassGuid
);
895 else return CR_INVALID_DATA
;
897 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
902 return CR_REGISTRY_ERROR
;
904 dwSize
= *Length
* sizeof(WCHAR
);
905 if (RegQueryValueExW(hKey
,
913 ret
= CR_REGISTRY_ERROR
;
917 *Length
= dwSize
/ sizeof(WCHAR
);
922 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
930 PNP_DeleteClassKey(handle_t BindingHandle
,
934 CONFIGRET ret
= CR_SUCCESS
;
936 UNREFERENCED_PARAMETER(BindingHandle
);
938 DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid
, Flags
);
940 if (Flags
& CM_DELETE_CLASS_SUBKEYS
)
942 if (RegDeleteTreeW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
943 ret
= CR_REGISTRY_ERROR
;
947 if (RegDeleteKeyW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
948 ret
= CR_REGISTRY_ERROR
;
951 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
959 PNP_CreateDevInst(handle_t BindingHandle
,
960 wchar_t *DeviceId
, /* [in, out, string, size_is(Length)] */
961 wchar_t *ParentDeviceId
, /* [in, string] */
962 unsigned long Length
, /* [in] */
963 unsigned long Flags
) /* [in] */
965 CONFIGRET ret
= CR_CALL_NOT_IMPLEMENTED
;
967 UNREFERENCED_PARAMETER(BindingHandle
);
968 UNREFERENCED_PARAMETER(DeviceId
);
969 UNREFERENCED_PARAMETER(ParentDeviceId
);
970 UNREFERENCED_PARAMETER(Length
);
971 UNREFERENCED_PARAMETER(Flags
);
973 DPRINT1("PNP_CreateDevInst() called\n");
975 DPRINT1("PNP_CreateDevInst() done (returns %lx)\n", ret
);
983 PNP_DeviceInstanceAction(handle_t BindingHandle
,
984 unsigned long MajorAction
,
985 unsigned long MinorAction
,
986 wchar_t *DeviceInstance1
,
987 wchar_t *DeviceInstance2
)
989 CONFIGRET ret
= CR_SUCCESS
;
991 UNREFERENCED_PARAMETER(BindingHandle
);
992 UNREFERENCED_PARAMETER(MinorAction
);
993 UNREFERENCED_PARAMETER(DeviceInstance1
);
994 UNREFERENCED_PARAMETER(DeviceInstance2
);
996 DPRINT("PNP_DeviceInstanceAction() called\n");
1001 DPRINT("Move device instance\n");
1003 ret
= CR_CALL_NOT_IMPLEMENTED
;
1007 DPRINT("Setup device instance\n");
1009 ret
= CR_CALL_NOT_IMPLEMENTED
;
1013 DPRINT("Enable device instance\n");
1015 ret
= CR_CALL_NOT_IMPLEMENTED
;
1019 DPRINT("Disable device instance\n");
1021 ret
= CR_CALL_NOT_IMPLEMENTED
;
1025 DPRINT("Reenumerate device instance\n");
1027 ret
= CR_CALL_NOT_IMPLEMENTED
;
1031 DPRINT1("Unknown function %lu\n", MajorAction
);
1032 ret
= CR_CALL_NOT_IMPLEMENTED
;
1035 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1043 PNP_GetDeviceStatus(handle_t BindingHandle
,
1044 wchar_t *DeviceInstance
,
1045 unsigned long *pStatus
,
1046 unsigned long *pProblem
,
1049 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1050 CONFIGRET ret
= CR_SUCCESS
;
1053 UNREFERENCED_PARAMETER(BindingHandle
);
1054 UNREFERENCED_PARAMETER(Flags
);
1056 DPRINT("PNP_GetDeviceStatus() called\n");
1058 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1060 PlugPlayData
.Operation
= 0; /* Get status */
1062 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1063 (PVOID
)&PlugPlayData
,
1064 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1065 if (NT_SUCCESS(Status
))
1067 *pStatus
= PlugPlayData
.DeviceStatus
;
1068 *pProblem
= PlugPlayData
.DeviceProblem
;
1072 ret
= NtStatusToCrError(Status
);
1075 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1083 PNP_SetDeviceProblem(handle_t BindingHandle
,
1084 wchar_t *DeviceInstance
,
1085 unsigned long Problem
,
1088 CONFIGRET ret
= CR_SUCCESS
;
1090 UNREFERENCED_PARAMETER(BindingHandle
);
1091 UNREFERENCED_PARAMETER(DeviceInstance
);
1092 UNREFERENCED_PARAMETER(Problem
);
1093 UNREFERENCED_PARAMETER(Flags
);
1095 DPRINT1("PNP_SetDeviceProblem() called\n");
1099 DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret
);
1107 PNP_UninstallDevInst(handle_t BindingHandle
,
1108 wchar_t *DeviceInstance
,
1111 CONFIGRET ret
= CR_SUCCESS
;
1113 UNREFERENCED_PARAMETER(BindingHandle
);
1114 UNREFERENCED_PARAMETER(DeviceInstance
);
1115 UNREFERENCED_PARAMETER(Flags
);
1117 DPRINT1("PNP_UninstallDevInst() called\n");
1121 DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret
);
1128 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1134 lpPtr
= lpDeviceIdList
;
1137 dwLength
= wcslen(lpPtr
);
1138 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1141 lpPtr
+= (dwLength
+ 1);
1149 AppendDeviceId(LPWSTR lpDeviceIdList
,
1150 LPDWORD lpDeviceIdListSize
,
1156 dwLen
= wcslen(lpDeviceId
);
1157 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1159 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1161 dwPos
+= (dwLen
+ 1);
1163 lpDeviceIdList
[dwPos
] = 0;
1165 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1171 PNP_AddID(handle_t BindingHandle
,
1172 wchar_t *DeviceInstance
,
1176 CONFIGRET ret
= CR_SUCCESS
;
1179 DWORD dwDeviceIdListSize
;
1180 WCHAR szDeviceIdList
[512];
1182 UNREFERENCED_PARAMETER(BindingHandle
);
1184 DPRINT("PNP_AddID() called\n");
1185 DPRINT(" DeviceInstance: %S\n", DeviceInstance
);
1186 DPRINT(" DeviceId: %S\n", DeviceId
);
1187 DPRINT(" Flags: %lx\n", Flags
);
1189 if (RegOpenKeyExW(hEnumKey
,
1192 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1193 &hDeviceKey
) != ERROR_SUCCESS
)
1195 DPRINT("Failed to open the device key!\n");
1196 return CR_INVALID_DEVNODE
;
1199 pszSubKey
= (Flags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1201 dwDeviceIdListSize
= 512 * sizeof(WCHAR
);
1202 if (RegQueryValueExW(hDeviceKey
,
1206 (LPBYTE
)szDeviceIdList
,
1207 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1209 DPRINT("Failed to query the desired ID string!\n");
1210 ret
= CR_REGISTRY_ERROR
;
1214 /* Check whether the device ID is already in use */
1215 if (CheckForDeviceId(szDeviceIdList
, DeviceId
))
1217 DPRINT("Device ID was found in the ID string!\n");
1222 /* Append the Device ID */
1223 AppendDeviceId(szDeviceIdList
, &dwDeviceIdListSize
, DeviceId
);
1225 if (RegSetValueExW(hDeviceKey
,
1229 (LPBYTE
)szDeviceIdList
,
1230 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1232 DPRINT("Failed to set the desired ID string!\n");
1233 ret
= CR_REGISTRY_ERROR
;
1237 RegCloseKey(hDeviceKey
);
1239 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1247 PNP_IsDockStationPresent(handle_t BindingHandle
,
1248 unsigned long *Present
)
1254 CONFIGRET ret
= CR_SUCCESS
;
1256 UNREFERENCED_PARAMETER(BindingHandle
);
1258 DPRINT1("PNP_IsDockStationPresent() called\n");
1262 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
1266 &hKey
) != ERROR_SUCCESS
)
1267 return CR_REGISTRY_ERROR
;
1269 dwSize
= sizeof(DWORD
);
1270 if (RegQueryValueExW(hKey
,
1275 &dwSize
) != ERROR_SUCCESS
)
1276 ret
= CR_REGISTRY_ERROR
;
1280 if (ret
== CR_SUCCESS
)
1282 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
1284 ret
= CR_REGISTRY_ERROR
;
1286 else if (dwValue
!= 0)
1292 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
1300 PNP_RequestEjectPC(handle_t BindingHandle
)
1302 CONFIGRET ret
= CR_SUCCESS
;
1304 UNREFERENCED_PARAMETER(BindingHandle
);
1306 DPRINT1("PNP_RequestEjectPC() called\n");
1308 ret
= CR_FAILURE
; /* FIXME */
1310 DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret
);
1318 PNP_HwProfFlags(handle_t BindingHandle
,
1322 DWORD
*Value
, // out
1325 CONFIGRET ret
= CR_SUCCESS
;
1327 UNREFERENCED_PARAMETER(BindingHandle
);
1328 UNREFERENCED_PARAMETER(Action
);
1329 UNREFERENCED_PARAMETER(DeviceId
);
1330 UNREFERENCED_PARAMETER(ProfileId
);
1331 UNREFERENCED_PARAMETER(Value
);
1332 UNREFERENCED_PARAMETER(Flags
);
1334 DPRINT1("PNP_HwProfFlags() called\n");
1336 ret
= CR_CALL_NOT_IMPLEMENTED
; /* FIXME */
1338 DPRINT1("PNP_HwProfFlags() done (returns %lx)\n", ret
);
1346 PNP_AddEmptyLogConf(handle_t BindingHandle
,
1347 wchar_t *DeviceInstance
,
1348 unsigned long ulPriority
,
1349 unsigned long *pulLogConfTag
,
1350 unsigned long ulFlags
)
1352 CONFIGRET ret
= CR_SUCCESS
;
1354 UNREFERENCED_PARAMETER(BindingHandle
);
1355 UNREFERENCED_PARAMETER(DeviceInstance
);
1356 UNREFERENCED_PARAMETER(ulPriority
);
1357 UNREFERENCED_PARAMETER(ulFlags
);
1359 DPRINT1("PNP_AddEmptyLogConf() called\n");
1361 *pulLogConfTag
= 0; /* FIXME */
1363 DPRINT1("PNP_AddEmptyLogConf() done (returns %lx)\n", ret
);
1371 PNP_FreeLogConf(handle_t BindingHandle
,
1372 wchar_t *DeviceInstance
,
1373 unsigned long ulType
,
1374 unsigned long ulLogConfTag
,
1375 unsigned long ulFlags
)
1377 CONFIGRET ret
= CR_SUCCESS
;
1379 UNREFERENCED_PARAMETER(BindingHandle
);
1380 UNREFERENCED_PARAMETER(DeviceInstance
);
1381 UNREFERENCED_PARAMETER(ulType
);
1382 UNREFERENCED_PARAMETER(ulLogConfTag
);
1383 UNREFERENCED_PARAMETER(ulFlags
);
1385 DPRINT1("PNP_FreeLogConf() called\n");
1388 DPRINT1("PNP_FreeLogConf() done (returns %lx)\n", ret
);
1396 PNP_GetFirstLogConf(handle_t BindingHandle
,
1397 wchar_t *DeviceInstance
,
1398 unsigned long ulPriority
,
1399 unsigned long *pulLogConfTag
,
1400 unsigned long ulFlags
)
1402 CONFIGRET ret
= CR_SUCCESS
;
1404 UNREFERENCED_PARAMETER(BindingHandle
);
1405 UNREFERENCED_PARAMETER(DeviceInstance
);
1406 UNREFERENCED_PARAMETER(ulPriority
);
1407 UNREFERENCED_PARAMETER(ulFlags
);
1409 DPRINT1("PNP_GetFirstLogConf() called\n");
1411 *pulLogConfTag
= 0; /* FIXME */
1413 DPRINT1("PNP_GetFirstLogConf() done (returns %lx)\n", ret
);
1421 PNP_GetNextLogConf(handle_t BindingHandle
,
1422 wchar_t *DeviceInstance
,
1423 unsigned long ulLogConfType
,
1424 unsigned long ulCurrentTag
,
1425 unsigned long *pulNextTag
,
1426 unsigned long ulFlags
)
1428 CONFIGRET ret
= CR_SUCCESS
;
1430 UNREFERENCED_PARAMETER(BindingHandle
);
1431 UNREFERENCED_PARAMETER(DeviceInstance
);
1432 UNREFERENCED_PARAMETER(ulLogConfType
);
1433 UNREFERENCED_PARAMETER(ulCurrentTag
);
1434 UNREFERENCED_PARAMETER(ulFlags
);
1436 DPRINT1("PNP_GetNextLogConf() called\n");
1438 *pulNextTag
= 0; /* FIXME */
1440 DPRINT1("PNP_GetNextLogConf() done (returns %lx)\n", ret
);
1448 PNP_GetLogConfPriority(handle_t BindingHandle
,
1449 wchar_t *DeviceInstance
,
1450 unsigned long ulLogConfType
,
1451 unsigned long ulCurrentTag
,
1452 unsigned long *pPriority
,
1453 unsigned long ulFlags
)
1455 CONFIGRET ret
= CR_SUCCESS
;
1457 UNREFERENCED_PARAMETER(BindingHandle
);
1458 UNREFERENCED_PARAMETER(DeviceInstance
);
1459 UNREFERENCED_PARAMETER(ulLogConfType
);
1460 UNREFERENCED_PARAMETER(ulCurrentTag
);
1461 UNREFERENCED_PARAMETER(ulFlags
);
1463 DPRINT1("PNP_GetLogConfPriority() called\n");
1465 *pPriority
= 0; /* FIXME */
1467 DPRINT1("PNP_GetLogConfPriority() done (returns %lx)\n", ret
);
1475 PNP_RunDetection(handle_t BindingHandle
,
1476 unsigned long Flags
)
1478 UNREFERENCED_PARAMETER(BindingHandle
);
1479 UNREFERENCED_PARAMETER(Flags
);
1481 DPRINT("PNP_RunDetection() called\n");
1482 return CR_CALL_NOT_IMPLEMENTED
;
1486 typedef BOOL (WINAPI
*PDEV_INSTALL_W
)(HWND
, HINSTANCE
, LPCWSTR
, INT
);
1489 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
1491 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1492 HMODULE hNewDev
= NULL
;
1493 PDEV_INSTALL_W DevInstallW
;
1495 BOOL DeviceInstalled
= FALSE
;
1497 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
1499 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1501 PlugPlayData
.Operation
= 0; /* Get status */
1503 /* Get device status */
1504 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1505 (PVOID
)&PlugPlayData
,
1506 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1507 if (!NT_SUCCESS(Status
))
1509 DPRINT1("NtPlugPlayControl('%S') failed with status 0x%08lx\n", DeviceInstance
, Status
);
1513 if ((PlugPlayData
.DeviceStatus
& (DNF_STARTED
| DNF_START_FAILED
)) != 0)
1515 /* Device is already started, or disabled due to some problem. Don't install it */
1516 DPRINT("No need to install '%S'\n", DeviceInstance
);
1520 /* Install device */
1521 SetEnvironmentVariableW(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1523 hNewDev
= LoadLibraryW(L
"newdev.dll");
1526 DPRINT1("Unable to load newdev.dll\n");
1530 DevInstallW
= (PDEV_INSTALL_W
)GetProcAddress(hNewDev
, (LPCSTR
)"DevInstallW");
1533 DPRINT1("'DevInstallW' not found in newdev.dll\n");
1537 if (!DevInstallW(NULL
, NULL
, DeviceInstance
, ShowWizard
? SW_SHOWNOACTIVATE
: SW_HIDE
))
1539 DPRINT1("DevInstallW('%S') failed\n", DeviceInstance
);
1543 DeviceInstalled
= TRUE
;
1546 if (hNewDev
!= NULL
)
1547 FreeLibrary(hNewDev
);
1549 return DeviceInstalled
;
1565 return ERROR_INVALID_PARAMETER
;
1568 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
1569 if (rc
!= ERROR_SUCCESS
)
1571 if (dwType
!= REG_SZ
)
1572 return ERROR_FILE_NOT_FOUND
;
1573 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
1575 return ERROR_NOT_ENOUGH_MEMORY
;
1576 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
1577 if (rc
!= ERROR_SUCCESS
)
1579 HeapFree(GetProcessHeap(), 0, Value
);
1582 /* NULL-terminate the string */
1583 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
1586 return ERROR_SUCCESS
;
1594 DWORD regType
, active
, size
;
1598 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
1599 if (rc
!= ERROR_SUCCESS
)
1602 size
= sizeof(DWORD
);
1603 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
1604 if (rc
!= ERROR_SUCCESS
)
1606 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
1609 ret
= (active
!= 0);
1615 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
1624 HKEY ControlKey
= NULL
;
1625 LPWSTR SystemStartOptions
= NULL
;
1626 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
1627 BOOL ConsoleBoot
= FALSE
;
1632 L
"SYSTEM\\CurrentControlSet\\Control",
1637 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
1638 if (rc
!= ERROR_SUCCESS
)
1641 /* Check for CMDCONS in SystemStartOptions */
1642 CurrentOption
= SystemStartOptions
;
1643 while (CurrentOption
)
1645 NextOption
= wcschr(CurrentOption
, L
' ');
1647 *NextOption
= L
'\0';
1648 if (wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
1650 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
1654 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
1658 if (ControlKey
!= NULL
)
1659 RegCloseKey(ControlKey
);
1660 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
1665 /* Loop to install all queued devices installations */
1667 DeviceInstallThread(LPVOID lpParameter
)
1669 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1670 PSLIST_ENTRY ListEntry
;
1672 PLIST_ENTRY ListEntry
;
1674 DeviceInstallParams
* Params
;
1677 UNREFERENCED_PARAMETER(lpParameter
);
1679 showWizard
= !SetupIsActive() && !IsConsoleBoot();
1683 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1684 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
1686 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
1689 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
1691 if (ListEntry
== NULL
)
1693 SetEvent(hNoPendingInstalls
);
1694 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
1698 ResetEvent(hNoPendingInstalls
);
1699 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
1700 InstallDevice(Params
->DeviceIds
, showWizard
);
1709 PnpEventThread(LPVOID lpParameter
)
1711 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
1714 RPC_STATUS RpcStatus
;
1716 UNREFERENCED_PARAMETER(lpParameter
);
1718 PnpEventSize
= 0x1000;
1719 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
1720 if (PnpEvent
== NULL
)
1721 return ERROR_OUTOFMEMORY
;
1725 DPRINT("Calling NtGetPlugPlayEvent()\n");
1727 /* Wait for the next pnp event */
1728 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
1730 /* Resize the buffer for the PnP event if it's too small. */
1731 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1733 PnpEventSize
+= 0x400;
1734 PnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
1735 if (PnpEvent
== NULL
)
1736 return ERROR_OUTOFMEMORY
;
1740 if (!NT_SUCCESS(Status
))
1742 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
1746 /* Process the pnp event */
1747 DPRINT("Received PnP Event\n");
1748 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
1750 DeviceInstallParams
* Params
;
1753 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
1755 /* Queue device install (will be dequeued by DeviceInstallThread */
1756 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
)
1757 + wcslen(PnpEvent
->TargetDevice
.DeviceIds
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
1758 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
1761 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
1762 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1763 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
1765 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
1767 SetEvent(hDeviceInstallListNotEmpty
);
1772 DPRINT1("Unknown event\n");
1775 /* Dequeue the current pnp event and signal the next one */
1776 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
1779 HeapFree(GetProcessHeap(), 0, PnpEvent
);
1781 return ERROR_SUCCESS
;
1785 static VOID CALLBACK
1786 ServiceMain(DWORD argc
, LPTSTR
*argv
)
1791 UNREFERENCED_PARAMETER(argc
);
1792 UNREFERENCED_PARAMETER(argv
);
1794 DPRINT("ServiceMain() called\n");
1796 hNoPendingInstalls
= CreateEventW(NULL
,
1799 L
"Global\\PnP_No_Pending_Install_Events");
1801 hThread
= CreateThread(NULL
,
1807 if (hThread
!= NULL
)
1808 CloseHandle(hThread
);
1810 hThread
= CreateThread(NULL
,
1812 DeviceInstallThread
,
1816 if (hThread
!= NULL
)
1817 CloseHandle(hThread
);
1819 hThread
= CreateThread(NULL
,
1825 if (hThread
!= NULL
)
1826 CloseHandle(hThread
);
1828 DPRINT("ServiceMain() done\n");
1833 main(int argc
, char *argv
[])
1837 UNREFERENCED_PARAMETER(argc
);
1838 UNREFERENCED_PARAMETER(argv
);
1840 DPRINT("Umpnpmgr: main() started\n");
1842 hInstallEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
1843 if (hInstallEvent
== NULL
)
1845 dwError
= GetLastError();
1846 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
1850 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1851 if (hDeviceInstallListNotEmpty
== NULL
)
1853 dwError
= GetLastError();
1854 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
1858 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1859 InitializeSListHead(&DeviceInstallListHead
);
1861 InitializeListHead(&DeviceInstallListHead
);
1864 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1865 L
"System\\CurrentControlSet\\Enum",
1869 if (dwError
!= ERROR_SUCCESS
)
1871 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
1875 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1876 L
"System\\CurrentControlSet\\Control\\Class",
1880 if (dwError
!= ERROR_SUCCESS
)
1882 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
1886 StartServiceCtrlDispatcher(ServiceTable
);
1888 DPRINT("Umpnpmgr: main() done\n");