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 <umpnpmgr/sysguid.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 static HANDLE hUserToken
= NULL
;
62 static HANDLE hInstallEvent
= NULL
;
65 /* FUNCTIONS *****************************************************************/
68 RpcServerThread(LPVOID lpParameter
)
72 DPRINT("RpcServerThread() called\n");
74 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
77 NULL
); // Security descriptor
78 if (Status
!= RPC_S_OK
)
80 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
84 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
87 if (Status
!= RPC_S_OK
)
89 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
93 Status
= RpcServerListen(1,
96 if (Status
!= RPC_S_OK
)
98 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
102 DPRINT("RpcServerThread() done\n");
108 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
110 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
114 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
116 HeapFree(GetProcessHeap(), 0, ptr
);
120 static CONFIGRET WINAPI
121 NtStatusToCrError(NTSTATUS Status
)
125 case STATUS_NO_SUCH_DEVICE
:
126 return CR_NO_SUCH_DEVINST
;
129 /* FIXME: add more mappings */
130 DPRINT1("Unable to map status 0x%08lx\n", Status
);
138 PNP_GetVersion(handle_t BindingHandle
,
139 unsigned short *Version
)
148 PNP_GetGlobalState(handle_t BindingHandle
,
149 unsigned long *State
,
152 *State
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
159 PNP_InitDetection(handle_t BindingHandle
)
161 DPRINT("PNP_InitDetection() called\n");
168 PNP_ReportLogOn(handle_t BindingHandle
,
170 unsigned long ProcessId
)
174 DPRINT1("PNP_ReportLogOn(%lu, %lu) called\n", Admin
, ProcessId
);
176 /* Get the users token */
177 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
,
180 if (hProcess
!= NULL
)
182 if (hUserToken
!= NULL
)
184 CloseHandle(hUserToken
);
188 OpenProcessToken(hProcess
,
191 CloseHandle(hProcess
);
194 /* Trigger the installer thread */
195 if (hInstallEvent
!= NULL
)
196 SetEvent(hInstallEvent
);
204 PNP_ValidateDeviceInstance(handle_t BindingHandle
,
205 wchar_t *DeviceInstance
,
208 CONFIGRET ret
= CR_SUCCESS
;
209 HKEY hEnumKey
= NULL
;
210 HKEY hDeviceKey
= NULL
;
212 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
213 DeviceInstance
, Flags
);
215 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
216 L
"System\\CurrentControlSet\\Enum",
221 DPRINT("Could not open the Enum Key!\n");
226 if (RegOpenKeyExW(hEnumKey
,
232 DPRINT("Could not open the Device Key!\n");
233 ret
= CR_NO_SUCH_DEVNODE
;
237 /* FIXME: add more tests */
240 if (hDeviceKey
!= NULL
)
241 RegCloseKey(hDeviceKey
);
243 if (hEnumKey
!= NULL
)
244 RegCloseKey(hEnumKey
);
246 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
254 PNP_GetRootDeviceInstance(handle_t BindingHandle
,
255 wchar_t *DeviceInstance
,
256 unsigned long Length
)
258 CONFIGRET ret
= CR_SUCCESS
;
260 DPRINT("PNP_GetRootDeviceInstance() called\n");
262 if (Length
< lstrlenW(szRootDeviceId
) + 1)
264 ret
= CR_BUFFER_SMALL
;
268 lstrcpyW(DeviceInstance
,
272 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
280 PNP_GetRelatedDeviceInstance(handle_t BindingHandle
,
281 unsigned long Relationship
,
283 wchar_t *RelatedDeviceId
,
284 unsigned long Length
,
287 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
288 CONFIGRET ret
= CR_SUCCESS
;
291 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
292 DPRINT(" Relationship %ld\n", Relationship
);
293 DPRINT(" DeviceId %S\n", DeviceId
);
295 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
298 PlugPlayData
.Relation
= Relationship
;
300 PlugPlayData
.RelatedDeviceInstance
.Length
= 0;
301 PlugPlayData
.RelatedDeviceInstance
.MaximumLength
= Length
;
302 PlugPlayData
.RelatedDeviceInstance
.Buffer
= RelatedDeviceId
;
304 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
305 (PVOID
)&PlugPlayData
,
306 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
307 if (!NT_SUCCESS(Status
))
309 ret
= NtStatusToCrError(Status
);
312 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
313 if (ret
== CR_SUCCESS
)
315 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
324 PNP_EnumerateSubKeys(handle_t BindingHandle
,
325 unsigned long Branch
,
328 unsigned long Length
,
329 unsigned long *RequiredLength
,
332 CONFIGRET ret
= CR_SUCCESS
;
336 DPRINT("PNP_EnumerateSubKeys() called\n");
340 case PNP_BRANCH_ENUM
:
344 case PNP_BRANCH_CLASS
:
352 *RequiredLength
= Length
;
353 dwError
= RegEnumKeyExW(hKey
,
361 if (dwError
!= ERROR_SUCCESS
)
363 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
370 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
378 PNP_GetDeviceListSize(handle_t BindingHandle
,
380 unsigned long *Length
,
383 DPRINT("PNP_GetDeviceListSize() called\n");
394 PNP_GetDepth(handle_t BindingHandle
,
395 wchar_t *DeviceInstance
,
396 unsigned long *Depth
,
399 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
400 CONFIGRET ret
= CR_SUCCESS
;
403 DPRINT("PNP_GetDepth() called\n");
405 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
408 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
409 (PVOID
)&PlugPlayData
,
410 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
411 if (NT_SUCCESS(Status
))
413 *Depth
= PlugPlayData
.Depth
;
417 ret
= NtStatusToCrError(Status
);
420 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
428 PNP_GetDeviceRegProp(handle_t BindingHandle
,
429 wchar_t *DeviceInstance
,
430 unsigned long Property
,
431 unsigned long *DataType
,
433 unsigned long *TransferLen
,
434 unsigned long *Length
,
437 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
438 CONFIGRET ret
= CR_SUCCESS
;
439 LPWSTR lpValueName
= NULL
;
443 DPRINT("PNP_GetDeviceRegProp() called\n");
447 case CM_DRP_DEVICEDESC
:
448 lpValueName
= L
"DeviceDesc";
451 case CM_DRP_HARDWAREID
:
452 lpValueName
= L
"HardwareID";
455 case CM_DRP_COMPATIBLEIDS
:
456 lpValueName
= L
"CompatibleIDs";
460 lpValueName
= L
"Service";
464 lpValueName
= L
"Class";
467 case CM_DRP_CLASSGUID
:
468 lpValueName
= L
"ClassGUID";
472 lpValueName
= L
"Driver";
475 case CM_DRP_CONFIGFLAGS
:
476 lpValueName
= L
"ConfigFlags";
480 lpValueName
= L
"Mfg";
483 case CM_DRP_FRIENDLYNAME
:
484 lpValueName
= L
"FriendlyName";
487 case CM_DRP_LOCATION_INFORMATION
:
488 lpValueName
= L
"LocationInformation";
491 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
495 case CM_DRP_CAPABILITIES
:
496 lpValueName
= L
"Capabilities";
499 case CM_DRP_UI_NUMBER
:
503 case CM_DRP_UPPERFILTERS
:
504 lpValueName
= L
"UpperFilters";
507 case CM_DRP_LOWERFILTERS
:
508 lpValueName
= L
"LowerFilters";
511 case CM_DRP_BUSTYPEGUID
:
515 case CM_DRP_LEGACYBUSTYPE
:
519 case CM_DRP_BUSNUMBER
:
523 case CM_DRP_ENUMERATOR_NAME
:
528 return CR_INVALID_PROPERTY
;
531 DPRINT("Value name: %S\n", lpValueName
);
535 /* Retrieve information from the Registry */
536 if (RegOpenKeyExW(hEnumKey
,
541 return CR_INVALID_DEVNODE
;
543 if (RegQueryValueExW(hKey
,
549 ret
= CR_REGISTRY_ERROR
;
551 /* FIXME: Check buffer size */
557 /* Retrieve information from the Device Node */
558 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
560 PlugPlayData
.Buffer
= Buffer
;
561 PlugPlayData
.BufferSize
= *TransferLen
;
566 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
567 PlugPlayData
.Property
= DevicePropertyPhysicalDeviceObjectName
;
570 case CM_DRP_UI_NUMBER
:
571 PlugPlayData
.Property
= DevicePropertyUINumber
;
574 case CM_DRP_BUSTYPEGUID
:
575 PlugPlayData
.Property
= DevicePropertyBusTypeGuid
;
578 case CM_DRP_LEGACYBUSTYPE
:
579 PlugPlayData
.Property
= DevicePropertyLegacyBusType
;
582 case CM_DRP_BUSNUMBER
:
583 PlugPlayData
.Property
= DevicePropertyBusNumber
;
586 case CM_DRP_ENUMERATOR_NAME
:
587 PlugPlayData
.Property
= DevicePropertyEnumeratorName
;
592 return CR_INVALID_PROPERTY
;
595 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
596 (PVOID
)&PlugPlayData
,
597 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
598 if (NT_SUCCESS(Status
))
600 *Length
= PlugPlayData
.BufferSize
;
604 ret
= NtStatusToCrError(Status
);
608 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
616 PNP_SetDeviceRegProp(handle_t BindingHandle
,
618 unsigned long Property
,
619 unsigned long DataType
,
621 unsigned long Length
,
624 CONFIGRET ret
= CR_SUCCESS
;
625 LPWSTR lpValueName
= NULL
;
628 DPRINT("PNP_SetDeviceRegProp() called\n");
630 DPRINT("DeviceId: %S\n", DeviceId
);
631 DPRINT("Property: %lu\n", Property
);
632 DPRINT("DataType: %lu\n", DataType
);
633 DPRINT("Length: %lu\n", Length
);
637 case CM_DRP_DEVICEDESC
:
638 lpValueName
= L
"DeviceDesc";
641 case CM_DRP_HARDWAREID
:
642 lpValueName
= L
"HardwareID";
645 case CM_DRP_COMPATIBLEIDS
:
646 lpValueName
= L
"CompatibleIDs";
650 lpValueName
= L
"Service";
654 lpValueName
= L
"Class";
657 case CM_DRP_CLASSGUID
:
658 lpValueName
= L
"ClassGUID";
662 lpValueName
= L
"Driver";
665 case CM_DRP_CONFIGFLAGS
:
666 lpValueName
= L
"ConfigFlags";
670 lpValueName
= L
"Mfg";
673 case CM_DRP_FRIENDLYNAME
:
674 lpValueName
= L
"FriendlyName";
677 case CM_DRP_LOCATION_INFORMATION
:
678 lpValueName
= L
"LocationInformation";
681 case CM_DRP_UPPERFILTERS
:
682 lpValueName
= L
"UpperFilters";
685 case CM_DRP_LOWERFILTERS
:
686 lpValueName
= L
"LowerFilters";
690 return CR_INVALID_PROPERTY
;
693 DPRINT("Value name: %S\n", lpValueName
);
695 if (RegOpenKeyExW(hEnumKey
,
700 return CR_INVALID_DEVNODE
;
704 if (RegDeleteValueW(hKey
,
706 ret
= CR_REGISTRY_ERROR
;
710 if (RegSetValueExW(hKey
,
716 ret
= CR_REGISTRY_ERROR
;
721 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
729 PNP_GetClassInstance(handle_t BindingHandle
,
730 wchar_t *DeviceId
, /* in */
731 wchar_t *Buffer
, /* out */
732 unsigned long Length
)
734 CONFIGRET ret
= CR_SUCCESS
;
736 DPRINT("PNP_Get_Class_Instance() called\n");
738 DPRINT("PNP_Get_Class_Instance() done (returns %lx)\n", ret
);
746 PNP_CreateKey(handle_t BindingHandle
,
748 unsigned long samDesired
,
751 CONFIGRET ret
= CR_SUCCESS
;
753 DPRINT("PNP_CreateKey() called\n");
755 DPRINT("PNP_CreateKey() done (returns %lx)\n", ret
);
763 PNP_DeleteRegistryKey(handle_t BindingHandle
,
769 CONFIGRET ret
= CR_SUCCESS
;
771 DPRINT("PNP_DeleteRegistryKey() called\n");
773 DPRINT("PNP_DeleteRegistryKey() done (returns %lx)\n", ret
);
782 PNP_GetClassCount(handle_t BindingHandle
,
783 unsigned long *ClassCount
,
789 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
794 if (dwError
!= ERROR_SUCCESS
)
795 return CR_INVALID_DATA
;
797 dwError
= RegQueryInfoKeyW(hKey
,
810 if (dwError
!= ERROR_SUCCESS
)
811 return CR_INVALID_DATA
;
820 PNP_GetClassName(handle_t BindingHandle
,
823 unsigned long *Length
,
826 WCHAR szKeyName
[MAX_PATH
];
827 CONFIGRET ret
= CR_SUCCESS
;
831 DPRINT("PNP_GetClassName() called\n");
833 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class");
834 lstrcatW(szKeyName
, L
"\\");
835 lstrcatW(szKeyName
, ClassGuid
);
837 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
842 return CR_REGISTRY_ERROR
;
844 ulSize
= *Length
* sizeof(WCHAR
);
845 if (RegQueryValueExW(hKey
,
853 ret
= CR_REGISTRY_ERROR
;
857 *Length
= ulSize
/ sizeof(WCHAR
);
862 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
870 PNP_DeleteClassKey(handle_t BindingHandle
,
874 CONFIGRET ret
= CR_SUCCESS
;
876 DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid
, Flags
);
878 if (Flags
& CM_DELETE_CLASS_SUBKEYS
)
880 if (RegDeleteTreeW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
881 ret
= CR_REGISTRY_ERROR
;
885 if (RegDeleteKeyW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
886 ret
= CR_REGISTRY_ERROR
;
889 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
897 PNP_DeviceInstanceAction(handle_t BindingHandle
,
898 unsigned long MajorAction
,
899 unsigned long MinorAction
,
900 wchar_t *DeviceInstance1
,
901 wchar_t *DeviceInstance2
)
903 CONFIGRET ret
= CR_SUCCESS
;
905 DPRINT("PNP_DeviceInstanceAction() called\n");
910 DPRINT("Move device instance\n");
912 ret
= CR_CALL_NOT_IMPLEMENTED
;
916 DPRINT("Setup device instance\n");
918 ret
= CR_CALL_NOT_IMPLEMENTED
;
922 DPRINT("Enable device instance\n");
924 ret
= CR_CALL_NOT_IMPLEMENTED
;
928 DPRINT("Disable device instance\n");
930 ret
= CR_CALL_NOT_IMPLEMENTED
;
934 DPRINT("Reenumerate device instance\n");
936 ret
= CR_CALL_NOT_IMPLEMENTED
;
940 DPRINT1("Unknown function %lu\n", MajorAction
);
941 ret
= CR_CALL_NOT_IMPLEMENTED
;
944 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
952 PNP_GetDeviceStatus(handle_t BindingHandle
,
953 wchar_t *DeviceInstance
,
954 unsigned long *pStatus
,
955 unsigned long *pProblem
,
958 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
959 CONFIGRET ret
= CR_SUCCESS
;
962 DPRINT("PNP_GetDeviceStatus() called\n");
964 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
966 PlugPlayData
.Operation
= 0; /* Get status */
968 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
969 (PVOID
)&PlugPlayData
,
970 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
971 if (NT_SUCCESS(Status
))
973 *pStatus
= PlugPlayData
.DeviceStatus
;
974 *pProblem
= PlugPlayData
.DeviceProblem
;
978 ret
= NtStatusToCrError(Status
);
981 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
989 PNP_SetDeviceProblem(handle_t BindingHandle
,
990 wchar_t *DeviceInstance
,
991 unsigned long Problem
,
994 CONFIGRET ret
= CR_SUCCESS
;
996 DPRINT1("PNP_SetDeviceProblem() called\n");
1000 DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret
);
1008 PNP_UninstallDevInst(handle_t BindingHandle
,
1009 wchar_t *DeviceInstance
,
1012 CONFIGRET ret
= CR_SUCCESS
;
1014 DPRINT1("PNP_UninstallDevInst() called\n");
1018 DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret
);
1026 PNP_IsDockStationPresent(handle_t BindingHandle
,
1027 unsigned long *Present
)
1033 CONFIGRET ret
= CR_SUCCESS
;
1035 DPRINT1("PNP_IsDockStationPresent() called\n");
1039 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
1043 &hKey
) != ERROR_SUCCESS
)
1044 return CR_REGISTRY_ERROR
;
1046 dwSize
= sizeof(DWORD
);
1047 if (RegQueryValueExW(hKey
,
1052 &dwSize
) != ERROR_SUCCESS
)
1053 ret
= CR_REGISTRY_ERROR
;
1057 if (ret
== CR_SUCCESS
)
1059 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
1061 ret
= CR_REGISTRY_ERROR
;
1063 else if (dwValue
!= 0)
1069 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
1077 PNP_RequestEjectPC(handle_t BindingHandle
)
1079 CONFIGRET ret
= CR_SUCCESS
;
1081 DPRINT1("PNP_RequestEjectPC() called\n");
1083 ret
= CR_FAILURE
; /* FIXME */
1085 DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret
);
1093 PNP_RunDetection(handle_t BindingHandle
,
1094 unsigned long Flags
)
1096 DPRINT("PNP_RunDetection() called\n");
1097 return CR_CALL_NOT_IMPLEMENTED
;
1101 typedef BOOL (WINAPI
*PDEV_INSTALL_W
)(HWND
, HINSTANCE
, LPCWSTR
, INT
);
1104 InstallDevice(PCWSTR DeviceInstance
, BOOL SetupIsActive
)
1106 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1107 HMODULE hNewDev
= NULL
;
1108 PDEV_INSTALL_W DevInstallW
;
1110 BOOL DeviceInstalled
= FALSE
;
1112 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1114 PlugPlayData
.Operation
= 0; /* Get status */
1116 /* Get device status */
1117 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1118 (PVOID
)&PlugPlayData
,
1119 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1120 if (!NT_SUCCESS(Status
))
1123 if (PlugPlayData
.DeviceStatus
& DNF_STARTED
|| PlugPlayData
.DeviceStatus
& DNF_START_FAILED
)
1124 /* Device is already started, or disabled due to some problem. Don't install it */
1127 /* Install device */
1128 SetEnvironmentVariable(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1130 hNewDev
= LoadLibraryW(L
"newdev.dll");
1134 DevInstallW
= (PDEV_INSTALL_W
)GetProcAddress(hNewDev
, (LPCSTR
)"DevInstallW");
1138 if (!DevInstallW(NULL
, NULL
, DeviceInstance
, SetupIsActive
? SW_HIDE
: SW_SHOWNOACTIVATE
))
1141 DeviceInstalled
= TRUE
;
1144 if (hNewDev
!= NULL
)
1145 FreeLibrary(hNewDev
);
1147 return DeviceInstalled
;
1154 HKEY hKey
= INVALID_HANDLE_VALUE
;
1155 DWORD regType
, active
, size
;
1159 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
1160 if (rc
!= ERROR_SUCCESS
)
1163 size
= sizeof(DWORD
);
1164 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
1165 if (rc
!= ERROR_SUCCESS
)
1167 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
1170 ret
= (active
!= 0);
1173 if (hKey
!= INVALID_HANDLE_VALUE
)
1176 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
1183 PnpEventThread(LPVOID lpParameter
)
1185 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
1188 RPC_STATUS RpcStatus
;
1191 PnpEventSize
= 0x1000;
1192 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
1193 if (PnpEvent
== NULL
)
1194 return ERROR_OUTOFMEMORY
;
1196 setupActive
= SetupIsActive();
1200 DPRINT("Calling NtGetPlugPlayEvent()\n");
1202 /* Wait for the next pnp event */
1203 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
1205 /* Resize the buffer for the PnP event if it's too small. */
1206 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1208 PnpEventSize
+= 0x400;
1209 PnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
1210 if (PnpEvent
== NULL
)
1211 return ERROR_OUTOFMEMORY
;
1215 if (!NT_SUCCESS(Status
))
1217 DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status
);
1221 DPRINT("Received PnP Event\n");
1222 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
1224 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
1225 InstallDevice(PnpEvent
->TargetDevice
.DeviceIds
, setupActive
);
1229 DPRINT1("Unknown event\n");
1232 /* FIXME: Process the pnp event */
1234 /* Dequeue the current pnp event and signal the next one */
1235 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
1238 HeapFree(GetProcessHeap(), 0, PnpEvent
);
1240 return ERROR_SUCCESS
;
1244 static VOID CALLBACK
1245 ServiceMain(DWORD argc
, LPTSTR
*argv
)
1250 DPRINT("ServiceMain() called\n");
1252 hThread
= CreateThread(NULL
,
1258 if (hThread
!= NULL
)
1259 CloseHandle(hThread
);
1261 hThread
= CreateThread(NULL
,
1267 if (hThread
!= NULL
)
1268 CloseHandle(hThread
);
1270 DPRINT("ServiceMain() done\n");
1275 main(int argc
, char *argv
[])
1279 DPRINT("Umpnpmgr: main() started\n");
1281 hInstallEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
1282 if (hInstallEvent
== NULL
)
1284 dwError
= GetLastError();
1285 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
1289 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1290 L
"System\\CurrentControlSet\\Enum",
1294 if (dwError
!= ERROR_SUCCESS
)
1296 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
1300 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1301 L
"System\\CurrentControlSet\\Control\\Class",
1305 if (dwError
!= ERROR_SUCCESS
)
1307 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
1311 StartServiceCtrlDispatcher(ServiceTable
);
1313 DPRINT("Umpnpmgr: main() done\n");