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 WIN32_NO_STATUS
31 #define NTOS_MODE_USER
32 #include <ndk/ntndk.h>
33 #include <ndk/sysguid.h>
34 #include <ddk/wdmguid.h>
35 #include <ddk/cfgmgr32.h>
45 /* GLOBALS ******************************************************************/
48 ServiceMain(DWORD argc
, LPTSTR
*argv
);
50 static SERVICE_TABLE_ENTRY ServiceTable
[2] =
52 {TEXT("PlugPlay"), ServiceMain
},
56 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
58 static HKEY hEnumKey
= NULL
;
59 static HKEY hClassKey
= NULL
;
61 /* FUNCTIONS *****************************************************************/
64 RpcServerThread(LPVOID lpParameter
)
68 DPRINT("RpcServerThread() called\n");
70 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
73 NULL
); // Security descriptor
74 if (Status
!= RPC_S_OK
)
76 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
80 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
83 if (Status
!= RPC_S_OK
)
85 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
89 Status
= RpcServerListen(1,
92 if (Status
!= RPC_S_OK
)
94 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
98 DPRINT("RpcServerThread() done\n");
104 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
106 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
110 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
112 HeapFree(GetProcessHeap(), 0, ptr
);
116 static CONFIGRET WINAPI
117 NtStatusToCrError(NTSTATUS Status
)
121 case STATUS_NO_SUCH_DEVICE
:
122 return CR_NO_SUCH_DEVINST
;
124 /* FIXME: add more mappings */
125 DPRINT1("Unable to map status 0x%08lx\n", Status
);
132 PNP_GetVersion(handle_t BindingHandle
,
133 unsigned short *Version
)
141 PNP_GetGlobalState(handle_t BindingHandle
,
142 unsigned long *State
,
145 *State
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
151 PNP_ValidateDeviceInstance(handle_t BindingHandle
,
152 wchar_t *DeviceInstance
,
155 CONFIGRET ret
= CR_SUCCESS
;
156 HKEY hEnumKey
= NULL
;
157 HKEY hDeviceKey
= NULL
;
159 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
160 DeviceInstance
, Flags
);
162 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
163 L
"System\\CurrentControlSet\\Enum",
168 DPRINT("Could not open the Enum Key!\n");
173 if (RegOpenKeyExW(hEnumKey
,
179 DPRINT("Could not open the Device Key!\n");
180 ret
= CR_NO_SUCH_DEVNODE
;
184 /* FIXME: add more tests */
187 if (hDeviceKey
!= NULL
)
188 RegCloseKey(hDeviceKey
);
190 if (hEnumKey
!= NULL
)
191 RegCloseKey(hEnumKey
);
193 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
200 PNP_GetRootDeviceInstance(handle_t BindingHandle
,
201 wchar_t *DeviceInstance
,
202 unsigned long Length
)
204 CONFIGRET ret
= CR_SUCCESS
;
206 DPRINT("PNP_GetRootDeviceInstance() called\n");
208 if (Length
< lstrlenW(szRootDeviceId
) + 1)
210 ret
= CR_BUFFER_SMALL
;
214 lstrcpyW(DeviceInstance
,
218 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
225 PNP_GetRelatedDeviceInstance(handle_t BindingHandle
,
226 unsigned long Relationship
,
228 wchar_t *RelatedDeviceId
,
229 unsigned long Length
,
232 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
233 CONFIGRET ret
= CR_SUCCESS
;
236 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
237 DPRINT(" Relationship %ld\n", Relationship
);
238 DPRINT(" DeviceId %S\n", DeviceId
);
240 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
243 PlugPlayData
.Relation
= Relationship
;
245 PlugPlayData
.RelatedDeviceInstance
.Length
= 0;
246 PlugPlayData
.RelatedDeviceInstance
.MaximumLength
= Length
;
247 PlugPlayData
.RelatedDeviceInstance
.Buffer
= RelatedDeviceId
;
249 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
250 (PVOID
)&PlugPlayData
,
251 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
252 if (!NT_SUCCESS(Status
))
254 ret
= NtStatusToCrError(Status
);
257 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
258 if (ret
== CR_SUCCESS
)
260 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
268 PNP_EnumerateSubKeys(handle_t BindingHandle
,
269 unsigned long Branch
,
272 unsigned long Length
,
273 unsigned long *RequiredLength
,
276 CONFIGRET ret
= CR_SUCCESS
;
280 DPRINT("PNP_EnumerateSubKeys() called\n");
284 case PNP_BRANCH_ENUM
:
288 case PNP_BRANCH_CLASS
:
296 *RequiredLength
= Length
;
297 dwError
= RegEnumKeyExW(hKey
,
305 if (dwError
!= ERROR_SUCCESS
)
307 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
314 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
321 PNP_GetDeviceListSize(handle_t BindingHandle
,
323 unsigned long *Length
,
326 DPRINT("PNP_GetDeviceListSize() called\n");
336 PNP_GetDepth(handle_t BindingHandle
,
337 wchar_t *DeviceInstance
,
338 unsigned long *Depth
,
341 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
342 CONFIGRET ret
= CR_SUCCESS
;
345 DPRINT("PNP_GetDepth() called\n");
347 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
350 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
351 (PVOID
)&PlugPlayData
,
352 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
353 if (NT_SUCCESS(Status
))
355 *Depth
= PlugPlayData
.Depth
;
359 ret
= NtStatusToCrError(Status
);
362 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
369 PNP_SetDeviceRegProp(handle_t BindingHandle
,
371 unsigned long Property
,
372 unsigned long DataType
,
374 unsigned long Length
,
377 CONFIGRET ret
= CR_SUCCESS
;
378 LPWSTR lpValueName
= NULL
;
381 DPRINT("PNP_SetDeviceRegProp() called\n");
383 DPRINT("DeviceId: %S\n", DeviceId
);
384 DPRINT("Property: %lu\n", Property
);
385 DPRINT("DataType: %lu\n", DataType
);
386 DPRINT("Length: %lu\n", Length
);
390 case CM_DRP_DEVICEDESC
:
391 lpValueName
= L
"DeviceDesc";
394 case CM_DRP_HARDWAREID
:
395 lpValueName
= L
"HardwareID";
398 case CM_DRP_COMPATIBLEIDS
:
399 lpValueName
= L
"CompatibleIDs";
403 lpValueName
= L
"Service";
407 lpValueName
= L
"Class";
410 case CM_DRP_CLASSGUID
:
411 lpValueName
= L
"ClassGUID";
415 lpValueName
= L
"Driver";
418 case CM_DRP_CONFIGFLAGS
:
419 lpValueName
= L
"ConfigFlags";
423 lpValueName
= L
"Mfg";
426 case CM_DRP_FRIENDLYNAME
:
427 lpValueName
= L
"FriendlyName";
430 case CM_DRP_LOCATION_INFORMATION
:
431 lpValueName
= L
"LocationInformation";
434 case CM_DRP_UPPERFILTERS
:
435 lpValueName
= L
"UpperFilters";
438 case CM_DRP_LOWERFILTERS
:
439 lpValueName
= L
"LowerFilters";
443 return CR_INVALID_PROPERTY
;
446 DPRINT("Value name: %S\n", lpValueName
);
448 if (RegOpenKeyExW(hEnumKey
,
453 return CR_INVALID_DEVNODE
;
457 if (RegDeleteValueW(hKey
,
459 ret
= CR_REGISTRY_ERROR
;
463 if (RegSetValueExW(hKey
,
469 ret
= CR_REGISTRY_ERROR
;
474 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
481 PNP_GetDeviceRegProp(handle_t BindingHandle
,
482 wchar_t *DeviceInstance
,
483 unsigned long Property
,
484 unsigned long *DataType
,
486 unsigned long *TransferLen
,
487 unsigned long *Length
,
490 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
491 CONFIGRET ret
= CR_SUCCESS
;
492 LPWSTR lpValueName
= NULL
;
496 DPRINT("PNP_GetDeviceRegProp() called\n");
500 case CM_DRP_DEVICEDESC
:
501 lpValueName
= L
"DeviceDesc";
504 case CM_DRP_HARDWAREID
:
505 lpValueName
= L
"HardwareID";
508 case CM_DRP_COMPATIBLEIDS
:
509 lpValueName
= L
"CompatibleIDs";
513 lpValueName
= L
"Service";
517 lpValueName
= L
"Class";
520 case CM_DRP_CLASSGUID
:
521 lpValueName
= L
"ClassGUID";
525 lpValueName
= L
"Driver";
528 case CM_DRP_CONFIGFLAGS
:
529 lpValueName
= L
"ConfigFlags";
533 lpValueName
= L
"Mfg";
536 case CM_DRP_FRIENDLYNAME
:
537 lpValueName
= L
"FriendlyName";
540 case CM_DRP_LOCATION_INFORMATION
:
541 lpValueName
= L
"LocationInformation";
544 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
548 case CM_DRP_CAPABILITIES
:
549 lpValueName
= L
"Capabilities";
552 case CM_DRP_UI_NUMBER
:
556 case CM_DRP_UPPERFILTERS
:
557 lpValueName
= L
"UpperFilters";
560 case CM_DRP_LOWERFILTERS
:
561 lpValueName
= L
"LowerFilters";
564 case CM_DRP_BUSTYPEGUID
:
568 case CM_DRP_LEGACYBUSTYPE
:
572 case CM_DRP_BUSNUMBER
:
576 case CM_DRP_ENUMERATOR_NAME
:
581 return CR_INVALID_PROPERTY
;
584 DPRINT("Value name: %S\n", lpValueName
);
588 /* Retrieve information from the Registry */
589 if (RegOpenKeyExW(hEnumKey
,
594 return CR_INVALID_DEVNODE
;
596 if (RegQueryValueExW(hKey
,
602 ret
= CR_REGISTRY_ERROR
;
604 /* FIXME: Check buffer size */
610 /* Retrieve information from the Device Node */
611 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
613 PlugPlayData
.Buffer
= Buffer
;
614 PlugPlayData
.BufferSize
= *TransferLen
;
619 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
620 PlugPlayData
.Property
= DevicePropertyPhysicalDeviceObjectName
;
623 case CM_DRP_UI_NUMBER
:
624 PlugPlayData
.Property
= DevicePropertyUINumber
;
627 case CM_DRP_BUSTYPEGUID
:
628 PlugPlayData
.Property
= DevicePropertyBusTypeGuid
;
631 case CM_DRP_LEGACYBUSTYPE
:
632 PlugPlayData
.Property
= DevicePropertyLegacyBusType
;
635 case CM_DRP_BUSNUMBER
:
636 PlugPlayData
.Property
= DevicePropertyBusNumber
;
639 case CM_DRP_ENUMERATOR_NAME
:
640 PlugPlayData
.Property
= DevicePropertyEnumeratorName
;
645 return CR_INVALID_PROPERTY
;
648 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
649 (PVOID
)&PlugPlayData
,
650 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
651 if (NT_SUCCESS(Status
))
653 *Length
= PlugPlayData
.BufferSize
;
657 ret
= NtStatusToCrError(Status
);
661 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
668 PNP_CreateKey(handle_t BindingHandle
,
670 unsigned long samDesired
,
673 CONFIGRET ret
= CR_SUCCESS
;
675 DPRINT("PNP_CreateKey() called\n");
677 DPRINT("PNP_CreateKey() done (returns %lx)\n", ret
);
684 PNP_GetClassName(handle_t BindingHandle
,
687 unsigned long *Length
,
690 WCHAR szKeyName
[MAX_PATH
];
691 CONFIGRET ret
= CR_SUCCESS
;
695 DPRINT("PNP_GetClassName() called\n");
697 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class");
698 lstrcatW(szKeyName
, L
"\\");
699 lstrcatW(szKeyName
, ClassGuid
);
701 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
706 return CR_REGISTRY_ERROR
;
708 ulSize
= *Length
* sizeof(WCHAR
);
709 if (RegQueryValueExW(hKey
,
717 ret
= CR_REGISTRY_ERROR
;
721 *Length
= ulSize
/ sizeof(WCHAR
);
726 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
733 PNP_DeleteClassKey(handle_t BindingHandle
,
737 CONFIGRET ret
= CR_SUCCESS
;
739 DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid
, Flags
);
741 if (Flags
& CM_DELETE_CLASS_SUBKEYS
)
743 if (RegDeleteTreeW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
744 ret
= CR_REGISTRY_ERROR
;
748 if (RegDeleteKeyW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
749 ret
= CR_REGISTRY_ERROR
;
752 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
759 PNP_GetDeviceStatus(handle_t BindingHandle
,
760 wchar_t *DeviceInstance
,
761 unsigned long *pStatus
,
762 unsigned long *pProblem
,
765 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
766 CONFIGRET ret
= CR_SUCCESS
;
769 DPRINT("PNP_GetDeviceStatus() called\n");
771 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
773 PlugPlayData
.Operation
= 0; /* Get status */
775 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
776 (PVOID
)&PlugPlayData
,
777 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
778 if (NT_SUCCESS(Status
))
780 *pStatus
= PlugPlayData
.DeviceStatus
;
781 *pProblem
= PlugPlayData
.DeviceProblem
;
785 ret
= NtStatusToCrError(Status
);
788 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
795 PNP_SetDeviceProblem(handle_t BindingHandle
,
796 wchar_t *DeviceInstance
,
797 unsigned long Problem
,
800 CONFIGRET ret
= CR_SUCCESS
;
802 DPRINT1("PNP_SetDeviceProblem() called\n");
806 DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret
);
814 PNP_IsDockStationPresent(handle_t BindingHandle
,
815 unsigned long *Present
)
821 CONFIGRET ret
= CR_SUCCESS
;
823 DPRINT1("PNP_IsDockStationPresent() called\n");
827 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
831 &hKey
) != ERROR_SUCCESS
)
832 return CR_REGISTRY_ERROR
;
834 dwSize
= sizeof(DWORD
);
835 if (RegQueryValueExW(hKey
,
840 &dwSize
) != ERROR_SUCCESS
)
841 ret
= CR_REGISTRY_ERROR
;
845 if (ret
== CR_SUCCESS
)
847 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
849 ret
= CR_REGISTRY_ERROR
;
851 else if (dwValue
!= 0)
857 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
865 PNP_RequestEjectPC(handle_t BindingHandle
)
867 CONFIGRET ret
= CR_SUCCESS
;
869 DPRINT1("PNP_RequestEjectPC() called\n");
871 ret
= CR_FAILURE
; /* FIXME */
873 DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret
);
878 typedef BOOL (WINAPI
*PDEV_INSTALL_W
)(HWND
, HINSTANCE
, LPCWSTR
, INT
);
881 InstallDevice(PCWSTR DeviceInstance
, BOOL SetupIsActive
)
883 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
884 HMODULE hNewDev
= NULL
;
885 PDEV_INSTALL_W DevInstallW
;
887 BOOL DeviceInstalled
= FALSE
;
889 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
891 PlugPlayData
.Operation
= 0; /* Get status */
893 /* Get device status */
894 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
895 (PVOID
)&PlugPlayData
,
896 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
897 if (!NT_SUCCESS(Status
))
900 if (PlugPlayData
.DeviceStatus
& DNF_STARTED
|| PlugPlayData
.DeviceStatus
& DNF_START_FAILED
)
901 /* Device is already started, or disabled due to some problem. Don't install it */
905 SetEnvironmentVariable(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
906 hNewDev
= LoadLibraryW(L
"newdev.dll");
909 DevInstallW
= (PDEV_INSTALL_W
)GetProcAddress(hNewDev
, (LPCSTR
)"DevInstallW");
912 if (!DevInstallW(NULL
, NULL
, DeviceInstance
, SetupIsActive
? SW_HIDE
: SW_SHOWNOACTIVATE
))
915 DeviceInstalled
= TRUE
;
919 FreeLibrary(hNewDev
);
921 return DeviceInstalled
;
927 HKEY hKey
= INVALID_HANDLE_VALUE
;
928 DWORD regType
, active
, size
;
932 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
933 if (rc
!= ERROR_SUCCESS
)
936 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
937 if (rc
!= ERROR_SUCCESS
)
939 if (regType
!= REG_DWORD
)
945 if (hKey
!= INVALID_HANDLE_VALUE
)
947 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
952 PnpEventThread(LPVOID lpParameter
)
954 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
957 RPC_STATUS RpcStatus
;
960 PnpEventSize
= 0x1000;
961 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
962 if (PnpEvent
== NULL
)
963 return ERROR_OUTOFMEMORY
;
965 setupActive
= SetupIsActive();
969 DPRINT("Calling NtGetPlugPlayEvent()\n");
971 /* Wait for the next pnp event */
972 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
974 /* Resize the buffer for the PnP event if it's too small. */
975 if (Status
== STATUS_BUFFER_TOO_SMALL
)
977 PnpEventSize
+= 0x400;
978 PnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
979 if (PnpEvent
== NULL
)
980 return ERROR_OUTOFMEMORY
;
984 if (!NT_SUCCESS(Status
))
986 DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status
);
990 DPRINT("Received PnP Event\n");
991 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
993 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
994 InstallDevice(PnpEvent
->TargetDevice
.DeviceIds
, setupActive
);
998 DPRINT1("Unknown event\n");
1001 /* FIXME: Process the pnp event */
1003 /* Dequeue the current pnp event and signal the next one */
1004 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
1007 HeapFree(GetProcessHeap(), 0, PnpEvent
);
1009 return ERROR_SUCCESS
;
1013 static VOID CALLBACK
1014 ServiceMain(DWORD argc
, LPTSTR
*argv
)
1019 DPRINT("ServiceMain() called\n");
1021 hThread
= CreateThread(NULL
,
1027 if (hThread
!= NULL
)
1028 CloseHandle(hThread
);
1030 hThread
= CreateThread(NULL
,
1036 if (hThread
!= NULL
)
1037 CloseHandle(hThread
);
1039 DPRINT("ServiceMain() done\n");
1044 main(int argc
, char *argv
[])
1048 DPRINT("Umpnpmgr: main() started\n");
1050 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1051 L
"System\\CurrentControlSet\\Enum",
1055 if (dwError
!= ERROR_SUCCESS
)
1057 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
1061 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1062 L
"System\\CurrentControlSet\\Control\\Class",
1066 if (dwError
!= ERROR_SUCCESS
)
1068 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
1072 StartServiceCtrlDispatcher(ServiceTable
);
1074 DPRINT("Umpnpmgr: main() done\n");