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
34 #include <umpnpmgr/sysguid.h>
46 /* GLOBALS ******************************************************************/
49 ServiceMain(DWORD argc
, LPTSTR
*argv
);
51 static SERVICE_TABLE_ENTRY ServiceTable
[2] =
53 {TEXT("PlugPlay"), ServiceMain
},
57 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
59 static HKEY hEnumKey
= NULL
;
60 static HKEY hClassKey
= NULL
;
62 static HANDLE hUserToken
= NULL
;
63 static HANDLE hInstallEvent
= NULL
;
66 /* FUNCTIONS *****************************************************************/
69 RpcServerThread(LPVOID lpParameter
)
73 DPRINT("RpcServerThread() called\n");
75 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
78 NULL
); // Security descriptor
79 if (Status
!= RPC_S_OK
)
81 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
85 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
88 if (Status
!= RPC_S_OK
)
90 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
94 Status
= RpcServerListen(1,
97 if (Status
!= RPC_S_OK
)
99 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
103 DPRINT("RpcServerThread() done\n");
109 void __RPC_FAR
* __RPC_USER
midl_user_allocate(size_t len
)
111 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
115 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
117 HeapFree(GetProcessHeap(), 0, ptr
);
121 static CONFIGRET WINAPI
122 NtStatusToCrError(NTSTATUS Status
)
126 case STATUS_NO_SUCH_DEVICE
:
127 return CR_NO_SUCH_DEVINST
;
130 /* FIXME: add more mappings */
131 DPRINT1("Unable to map status 0x%08lx\n", Status
);
139 PNP_GetVersion(handle_t BindingHandle
,
140 unsigned short *Version
)
149 PNP_GetGlobalState(handle_t BindingHandle
,
150 unsigned long *State
,
153 *State
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
160 PNP_InitDetection(handle_t BindingHandle
)
162 DPRINT("PNP_InitDetection() called\n");
169 PNP_ReportLogOn(handle_t BindingHandle
,
171 unsigned long ProcessId
)
175 DPRINT1("PNP_ReportLogOn(%lu, %lu) called\n", Admin
, ProcessId
);
177 /* Get the users token */
178 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
,
181 if (hProcess
!= NULL
)
183 if (hUserToken
!= NULL
)
185 CloseHandle(hUserToken
);
189 OpenProcessToken(hProcess
,
192 CloseHandle(hProcess
);
195 /* Trigger the installer thread */
196 if (hInstallEvent
!= NULL
)
197 SetEvent(hInstallEvent
);
205 PNP_ValidateDeviceInstance(handle_t BindingHandle
,
206 wchar_t *DeviceInstance
,
209 CONFIGRET ret
= CR_SUCCESS
;
210 HKEY hEnumKey
= NULL
;
211 HKEY hDeviceKey
= NULL
;
213 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
214 DeviceInstance
, Flags
);
216 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
217 L
"System\\CurrentControlSet\\Enum",
222 DPRINT("Could not open the Enum Key!\n");
227 if (RegOpenKeyExW(hEnumKey
,
233 DPRINT("Could not open the Device Key!\n");
234 ret
= CR_NO_SUCH_DEVNODE
;
238 /* FIXME: add more tests */
241 if (hDeviceKey
!= NULL
)
242 RegCloseKey(hDeviceKey
);
244 if (hEnumKey
!= NULL
)
245 RegCloseKey(hEnumKey
);
247 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
255 PNP_GetRootDeviceInstance(handle_t BindingHandle
,
256 wchar_t *DeviceInstance
,
257 unsigned long Length
)
259 CONFIGRET ret
= CR_SUCCESS
;
261 DPRINT("PNP_GetRootDeviceInstance() called\n");
263 if (Length
< lstrlenW(szRootDeviceId
) + 1)
265 ret
= CR_BUFFER_SMALL
;
269 lstrcpyW(DeviceInstance
,
273 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
281 PNP_GetRelatedDeviceInstance(handle_t BindingHandle
,
282 unsigned long Relationship
,
284 wchar_t *RelatedDeviceId
,
285 unsigned long Length
,
288 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
289 CONFIGRET ret
= CR_SUCCESS
;
292 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
293 DPRINT(" Relationship %ld\n", Relationship
);
294 DPRINT(" DeviceId %S\n", DeviceId
);
296 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
299 PlugPlayData
.Relation
= Relationship
;
301 PlugPlayData
.RelatedDeviceInstanceLength
= Length
;
302 PlugPlayData
.RelatedDeviceInstance
= 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 if(lstrlenW(ClassGuid
) < sizeof(szKeyName
)/sizeof(WCHAR
)-lstrlenW(szKeyName
))
836 lstrcatW(szKeyName
, ClassGuid
);
837 else return CR_INVALID_DATA
;
839 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
844 return CR_REGISTRY_ERROR
;
846 ulSize
= *Length
* sizeof(WCHAR
);
847 if (RegQueryValueExW(hKey
,
855 ret
= CR_REGISTRY_ERROR
;
859 *Length
= ulSize
/ sizeof(WCHAR
);
864 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
872 PNP_DeleteClassKey(handle_t BindingHandle
,
876 CONFIGRET ret
= CR_SUCCESS
;
878 DPRINT("PNP_GetClassName(%S, %lx) called\n", ClassGuid
, Flags
);
880 if (Flags
& CM_DELETE_CLASS_SUBKEYS
)
882 if (RegDeleteTreeW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
883 ret
= CR_REGISTRY_ERROR
;
887 if (RegDeleteKeyW(hClassKey
, ClassGuid
) != ERROR_SUCCESS
)
888 ret
= CR_REGISTRY_ERROR
;
891 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
899 PNP_CreateDevInst(handle_t BindingHandle
,
900 wchar_t *DeviceId
, /* [in, out, string, size_is(Length)] */
901 wchar_t *ParentDeviceId
, /* [in, string] */
902 unsigned long Length
, /* [in] */
903 unsigned long Flags
) /* [in] */
905 CONFIGRET ret
= CR_CALL_NOT_IMPLEMENTED
;
907 DPRINT1("PNP_CreateDevInst() called\n");
909 DPRINT1("PNP_CreateDevInst() done (returns %lx)\n", ret
);
917 PNP_DeviceInstanceAction(handle_t BindingHandle
,
918 unsigned long MajorAction
,
919 unsigned long MinorAction
,
920 wchar_t *DeviceInstance1
,
921 wchar_t *DeviceInstance2
)
923 CONFIGRET ret
= CR_SUCCESS
;
925 DPRINT("PNP_DeviceInstanceAction() called\n");
930 DPRINT("Move device instance\n");
932 ret
= CR_CALL_NOT_IMPLEMENTED
;
936 DPRINT("Setup device instance\n");
938 ret
= CR_CALL_NOT_IMPLEMENTED
;
942 DPRINT("Enable device instance\n");
944 ret
= CR_CALL_NOT_IMPLEMENTED
;
948 DPRINT("Disable device instance\n");
950 ret
= CR_CALL_NOT_IMPLEMENTED
;
954 DPRINT("Reenumerate device instance\n");
956 ret
= CR_CALL_NOT_IMPLEMENTED
;
960 DPRINT1("Unknown function %lu\n", MajorAction
);
961 ret
= CR_CALL_NOT_IMPLEMENTED
;
964 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
972 PNP_GetDeviceStatus(handle_t BindingHandle
,
973 wchar_t *DeviceInstance
,
974 unsigned long *pStatus
,
975 unsigned long *pProblem
,
978 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
979 CONFIGRET ret
= CR_SUCCESS
;
982 DPRINT("PNP_GetDeviceStatus() called\n");
984 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
986 PlugPlayData
.Operation
= 0; /* Get status */
988 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
989 (PVOID
)&PlugPlayData
,
990 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
991 if (NT_SUCCESS(Status
))
993 *pStatus
= PlugPlayData
.DeviceStatus
;
994 *pProblem
= PlugPlayData
.DeviceProblem
;
998 ret
= NtStatusToCrError(Status
);
1001 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1009 PNP_SetDeviceProblem(handle_t BindingHandle
,
1010 wchar_t *DeviceInstance
,
1011 unsigned long Problem
,
1014 CONFIGRET ret
= CR_SUCCESS
;
1016 DPRINT1("PNP_SetDeviceProblem() called\n");
1020 DPRINT1("PNP_SetDeviceProblem() done (returns %lx)\n", ret
);
1028 PNP_UninstallDevInst(handle_t BindingHandle
,
1029 wchar_t *DeviceInstance
,
1032 CONFIGRET ret
= CR_SUCCESS
;
1034 DPRINT1("PNP_UninstallDevInst() called\n");
1038 DPRINT1("PNP_UninstallDevInst() done (returns %lx)\n", ret
);
1045 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1051 lpPtr
= lpDeviceIdList
;
1054 dwLength
= wcslen(lpPtr
);
1055 if (!_wcsicmp(lpPtr
, lpDeviceId
))
1058 lpPtr
+= (dwLength
+ 1);
1066 AppendDeviceId(LPWSTR lpDeviceIdList
,
1067 LPDWORD lpDeviceIdListSize
,
1073 dwLen
= wcslen(lpDeviceId
);
1074 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1076 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1078 dwPos
+= (dwLen
+ 1);
1080 lpDeviceIdList
[dwPos
] = 0;
1082 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1088 PNP_AddID(handle_t BindingHandle
,
1089 wchar_t *DeviceInstance
,
1093 CONFIGRET ret
= CR_SUCCESS
;
1096 DWORD dwDeviceIdListSize
;
1097 WCHAR szDeviceIdList
[512];
1099 DPRINT("PNP_AddID() called\n");
1100 DPRINT(" DeviceInstance: %S\n", DeviceInstance
);
1101 DPRINT(" DeviceId: %S\n", DeviceId
);
1102 DPRINT(" Flags: %lx\n", Flags
);
1104 if (RegOpenKeyExW(hEnumKey
,
1107 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1108 &hDeviceKey
) != ERROR_SUCCESS
)
1110 DPRINT("Failed to open the device key!\n");
1111 return CR_INVALID_DEVNODE
;
1114 pszSubKey
= (Flags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1116 dwDeviceIdListSize
= 512 * sizeof(WCHAR
);
1117 if (RegQueryValueExW(hDeviceKey
,
1121 (LPBYTE
)szDeviceIdList
,
1122 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1124 DPRINT("Failed to query the desired ID string!\n");
1125 ret
= CR_REGISTRY_ERROR
;
1129 /* Check whether the device ID is already in use */
1130 if (CheckForDeviceId(szDeviceIdList
, DeviceId
))
1132 DPRINT("Device ID was found in the ID string!\n");
1137 /* Append the Device ID */
1138 AppendDeviceId(szDeviceIdList
, &dwDeviceIdListSize
, DeviceId
);
1140 if (RegSetValueExW(hDeviceKey
,
1144 (LPBYTE
)szDeviceIdList
,
1145 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1147 DPRINT("Failed to set the desired ID string!\n");
1148 ret
= CR_REGISTRY_ERROR
;
1152 RegCloseKey(hDeviceKey
);
1154 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1162 PNP_IsDockStationPresent(handle_t BindingHandle
,
1163 unsigned long *Present
)
1169 CONFIGRET ret
= CR_SUCCESS
;
1171 DPRINT1("PNP_IsDockStationPresent() called\n");
1175 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
1179 &hKey
) != ERROR_SUCCESS
)
1180 return CR_REGISTRY_ERROR
;
1182 dwSize
= sizeof(DWORD
);
1183 if (RegQueryValueExW(hKey
,
1188 &dwSize
) != ERROR_SUCCESS
)
1189 ret
= CR_REGISTRY_ERROR
;
1193 if (ret
== CR_SUCCESS
)
1195 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
1197 ret
= CR_REGISTRY_ERROR
;
1199 else if (dwValue
!= 0)
1205 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
1213 PNP_RequestEjectPC(handle_t BindingHandle
)
1215 CONFIGRET ret
= CR_SUCCESS
;
1217 DPRINT1("PNP_RequestEjectPC() called\n");
1219 ret
= CR_FAILURE
; /* FIXME */
1221 DPRINT1("PNP_RequestEjectPC() done (returns %lx)\n", ret
);
1229 PNP_HwProfFlags(handle_t BindingHandle
,
1230 unsigned long Action
,
1232 unsigned long ProfileId
,
1233 unsigned long *Value
, // out
1234 unsigned long Flags
)
1236 CONFIGRET ret
= CR_SUCCESS
;
1238 DPRINT1("PNP_HwProfFlags() called\n");
1240 ret
= CR_CALL_NOT_IMPLEMENTED
; /* FIXME */
1242 DPRINT1("PNP_HwProfFlags() done (returns %lx)\n", ret
);
1250 PNP_AddEmptyLogConf(handle_t BindingHandle
,
1251 wchar_t *DeviceInstance
,
1253 ULONG
*ulLogConfTag
,
1256 CONFIGRET ret
= CR_SUCCESS
;
1258 DPRINT1("PNP_AddEmptyLogConf() called\n");
1260 *ulLogConfTag
= 0; /* FIXME */
1262 DPRINT1("PNP_AddEmptyLogConf() done (returns %lx)\n", ret
);
1270 PNP_RunDetection(handle_t BindingHandle
,
1271 unsigned long Flags
)
1273 DPRINT("PNP_RunDetection() called\n");
1274 return CR_CALL_NOT_IMPLEMENTED
;
1278 typedef BOOL (WINAPI
*PDEV_INSTALL_W
)(HWND
, HINSTANCE
, LPCWSTR
, INT
);
1281 InstallDevice(PCWSTR DeviceInstance
, BOOL SetupIsActive
)
1283 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1284 HMODULE hNewDev
= NULL
;
1285 PDEV_INSTALL_W DevInstallW
;
1287 BOOL DeviceInstalled
= FALSE
;
1289 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1291 PlugPlayData
.Operation
= 0; /* Get status */
1293 /* Get device status */
1294 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1295 (PVOID
)&PlugPlayData
,
1296 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1297 if (!NT_SUCCESS(Status
))
1300 if (PlugPlayData
.DeviceStatus
& DNF_STARTED
|| PlugPlayData
.DeviceStatus
& DNF_START_FAILED
)
1301 /* Device is already started, or disabled due to some problem. Don't install it */
1304 /* Install device */
1305 SetEnvironmentVariable(L
"USERPROFILE", L
"."); /* FIXME: why is it needed? */
1307 hNewDev
= LoadLibraryW(L
"newdev.dll");
1311 DevInstallW
= (PDEV_INSTALL_W
)GetProcAddress(hNewDev
, (LPCSTR
)"DevInstallW");
1315 if (!DevInstallW(NULL
, NULL
, DeviceInstance
, SetupIsActive
? SW_HIDE
: SW_SHOWNOACTIVATE
))
1318 DeviceInstalled
= TRUE
;
1321 if (hNewDev
!= NULL
)
1322 FreeLibrary(hNewDev
);
1324 return DeviceInstalled
;
1332 DWORD regType
, active
, size
;
1336 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
1337 if (rc
!= ERROR_SUCCESS
)
1340 size
= sizeof(DWORD
);
1341 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
1342 if (rc
!= ERROR_SUCCESS
)
1344 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
1347 ret
= (active
!= 0);
1353 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
1360 PnpEventThread(LPVOID lpParameter
)
1362 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
1365 RPC_STATUS RpcStatus
;
1368 PnpEventSize
= 0x1000;
1369 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
1370 if (PnpEvent
== NULL
)
1371 return ERROR_OUTOFMEMORY
;
1373 setupActive
= SetupIsActive();
1377 DPRINT("Calling NtGetPlugPlayEvent()\n");
1379 /* Wait for the next pnp event */
1380 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
1382 /* Resize the buffer for the PnP event if it's too small. */
1383 if (Status
== STATUS_BUFFER_TOO_SMALL
)
1385 PnpEventSize
+= 0x400;
1386 PnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
1387 if (PnpEvent
== NULL
)
1388 return ERROR_OUTOFMEMORY
;
1392 if (!NT_SUCCESS(Status
))
1394 DPRINT("NtPlugPlayEvent() failed (Status %lx)\n", Status
);
1398 DPRINT("Received PnP Event\n");
1399 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
1401 DPRINT("Device arrival event: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
1402 InstallDevice(PnpEvent
->TargetDevice
.DeviceIds
, setupActive
);
1406 DPRINT1("Unknown event\n");
1409 /* FIXME: Process the pnp event */
1411 /* Dequeue the current pnp event and signal the next one */
1412 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
1415 HeapFree(GetProcessHeap(), 0, PnpEvent
);
1417 return ERROR_SUCCESS
;
1421 static VOID CALLBACK
1422 ServiceMain(DWORD argc
, LPTSTR
*argv
)
1427 DPRINT("ServiceMain() called\n");
1429 hThread
= CreateThread(NULL
,
1435 if (hThread
!= NULL
)
1436 CloseHandle(hThread
);
1438 hThread
= CreateThread(NULL
,
1444 if (hThread
!= NULL
)
1445 CloseHandle(hThread
);
1447 DPRINT("ServiceMain() done\n");
1452 main(int argc
, char *argv
[])
1456 DPRINT("Umpnpmgr: main() started\n");
1458 hInstallEvent
= CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
1459 if (hInstallEvent
== NULL
)
1461 dwError
= GetLastError();
1462 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
1466 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1467 L
"System\\CurrentControlSet\\Enum",
1471 if (dwError
!= ERROR_SUCCESS
)
1473 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
1477 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1478 L
"System\\CurrentControlSet\\Control\\Class",
1482 if (dwError
!= ERROR_SUCCESS
)
1484 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
1488 StartServiceCtrlDispatcher(ServiceTable
);
1490 DPRINT("Umpnpmgr: main() done\n");