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
,
198 unsigned long ProcessId
)
202 UNREFERENCED_PARAMETER(BindingHandle
);
204 DPRINT1("PNP_ReportLogOn(%lu, %lu) 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
,
273 unsigned long Length
)
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
,
300 unsigned long Relationship
,
302 wchar_t *RelatedDeviceId
,
303 unsigned long Length
,
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
,
346 unsigned long Branch
,
349 unsigned long Length
,
350 unsigned long *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
,
461 unsigned long Property
,
462 unsigned long *DataType
,
464 unsigned long *TransferLen
,
465 unsigned long *Length
,
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 ulSize
= *Length
* sizeof(WCHAR
);
905 if (RegQueryValueExW(hKey
,
913 ret
= CR_REGISTRY_ERROR
;
917 *Length
= ulSize
/ 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
,
1319 unsigned long Action
,
1321 unsigned long ProfileId
,
1322 unsigned long *Value
, // out
1323 unsigned long Flags
)
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
,
1349 ULONG
*pulLogConfTag
,
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
,
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
,
1399 ULONG
*pulLogConfTag
,
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 ULONG ulLogConfType
,
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 ULONG ulLogConfType
,
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 SetupIsActive
)
1491 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1492 HMODULE hNewDev
= NULL
;
1493 PDEV_INSTALL_W DevInstallW
;
1495 BOOL DeviceInstalled
= FALSE
;
1497 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1499 PlugPlayData
.Operation
= 0; /* Get status */
1501 /* Get device status */
1502 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1503 (PVOID
)&PlugPlayData
,
1504 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1505 if (!NT_SUCCESS(Status
))
1508 if ((PlugPlayData
.DeviceStatus
& (DNF_STARTED
| DNF_START_FAILED
)) != 0)
1509 /* Device is already started, or disabled due to some problem. Don't install it */
1512 /* Install device */
1513 SetEnvironmentVariableW(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1515 hNewDev
= LoadLibraryW(L
"newdev.dll");
1519 DevInstallW
= (PDEV_INSTALL_W
)GetProcAddress(hNewDev
, (LPCSTR
)"DevInstallW");
1523 if (!DevInstallW(NULL
, NULL
, DeviceInstance
, SetupIsActive
? SW_HIDE
: SW_SHOWNOACTIVATE
))
1526 DeviceInstalled
= TRUE
;
1529 if (hNewDev
!= NULL
)
1530 FreeLibrary(hNewDev
);
1532 return DeviceInstalled
;
1540 DWORD regType
, active
, size
;
1544 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
1545 if (rc
!= ERROR_SUCCESS
)
1548 size
= sizeof(DWORD
);
1549 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
1550 if (rc
!= ERROR_SUCCESS
)
1552 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
1555 ret
= (active
!= 0);
1561 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
1567 /* Loop to install all queued devices installations */
1569 DeviceInstallThread(LPVOID lpParameter
)
1571 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1572 PSLIST_ENTRY ListEntry
;
1574 PLIST_ENTRY ListEntry
;
1576 DeviceInstallParams
* Params
;
1579 UNREFERENCED_PARAMETER(lpParameter
);
1581 setupActive
= SetupIsActive();
1583 SetEnvironmentVariable(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1587 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1588 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
1590 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
1593 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
1595 if (ListEntry
== NULL
)
1597 SetEvent(hNoPendingInstalls
);
1598 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
1602 ResetEvent(hNoPendingInstalls
);
1603 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
1604 InstallDevice(Params
->DeviceIds
, setupActive
);
1613 PnpEventThread(LPVOID lpParameter
)
1615 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
1618 RPC_STATUS RpcStatus
;
1620 UNREFERENCED_PARAMETER(lpParameter
);
1622 PnpEventSize
= 0x1000;
1623 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
1624 if (PnpEvent
== NULL
)
1625 return ERROR_OUTOFMEMORY
;
1629 DPRINT("Calling NtGetPlugPlayEvent()\n");
1631 /* Wait for the next pnp event */
1632 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
1634 /* Resize the buffer for the PnP event if it's too small. */
1635 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1637 PnpEventSize
+= 0x400;
1638 PnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
1639 if (PnpEvent
== NULL
)
1640 return ERROR_OUTOFMEMORY
;
1644 if (!NT_SUCCESS(Status
))
1646 DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status
);
1650 /* Process the pnp event */
1651 DPRINT("Received PnP Event\n");
1652 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
1654 DeviceInstallParams
* Params
;
1657 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
1659 /* Queue device install (will be dequeued by DeviceInstallThread */
1660 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
)
1661 + wcslen(PnpEvent
->TargetDevice
.DeviceIds
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
1662 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
1665 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
1666 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1667 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
1669 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
1671 SetEvent(hDeviceInstallListNotEmpty
);
1676 DPRINT1("Unknown event\n");
1679 /* Dequeue the current pnp event and signal the next one */
1680 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
1683 HeapFree(GetProcessHeap(), 0, PnpEvent
);
1685 return ERROR_SUCCESS
;
1689 static VOID CALLBACK
1690 ServiceMain(DWORD argc
, LPTSTR
*argv
)
1695 UNREFERENCED_PARAMETER(argc
);
1696 UNREFERENCED_PARAMETER(argv
);
1698 DPRINT("ServiceMain() called\n");
1700 hNoPendingInstalls
= CreateEventW(NULL
,
1703 L
"Global\\PnP_No_Pending_Install_Events");
1705 hThread
= CreateThread(NULL
,
1711 if (hThread
!= NULL
)
1712 CloseHandle(hThread
);
1714 hThread
= CreateThread(NULL
,
1716 DeviceInstallThread
,
1720 if (hThread
!= NULL
)
1721 CloseHandle(hThread
);
1723 hThread
= CreateThread(NULL
,
1729 if (hThread
!= NULL
)
1730 CloseHandle(hThread
);
1732 DPRINT("ServiceMain() done\n");
1737 main(int argc
, char *argv
[])
1741 UNREFERENCED_PARAMETER(argc
);
1742 UNREFERENCED_PARAMETER(argv
);
1744 DPRINT("Umpnpmgr: main() started\n");
1746 hInstallEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
1747 if (hInstallEvent
== NULL
)
1749 dwError
= GetLastError();
1750 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
1754 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1755 if (hDeviceInstallListNotEmpty
== NULL
)
1757 dwError
= GetLastError();
1758 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
1762 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1763 InitializeSListHead(&DeviceInstallListHead
);
1765 InitializeListHead(&DeviceInstallListHead
);
1768 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1769 L
"System\\CurrentControlSet\\Enum",
1773 if (dwError
!= ERROR_SUCCESS
)
1775 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
1779 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1780 L
"System\\CurrentControlSet\\Control\\Class",
1784 if (dwError
!= ERROR_SUCCESS
)
1786 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
1790 StartServiceCtrlDispatcher(ServiceTable
);
1792 DPRINT("Umpnpmgr: main() done\n");