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 DPRINT("RpcServerThread() called\n");
93 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
96 NULL
); // Security descriptor
97 if (Status
!= RPC_S_OK
)
99 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
103 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
106 if (Status
!= RPC_S_OK
)
108 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
112 Status
= RpcServerListen(1,
115 if (Status
!= RPC_S_OK
)
117 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
121 DPRINT("RpcServerThread() done\n");
127 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
129 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
133 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
135 HeapFree(GetProcessHeap(), 0, ptr
);
139 static CONFIGRET WINAPI
140 NtStatusToCrError(NTSTATUS Status
)
144 case STATUS_NO_SUCH_DEVICE
:
145 return CR_NO_SUCH_DEVINST
;
148 /* FIXME: add more mappings */
149 DPRINT1("Unable to map status 0x%08lx\n", Status
);
157 PNP_GetVersion(handle_t BindingHandle
,
158 unsigned short *Version
)
167 PNP_GetGlobalState(handle_t BindingHandle
,
168 unsigned long *State
,
171 *State
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
178 PNP_InitDetection(handle_t BindingHandle
)
180 DPRINT("PNP_InitDetection() called\n");
187 PNP_ReportLogOn(handle_t BindingHandle
,
189 unsigned long ProcessId
)
193 DPRINT1("PNP_ReportLogOn(%lu, %lu) called\n", Admin
, ProcessId
);
195 /* Get the users token */
196 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
,
199 if (hProcess
!= NULL
)
201 if (hUserToken
!= NULL
)
203 CloseHandle(hUserToken
);
207 OpenProcessToken(hProcess
,
210 CloseHandle(hProcess
);
213 /* Trigger the installer thread */
214 if (hInstallEvent
!= NULL
)
215 SetEvent(hInstallEvent
);
223 PNP_ValidateDeviceInstance(handle_t BindingHandle
,
224 wchar_t *DeviceInstance
,
227 CONFIGRET ret
= CR_SUCCESS
;
228 HKEY hEnumKey
= NULL
;
229 HKEY hDeviceKey
= NULL
;
231 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
232 DeviceInstance
, Flags
);
234 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
235 L
"System\\CurrentControlSet\\Enum",
240 DPRINT("Could not open the Enum Key!\n");
245 if (RegOpenKeyExW(hEnumKey
,
251 DPRINT("Could not open the Device Key!\n");
252 ret
= CR_NO_SUCH_DEVNODE
;
256 /* FIXME: add more tests */
259 if (hDeviceKey
!= NULL
)
260 RegCloseKey(hDeviceKey
);
262 if (hEnumKey
!= NULL
)
263 RegCloseKey(hEnumKey
);
265 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
273 PNP_GetRootDeviceInstance(handle_t BindingHandle
,
274 wchar_t *DeviceInstance
,
275 unsigned long Length
)
277 CONFIGRET ret
= CR_SUCCESS
;
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 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
311 DPRINT(" Relationship %ld\n", Relationship
);
312 DPRINT(" DeviceId %S\n", DeviceId
);
314 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
317 PlugPlayData
.Relation
= Relationship
;
319 PlugPlayData
.RelatedDeviceInstanceLength
= Length
;
320 PlugPlayData
.RelatedDeviceInstance
= RelatedDeviceId
;
322 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
323 (PVOID
)&PlugPlayData
,
324 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
325 if (!NT_SUCCESS(Status
))
327 ret
= NtStatusToCrError(Status
);
330 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
331 if (ret
== CR_SUCCESS
)
333 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
342 PNP_EnumerateSubKeys(handle_t BindingHandle
,
343 unsigned long Branch
,
346 unsigned long Length
,
347 unsigned long *RequiredLength
,
350 CONFIGRET ret
= CR_SUCCESS
;
354 DPRINT("PNP_EnumerateSubKeys() called\n");
358 case PNP_BRANCH_ENUM
:
362 case PNP_BRANCH_CLASS
:
370 *RequiredLength
= Length
;
371 dwError
= RegEnumKeyExW(hKey
,
379 if (dwError
!= ERROR_SUCCESS
)
381 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
388 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
396 PNP_GetDeviceListSize(handle_t BindingHandle
,
398 unsigned long *Length
,
401 DPRINT("PNP_GetDeviceListSize() called\n");
412 PNP_GetDepth(handle_t BindingHandle
,
413 wchar_t *DeviceInstance
,
414 unsigned long *Depth
,
417 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
418 CONFIGRET ret
= CR_SUCCESS
;
421 DPRINT("PNP_GetDepth() called\n");
423 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
426 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
427 (PVOID
)&PlugPlayData
,
428 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
429 if (NT_SUCCESS(Status
))
431 *Depth
= PlugPlayData
.Depth
;
435 ret
= NtStatusToCrError(Status
);
438 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
446 PNP_GetDeviceRegProp(handle_t BindingHandle
,
447 wchar_t *DeviceInstance
,
448 unsigned long Property
,
449 unsigned long *DataType
,
451 unsigned long *TransferLen
,
452 unsigned long *Length
,
455 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
456 CONFIGRET ret
= CR_SUCCESS
;
457 LPWSTR lpValueName
= NULL
;
461 DPRINT("PNP_GetDeviceRegProp() called\n");
465 case CM_DRP_DEVICEDESC
:
466 lpValueName
= L
"DeviceDesc";
469 case CM_DRP_HARDWAREID
:
470 lpValueName
= L
"HardwareID";
473 case CM_DRP_COMPATIBLEIDS
:
474 lpValueName
= L
"CompatibleIDs";
478 lpValueName
= L
"Service";
482 lpValueName
= L
"Class";
485 case CM_DRP_CLASSGUID
:
486 lpValueName
= L
"ClassGUID";
490 lpValueName
= L
"Driver";
493 case CM_DRP_CONFIGFLAGS
:
494 lpValueName
= L
"ConfigFlags";
498 lpValueName
= L
"Mfg";
501 case CM_DRP_FRIENDLYNAME
:
502 lpValueName
= L
"FriendlyName";
505 case CM_DRP_LOCATION_INFORMATION
:
506 lpValueName
= L
"LocationInformation";
509 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
513 case CM_DRP_CAPABILITIES
:
514 lpValueName
= L
"Capabilities";
517 case CM_DRP_UI_NUMBER
:
521 case CM_DRP_UPPERFILTERS
:
522 lpValueName
= L
"UpperFilters";
525 case CM_DRP_LOWERFILTERS
:
526 lpValueName
= L
"LowerFilters";
529 case CM_DRP_BUSTYPEGUID
:
533 case CM_DRP_LEGACYBUSTYPE
:
537 case CM_DRP_BUSNUMBER
:
541 case CM_DRP_ENUMERATOR_NAME
:
546 return CR_INVALID_PROPERTY
;
549 DPRINT("Value name: %S\n", lpValueName
);
553 /* Retrieve information from the Registry */
554 if (RegOpenKeyExW(hEnumKey
,
559 return CR_INVALID_DEVNODE
;
561 if (RegQueryValueExW(hKey
,
567 ret
= CR_REGISTRY_ERROR
;
569 /* FIXME: Check buffer size */
575 /* Retrieve information from the Device Node */
576 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
578 PlugPlayData
.Buffer
= Buffer
;
579 PlugPlayData
.BufferSize
= *TransferLen
;
584 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
585 PlugPlayData
.Property
= DevicePropertyPhysicalDeviceObjectName
;
588 case CM_DRP_UI_NUMBER
:
589 PlugPlayData
.Property
= DevicePropertyUINumber
;
592 case CM_DRP_BUSTYPEGUID
:
593 PlugPlayData
.Property
= DevicePropertyBusTypeGuid
;
596 case CM_DRP_LEGACYBUSTYPE
:
597 PlugPlayData
.Property
= DevicePropertyLegacyBusType
;
600 case CM_DRP_BUSNUMBER
:
601 PlugPlayData
.Property
= DevicePropertyBusNumber
;
604 case CM_DRP_ENUMERATOR_NAME
:
605 PlugPlayData
.Property
= DevicePropertyEnumeratorName
;
610 return CR_INVALID_PROPERTY
;
613 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
614 (PVOID
)&PlugPlayData
,
615 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
616 if (NT_SUCCESS(Status
))
618 *Length
= PlugPlayData
.BufferSize
;
622 ret
= NtStatusToCrError(Status
);
626 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
634 PNP_SetDeviceRegProp(handle_t BindingHandle
,
636 unsigned long Property
,
637 unsigned long DataType
,
639 unsigned long Length
,
642 CONFIGRET ret
= CR_SUCCESS
;
643 LPWSTR lpValueName
= NULL
;
646 DPRINT("PNP_SetDeviceRegProp() called\n");
648 DPRINT("DeviceId: %S\n", DeviceId
);
649 DPRINT("Property: %lu\n", Property
);
650 DPRINT("DataType: %lu\n", DataType
);
651 DPRINT("Length: %lu\n", Length
);
655 case CM_DRP_DEVICEDESC
:
656 lpValueName
= L
"DeviceDesc";
659 case CM_DRP_HARDWAREID
:
660 lpValueName
= L
"HardwareID";
663 case CM_DRP_COMPATIBLEIDS
:
664 lpValueName
= L
"CompatibleIDs";
668 lpValueName
= L
"Service";
672 lpValueName
= L
"Class";
675 case CM_DRP_CLASSGUID
:
676 lpValueName
= L
"ClassGUID";
680 lpValueName
= L
"Driver";
683 case CM_DRP_CONFIGFLAGS
:
684 lpValueName
= L
"ConfigFlags";
688 lpValueName
= L
"Mfg";
691 case CM_DRP_FRIENDLYNAME
:
692 lpValueName
= L
"FriendlyName";
695 case CM_DRP_LOCATION_INFORMATION
:
696 lpValueName
= L
"LocationInformation";
699 case CM_DRP_UPPERFILTERS
:
700 lpValueName
= L
"UpperFilters";
703 case CM_DRP_LOWERFILTERS
:
704 lpValueName
= L
"LowerFilters";
708 return CR_INVALID_PROPERTY
;
711 DPRINT("Value name: %S\n", lpValueName
);
713 if (RegOpenKeyExW(hEnumKey
,
718 return CR_INVALID_DEVNODE
;
722 if (RegDeleteValueW(hKey
,
724 ret
= CR_REGISTRY_ERROR
;
728 if (RegSetValueExW(hKey
,
734 ret
= CR_REGISTRY_ERROR
;
739 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
747 PNP_GetClassInstance(handle_t BindingHandle
,
748 wchar_t *DeviceId
, /* in */
749 wchar_t *Buffer
, /* out */
750 unsigned long Length
)
752 CONFIGRET ret
= CR_SUCCESS
;
754 DPRINT("PNP_Get_Class_Instance() called\n");
756 DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret
);
764 PNP_CreateKey(handle_t BindingHandle
,
766 unsigned long samDesired
,
769 CONFIGRET ret
= CR_SUCCESS
;
771 DPRINT("PNP_CreateKey() called\n");
773 DPRINT("PNP_CreateKey() done (returns %lx)\n", ret
);
781 PNP_DeleteRegistryKey(handle_t BindingHandle
,
787 CONFIGRET ret
= CR_SUCCESS
;
789 DPRINT("PNP_DeleteRegistryKey() called\n");
791 DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret
);
800 PNP_GetClassCount(handle_t BindingHandle
,
801 unsigned long *ClassCount
,
807 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
812 if (dwError
!= ERROR_SUCCESS
)
813 return CR_INVALID_DATA
;
815 dwError
= RegQueryInfoKeyW(hKey
,
828 if (dwError
!= ERROR_SUCCESS
)
829 return CR_INVALID_DATA
;
838 PNP_GetClassName(handle_t BindingHandle
,
841 unsigned long *Length
,
844 WCHAR szKeyName
[MAX_PATH
];
845 CONFIGRET ret
= CR_SUCCESS
;
849 DPRINT("PNP_GetClassName() called\n");
851 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class");
852 lstrcatW(szKeyName
, L
"\\");
853 if(lstrlenW(ClassGuid
) < sizeof(szKeyName
)/sizeof(WCHAR
)-lstrlenW(szKeyName
))
854 lstrcatW(szKeyName
, ClassGuid
);
855 else return CR_INVALID_DATA
;
857 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
862 return CR_REGISTRY_ERROR
;
864 ulSize
= *Length
* sizeof(WCHAR
);
865 if (RegQueryValueExW(hKey
,
873 ret
= CR_REGISTRY_ERROR
;
877 *Length
= ulSize
/ sizeof(WCHAR
);
882 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
890 PNP_DeleteClassKey(handle_t BindingHandle
,
894 CONFIGRET ret
= CR_SUCCESS
;
896 DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid
, Flags
);
898 if (Flags
& CM_DELETE_CLASS_SUBKEYS
)
900 if (RegDeleteTreeW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
901 ret
= CR_REGISTRY_ERROR
;
905 if (RegDeleteKeyW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
906 ret
= CR_REGISTRY_ERROR
;
909 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
917 PNP_CreateDevInst(handle_t BindingHandle
,
918 wchar_t *DeviceId
, /* [in, out, string, size_is(Length)] */
919 wchar_t *ParentDeviceId
, /* [in, string] */
920 unsigned long Length
, /* [in] */
921 unsigned long Flags
) /* [in] */
923 CONFIGRET ret
= CR_CALL_NOT_IMPLEMENTED
;
925 DPRINT1("PNP_CreateDevInst() called\n");
927 DPRINT1("PNP_CreateDevInst() done (returns %lx)\n", ret
);
935 PNP_DeviceInstanceAction(handle_t BindingHandle
,
936 unsigned long MajorAction
,
937 unsigned long MinorAction
,
938 wchar_t *DeviceInstance1
,
939 wchar_t *DeviceInstance2
)
941 CONFIGRET ret
= CR_SUCCESS
;
943 DPRINT("PNP_DeviceInstanceAction() called\n");
948 DPRINT("Move device instance\n");
950 ret
= CR_CALL_NOT_IMPLEMENTED
;
954 DPRINT("Setup device instance\n");
956 ret
= CR_CALL_NOT_IMPLEMENTED
;
960 DPRINT("Enable device instance\n");
962 ret
= CR_CALL_NOT_IMPLEMENTED
;
966 DPRINT("Disable device instance\n");
968 ret
= CR_CALL_NOT_IMPLEMENTED
;
972 DPRINT("Reenumerate device instance\n");
974 ret
= CR_CALL_NOT_IMPLEMENTED
;
978 DPRINT1("Unknown function %lu\n", MajorAction
);
979 ret
= CR_CALL_NOT_IMPLEMENTED
;
982 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
990 PNP_GetDeviceStatus(handle_t BindingHandle
,
991 wchar_t *DeviceInstance
,
992 unsigned long *pStatus
,
993 unsigned long *pProblem
,
996 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
997 CONFIGRET ret
= CR_SUCCESS
;
1000 DPRINT("PNP_GetDeviceStatus() called\n");
1002 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1004 PlugPlayData
.Operation
= 0; /* Get status */
1006 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1007 (PVOID
)&PlugPlayData
,
1008 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1009 if (NT_SUCCESS(Status
))
1011 *pStatus
= PlugPlayData
.DeviceStatus
;
1012 *pProblem
= PlugPlayData
.DeviceProblem
;
1016 ret
= NtStatusToCrError(Status
);
1019 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1027 PNP_SetDeviceProblem(handle_t BindingHandle
,
1028 wchar_t *DeviceInstance
,
1029 unsigned long Problem
,
1032 CONFIGRET ret
= CR_SUCCESS
;
1034 DPRINT1("PNP_SetDeviceProblem() called\n");
1038 DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret
);
1046 PNP_UninstallDevInst(handle_t BindingHandle
,
1047 wchar_t *DeviceInstance
,
1050 CONFIGRET ret
= CR_SUCCESS
;
1052 DPRINT1("PNP_UninstallDevInst() called\n");
1056 DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret
);
1063 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1069 lpPtr
= lpDeviceIdList
;
1072 dwLength
= wcslen(lpPtr
);
1073 if (!_wcsicmp(lpPtr
, lpDeviceId
))
1076 lpPtr
+= (dwLength
+ 1);
1084 AppendDeviceId(LPWSTR lpDeviceIdList
,
1085 LPDWORD lpDeviceIdListSize
,
1091 dwLen
= wcslen(lpDeviceId
);
1092 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1094 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1096 dwPos
+= (dwLen
+ 1);
1098 lpDeviceIdList
[dwPos
] = 0;
1100 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1106 PNP_AddID(handle_t BindingHandle
,
1107 wchar_t *DeviceInstance
,
1111 CONFIGRET ret
= CR_SUCCESS
;
1114 DWORD dwDeviceIdListSize
;
1115 WCHAR szDeviceIdList
[512];
1117 DPRINT("PNP_AddID() called\n");
1118 DPRINT(" DeviceInstance: %S\n", DeviceInstance
);
1119 DPRINT(" DeviceId: %S\n", DeviceId
);
1120 DPRINT(" Flags: %lx\n", Flags
);
1122 if (RegOpenKeyExW(hEnumKey
,
1125 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1126 &hDeviceKey
) != ERROR_SUCCESS
)
1128 DPRINT("Failed to open the device key!\n");
1129 return CR_INVALID_DEVNODE
;
1132 pszSubKey
= (Flags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1134 dwDeviceIdListSize
= 512 * sizeof(WCHAR
);
1135 if (RegQueryValueExW(hDeviceKey
,
1139 (LPBYTE
)szDeviceIdList
,
1140 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1142 DPRINT("Failed to query the desired ID string!\n");
1143 ret
= CR_REGISTRY_ERROR
;
1147 /* Check whether the device ID is already in use */
1148 if (CheckForDeviceId(szDeviceIdList
, DeviceId
))
1150 DPRINT("Device ID was found in the ID string!\n");
1155 /* Append the Device ID */
1156 AppendDeviceId(szDeviceIdList
, &dwDeviceIdListSize
, DeviceId
);
1158 if (RegSetValueExW(hDeviceKey
,
1162 (LPBYTE
)szDeviceIdList
,
1163 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1165 DPRINT("Failed to set the desired ID string!\n");
1166 ret
= CR_REGISTRY_ERROR
;
1170 RegCloseKey(hDeviceKey
);
1172 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1180 PNP_IsDockStationPresent(handle_t BindingHandle
,
1181 unsigned long *Present
)
1187 CONFIGRET ret
= CR_SUCCESS
;
1189 DPRINT1("PNP_IsDockStationPresent() called\n");
1193 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
1197 &hKey
) != ERROR_SUCCESS
)
1198 return CR_REGISTRY_ERROR
;
1200 dwSize
= sizeof(DWORD
);
1201 if (RegQueryValueExW(hKey
,
1206 &dwSize
) != ERROR_SUCCESS
)
1207 ret
= CR_REGISTRY_ERROR
;
1211 if (ret
== CR_SUCCESS
)
1213 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
1215 ret
= CR_REGISTRY_ERROR
;
1217 else if (dwValue
!= 0)
1223 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
1231 PNP_RequestEjectPC(handle_t BindingHandle
)
1233 CONFIGRET ret
= CR_SUCCESS
;
1235 DPRINT1("PNP_RequestEjectPC() called\n");
1237 ret
= CR_FAILURE
; /* FIXME */
1239 DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret
);
1247 PNP_HwProfFlags(handle_t BindingHandle
,
1248 unsigned long Action
,
1250 unsigned long ProfileId
,
1251 unsigned long *Value
, // out
1252 unsigned long Flags
)
1254 CONFIGRET ret
= CR_SUCCESS
;
1256 DPRINT1("PNP_HwProfFlags() called\n");
1258 ret
= CR_CALL_NOT_IMPLEMENTED
; /* FIXME */
1260 DPRINT1("PNP_HwProfFlags() done (returns %lx)\n", ret
);
1268 PNP_AddEmptyLogConf(handle_t BindingHandle
,
1269 wchar_t *DeviceInstance
,
1271 ULONG
*pulLogConfTag
,
1274 CONFIGRET ret
= CR_SUCCESS
;
1276 DPRINT1("PNP_AddEmptyLogConf() called\n");
1278 *pulLogConfTag
= 0; /* FIXME */
1280 DPRINT1("PNP_AddEmptyLogConf() done (returns %lx)\n", ret
);
1288 PNP_FreeLogConf(handle_t BindingHandle
,
1289 wchar_t *DeviceInstance
,
1294 CONFIGRET ret
= CR_SUCCESS
;
1296 DPRINT1("PNP_FreeLogConf() called\n");
1299 DPRINT1("PNP_FreeLogConf() done (returns %lx)\n", ret
);
1307 PNP_GetFirstLogConf(handle_t BindingHandle
,
1308 wchar_t *DeviceInstance
,
1310 ULONG
*pulLogConfTag
,
1313 CONFIGRET ret
= CR_SUCCESS
;
1315 DPRINT1("PNP_GetFirstLogConf() called\n");
1317 *pulLogConfTag
= 0; /* FIXME */
1319 DPRINT1("PNP_GetFirstLogConf() done (returns %lx)\n", ret
);
1327 PNP_GetNextLogConf(handle_t BindingHandle
,
1328 wchar_t *DeviceInstance
,
1329 ULONG ulLogConfType
,
1334 CONFIGRET ret
= CR_SUCCESS
;
1336 DPRINT1("PNP_GetNextLogConf() called\n");
1338 *pulNextTag
= 0; /* FIXME */
1340 DPRINT1("PNP_GetNextLogConf() done (returns %lx)\n", ret
);
1348 PNP_GetLogConfPriority(handle_t BindingHandle
,
1349 wchar_t *DeviceInstance
,
1350 ULONG ulLogConfType
,
1355 CONFIGRET ret
= CR_SUCCESS
;
1357 DPRINT1("PNP_GetLogConfPriority() called\n");
1359 *pPriority
= 0; /* FIXME */
1361 DPRINT1("PNP_GetLogConfPriority() done (returns %lx)\n", ret
);
1369 PNP_RunDetection(handle_t BindingHandle
,
1370 unsigned long Flags
)
1372 DPRINT("PNP_RunDetection() called\n");
1373 return CR_CALL_NOT_IMPLEMENTED
;
1377 typedef BOOL (WINAPI
*PDEV_INSTALL_W
)(HWND
, HINSTANCE
, LPCWSTR
, INT
);
1380 InstallDevice(PCWSTR DeviceInstance
, BOOL SetupIsActive
)
1382 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1383 HMODULE hNewDev
= NULL
;
1384 PDEV_INSTALL_W DevInstallW
;
1386 BOOL DeviceInstalled
= FALSE
;
1388 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1390 PlugPlayData
.Operation
= 0; /* Get status */
1392 /* Get device status */
1393 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1394 (PVOID
)&PlugPlayData
,
1395 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1396 if (!NT_SUCCESS(Status
))
1399 if (PlugPlayData
.DeviceStatus
& DNF_STARTED
|| PlugPlayData
.DeviceStatus
& DNF_START_FAILED
)
1400 /* Device is already started, or disabled due to some problem. Don't install it */
1403 /* Install device */
1404 SetEnvironmentVariable(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1406 hNewDev
= LoadLibraryW(L
"newdev.dll");
1410 DevInstallW
= (PDEV_INSTALL_W
)GetProcAddress(hNewDev
, (LPCSTR
)"DevInstallW");
1414 if (!DevInstallW(NULL
, NULL
, DeviceInstance
, SetupIsActive
? SW_HIDE
: SW_SHOWNOACTIVATE
))
1417 DeviceInstalled
= TRUE
;
1420 if (hNewDev
!= NULL
)
1421 FreeLibrary(hNewDev
);
1423 return DeviceInstalled
;
1431 DWORD regType
, active
, size
;
1435 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
1436 if (rc
!= ERROR_SUCCESS
)
1439 size
= sizeof(DWORD
);
1440 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
1441 if (rc
!= ERROR_SUCCESS
)
1443 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
1446 ret
= (active
!= 0);
1452 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
1458 /* Loop to install all queued devices installations */
1460 DeviceInstallThread(LPVOID lpParameter
)
1462 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1463 PSLIST_ENTRY ListEntry
;
1465 PLIST_ENTRY ListEntry
;
1467 DeviceInstallParams
* Params
;
1470 setupActive
= SetupIsActive();
1472 SetEnvironmentVariable(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1476 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1477 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
1479 if (IsListEmpty(&DeviceInstallListHead
))
1482 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
1484 if (ListEntry
== NULL
)
1486 SetEvent(hNoPendingInstalls
);
1487 DPRINT1("*** EVENT SETTED\n");
1488 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
1492 ResetEvent(hNoPendingInstalls
);
1493 DPRINT1("*** EVENT RESETTED\n");
1494 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
1495 InstallDevice(Params
->DeviceIds
, setupActive
);
1504 PnpEventThread(LPVOID lpParameter
)
1506 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
1509 RPC_STATUS RpcStatus
;
1511 PnpEventSize
= 0x1000;
1512 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
1513 if (PnpEvent
== NULL
)
1514 return ERROR_OUTOFMEMORY
;
1518 DPRINT("Calling NtGetPlugPlayEvent()\n");
1520 /* Wait for the next pnp event */
1521 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
1523 /* Resize the buffer for the PnP event if it's too small. */
1524 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1526 PnpEventSize
+= 0x400;
1527 PnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
1528 if (PnpEvent
== NULL
)
1529 return ERROR_OUTOFMEMORY
;
1533 if (!NT_SUCCESS(Status
))
1535 DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status
);
1539 /* Process the pnp event */
1540 DPRINT("Received PnP Event\n");
1541 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
1543 DeviceInstallParams
* Params
;
1546 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
1548 /* Queue device install (will be dequeued by DeviceInstallThread */
1549 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
)
1550 + wcslen(PnpEvent
->TargetDevice
.DeviceIds
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
);
1551 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
1554 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
1555 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1556 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
1558 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
1560 SetEvent(hDeviceInstallListNotEmpty
);
1565 DPRINT1("Unknown event\n");
1568 /* Dequeue the current pnp event and signal the next one */
1569 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
1572 HeapFree(GetProcessHeap(), 0, PnpEvent
);
1574 return ERROR_SUCCESS
;
1578 static VOID CALLBACK
1579 ServiceMain(DWORD argc
, LPTSTR
*argv
)
1584 DPRINT("ServiceMain() called\n");
1586 hNoPendingInstalls
= CreateEventW(NULL
,
1589 L
"Global\\PnP_No_Pending_Install_Events");
1591 hThread
= CreateThread(NULL
,
1597 if (hThread
!= NULL
)
1598 CloseHandle(hThread
);
1600 hThread
= CreateThread(NULL
,
1602 DeviceInstallThread
,
1606 if (hThread
!= NULL
)
1607 CloseHandle(hThread
);
1609 hThread
= CreateThread(NULL
,
1615 if (hThread
!= NULL
)
1616 CloseHandle(hThread
);
1618 DPRINT("ServiceMain() done\n");
1623 main(int argc
, char *argv
[])
1627 DPRINT("Umpnpmgr: main() started\n");
1629 hInstallEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
1630 if (hInstallEvent
== NULL
)
1632 dwError
= GetLastError();
1633 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
1637 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
1638 if (hDeviceInstallListNotEmpty
== NULL
)
1640 dwError
= GetLastError();
1641 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
1645 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
1646 InitializeSListHead(&DeviceInstallListHead
);
1648 InitializeListHead(&DeviceInstallListHead
);
1651 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1652 L
"System\\CurrentControlSet\\Enum",
1656 if (dwError
!= ERROR_SUCCESS
)
1658 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
1662 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1663 L
"System\\CurrentControlSet\\Control\\Class",
1667 if (dwError
!= ERROR_SUCCESS
)
1669 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
1673 StartServiceCtrlDispatcher(ServiceTable
);
1675 DPRINT("Umpnpmgr: main() done\n");