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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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)
26 * Colin Finck (colin@reactos.org)
29 /* INCLUDES *****************************************************************/
30 //#define HAVE_SLIST_ENTRY_IMPLEMENTED
31 #define WIN32_NO_STATUS
33 #define COM_NO_WINDOWS_H
43 #include <umpnpmgr/sysguid.h>
52 /* GLOBALS ******************************************************************/
54 static VOID CALLBACK
ServiceMain(DWORD argc
, LPWSTR
*argv
);
55 static WCHAR ServiceName
[] = L
"PlugPlay";
56 static SERVICE_TABLE_ENTRYW ServiceTable
[] =
58 {ServiceName
, ServiceMain
},
62 static SERVICE_STATUS_HANDLE ServiceStatusHandle
;
63 static SERVICE_STATUS ServiceStatus
;
65 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
67 static HKEY hEnumKey
= NULL
;
68 static HKEY hClassKey
= NULL
;
70 static HANDLE hUserToken
= NULL
;
71 static HANDLE hInstallEvent
= NULL
;
72 static HANDLE hNoPendingInstalls
= NULL
;
74 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
75 static SLIST_HEADER DeviceInstallListHead
;
77 static LIST_ENTRY DeviceInstallListHead
;
79 static HANDLE hDeviceInstallListNotEmpty
;
83 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
84 SLIST_ENTRY ListEntry
;
89 } DeviceInstallParams
;
91 /* FUNCTIONS *****************************************************************/
94 RpcServerThread(LPVOID lpParameter
)
97 BOOLEAN RegisteredProtSeq
= FALSE
;
99 UNREFERENCED_PARAMETER(lpParameter
);
101 DPRINT("RpcServerThread() called\n");
104 /* XP-compatible protocol sequence/endpoint */
105 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
108 NULL
); // Security descriptor
109 if (Status
== RPC_S_OK
)
110 RegisteredProtSeq
= TRUE
;
112 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
115 /* Vista-compatible protocol sequence/endpoint */
116 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
119 NULL
); // Security descriptor
120 if (Status
== RPC_S_OK
)
121 RegisteredProtSeq
= TRUE
;
123 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
125 /* Make sure there's a usable endpoint */
126 if (RegisteredProtSeq
== FALSE
)
129 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
132 if (Status
!= RPC_S_OK
)
134 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
138 Status
= RpcServerListen(1,
141 if (Status
!= RPC_S_OK
)
143 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
147 /* ROS HACK (this should never happen...) */
148 DPRINT1("*** Other devices won't be installed correctly. If something\n");
149 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
151 DPRINT("RpcServerThread() done\n");
157 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
159 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
163 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
165 HeapFree(GetProcessHeap(), 0, ptr
);
169 static CONFIGRET WINAPI
170 NtStatusToCrError(NTSTATUS Status
)
174 case STATUS_NO_SUCH_DEVICE
:
175 return CR_NO_SUCH_DEVINST
;
178 /* FIXME: add more mappings */
179 DPRINT1("Unable to map status 0x%08lx\n", Status
);
186 DWORD
PNP_Disconnect(
189 UNREFERENCED_PARAMETER(hBinding
);
198 UNREFERENCED_PARAMETER(hBinding
);
204 DWORD
PNP_GetVersion(
208 UNREFERENCED_PARAMETER(hBinding
);
216 DWORD
PNP_GetGlobalState(
221 UNREFERENCED_PARAMETER(hBinding
);
222 UNREFERENCED_PARAMETER(ulFlags
);
224 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
230 DWORD
PNP_InitDetection(
233 UNREFERENCED_PARAMETER(hBinding
);
235 DPRINT("PNP_InitDetection() called\n");
241 DWORD
PNP_ReportLogOn(
246 DWORD ReturnValue
= CR_FAILURE
;
249 UNREFERENCED_PARAMETER(hBinding
);
250 UNREFERENCED_PARAMETER(Admin
);
252 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
254 /* Get the users token */
255 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
259 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
265 CloseHandle(hUserToken
);
269 if(!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
271 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
275 /* Trigger the installer thread */
277 SetEvent(hInstallEvent
);
279 ReturnValue
= CR_SUCCESS
;
283 CloseHandle(hProcess
);
290 DWORD
PNP_ValidateDeviceInstance(
295 CONFIGRET ret
= CR_SUCCESS
;
296 HKEY hDeviceKey
= NULL
;
298 UNREFERENCED_PARAMETER(hBinding
);
299 UNREFERENCED_PARAMETER(ulFlags
);
301 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
304 if (RegOpenKeyExW(hEnumKey
,
310 DPRINT("Could not open the Device Key!\n");
311 ret
= CR_NO_SUCH_DEVNODE
;
315 /* FIXME: add more tests */
318 if (hDeviceKey
!= NULL
)
319 RegCloseKey(hDeviceKey
);
321 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
328 DWORD
PNP_GetRootDeviceInstance(
331 PNP_RPC_STRING_LEN ulLength
)
333 CONFIGRET ret
= CR_SUCCESS
;
335 UNREFERENCED_PARAMETER(hBinding
);
337 DPRINT("PNP_GetRootDeviceInstance() called\n");
341 ret
= CR_INVALID_POINTER
;
344 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
346 ret
= CR_BUFFER_SMALL
;
354 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
361 DWORD
PNP_GetRelatedDeviceInstance(
363 DWORD ulRelationship
,
365 LPWSTR pRelatedDeviceId
,
366 PNP_RPC_STRING_LEN
*pulLength
,
369 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
370 CONFIGRET ret
= CR_SUCCESS
;
373 UNREFERENCED_PARAMETER(hBinding
);
374 UNREFERENCED_PARAMETER(ulFlags
);
376 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
377 DPRINT(" Relationship %ld\n", ulRelationship
);
378 DPRINT(" DeviceId %S\n", pDeviceID
);
380 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
383 PlugPlayData
.Relation
= ulRelationship
;
385 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
386 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
388 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
389 (PVOID
)&PlugPlayData
,
390 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
391 if (!NT_SUCCESS(Status
))
393 ret
= NtStatusToCrError(Status
);
396 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
397 if (ret
== CR_SUCCESS
)
399 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
407 DWORD
PNP_EnumerateSubKeys(
412 PNP_RPC_STRING_LEN ulLength
,
413 PNP_RPC_STRING_LEN
*pulRequiredLen
,
416 CONFIGRET ret
= CR_SUCCESS
;
420 UNREFERENCED_PARAMETER(hBinding
);
421 UNREFERENCED_PARAMETER(ulFlags
);
423 DPRINT("PNP_EnumerateSubKeys() called\n");
427 case PNP_ENUMERATOR_SUBKEYS
:
431 case PNP_CLASS_SUBKEYS
:
439 *pulRequiredLen
= ulLength
;
440 dwError
= RegEnumKeyExW(hKey
,
448 if (dwError
!= ERROR_SUCCESS
)
450 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
457 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
464 DWORD
PNP_GetDeviceList(
468 PNP_RPC_STRING_LEN
*pulLength
,
472 return CR_CALL_NOT_IMPLEMENTED
;
477 DWORD
PNP_GetDeviceListSize(
480 PNP_RPC_BUFFER_SIZE
*pulLen
,
484 return CR_CALL_NOT_IMPLEMENTED
;
495 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
496 CONFIGRET ret
= CR_SUCCESS
;
499 UNREFERENCED_PARAMETER(hBinding
);
500 UNREFERENCED_PARAMETER(ulFlags
);
502 DPRINT("PNP_GetDepth() called\n");
504 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
507 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
508 (PVOID
)&PlugPlayData
,
509 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
510 if (NT_SUCCESS(Status
))
512 *pulDepth
= PlugPlayData
.Depth
;
516 ret
= NtStatusToCrError(Status
);
519 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
526 DWORD
PNP_GetDeviceRegProp(
530 DWORD
*pulRegDataType
,
532 PNP_PROP_SIZE
*pulTransferLen
,
533 PNP_PROP_SIZE
*pulLength
,
536 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
537 CONFIGRET ret
= CR_SUCCESS
;
538 LPWSTR lpValueName
= NULL
;
543 UNREFERENCED_PARAMETER(hBinding
);
545 DPRINT("PNP_GetDeviceRegProp() called\n");
547 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
549 ret
= CR_INVALID_POINTER
;
555 ret
= CR_INVALID_FLAG
;
559 /* FIXME: Check pDeviceID */
561 if (*pulLength
< *pulTransferLen
)
562 *pulLength
= *pulTransferLen
;
568 case CM_DRP_DEVICEDESC
:
569 lpValueName
= L
"DeviceDesc";
572 case CM_DRP_HARDWAREID
:
573 lpValueName
= L
"HardwareID";
576 case CM_DRP_COMPATIBLEIDS
:
577 lpValueName
= L
"CompatibleIDs";
581 lpValueName
= L
"Service";
585 lpValueName
= L
"Class";
588 case CM_DRP_CLASSGUID
:
589 lpValueName
= L
"ClassGUID";
593 lpValueName
= L
"Driver";
596 case CM_DRP_CONFIGFLAGS
:
597 lpValueName
= L
"ConfigFlags";
601 lpValueName
= L
"Mfg";
604 case CM_DRP_FRIENDLYNAME
:
605 lpValueName
= L
"FriendlyName";
608 case CM_DRP_LOCATION_INFORMATION
:
609 lpValueName
= L
"LocationInformation";
612 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
616 case CM_DRP_CAPABILITIES
:
617 lpValueName
= L
"Capabilities";
620 case CM_DRP_UI_NUMBER
:
624 case CM_DRP_UPPERFILTERS
:
625 lpValueName
= L
"UpperFilters";
628 case CM_DRP_LOWERFILTERS
:
629 lpValueName
= L
"LowerFilters";
632 case CM_DRP_BUSTYPEGUID
:
636 case CM_DRP_LEGACYBUSTYPE
:
640 case CM_DRP_BUSNUMBER
:
644 case CM_DRP_ENUMERATOR_NAME
:
648 case CM_DRP_SECURITY
:
649 lpValueName
= L
"Security";
653 lpValueName
= L
"DeviceType";
656 case CM_DRP_EXCLUSIVE
:
657 lpValueName
= L
"Exclusive";
660 case CM_DRP_CHARACTERISTICS
:
661 lpValueName
= L
"DeviceCharacteristics";
668 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
669 lpValueName
= L
"UINumberDescFormat";
672 case CM_DRP_DEVICE_POWER_DATA
:
676 case CM_DRP_REMOVAL_POLICY
:
680 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
684 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
685 lpValueName
= L
"RemovalPolicy";
688 case CM_DRP_INSTALL_STATE
:
692 #if (WINVER >= _WIN32_WINNT_WS03)
693 case CM_DRP_LOCATION_PATHS
:
698 #if (WINVER >= _WIN32_WINNT_WIN7)
699 case CM_DRP_BASE_CONTAINERID
:
705 ret
= CR_INVALID_PROPERTY
;
709 DPRINT("Value name: %S\n", lpValueName
);
713 /* Retrieve information from the Registry */
714 lError
= RegOpenKeyExW(hEnumKey
,
719 if (lError
!= ERROR_SUCCESS
)
723 ret
= CR_INVALID_DEVNODE
;
727 lError
= RegQueryValueExW(hKey
,
733 if (lError
!= ERROR_SUCCESS
)
735 if (lError
== ERROR_MORE_DATA
)
737 ret
= CR_BUFFER_SMALL
;
742 ret
= CR_NO_SUCH_VALUE
;
748 /* Retrieve information from the Device Node */
749 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
751 PlugPlayData
.Buffer
= Buffer
;
752 PlugPlayData
.BufferSize
= *pulLength
;
756 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
757 PlugPlayData
.Property
= 0xb; // DevicePropertyPhysicalDeviceObjectName;
760 case CM_DRP_UI_NUMBER
:
761 PlugPlayData
.Property
= 0x11; // DevicePropertyUINumber;
764 case CM_DRP_BUSTYPEGUID
:
765 PlugPlayData
.Property
= 0xc; // DevicePropertyBusTypeGuid;
768 case CM_DRP_LEGACYBUSTYPE
:
769 PlugPlayData
.Property
= 0xd; // DevicePropertyLegacyBusType;
772 case CM_DRP_BUSNUMBER
:
773 PlugPlayData
.Property
= 0xe; // DevicePropertyBusNumber;
776 case CM_DRP_ENUMERATOR_NAME
:
777 PlugPlayData
.Property
= 0xf; // DevicePropertyEnumeratorName;
781 PlugPlayData
.Property
= 0x10; // DevicePropertyAddress;
785 /* FIXME: This property is not supported by IoGetDeviceProperty */
786 case CM_DRP_DEVICE_POWER_DATA
:
789 case CM_DRP_REMOVAL_POLICY
:
790 PlugPlayData
.Property
= 0x12; // DevicePropertyRemovalPolicy
794 /* FIXME: This property is not supported by IoGetDeviceProperty */
795 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
798 case CM_DRP_INSTALL_STATE
:
799 PlugPlayData
.Property
= 0x12; // DevicePropertyInstallState;
803 /* FIXME: This property is not supported by IoGetDeviceProperty */
804 #if (WINVER >= _WIN32_WINNT_WS03)
805 case CM_DRP_LOCATION_PATHS
:
809 #if (WINVER >= _WIN32_WINNT_WIN7)
810 case CM_DRP_BASE_CONTAINERID
:
811 PlugPlayData
.Property
= 0x16; // DevicePropertyContainerID;
816 return CR_INVALID_PROPERTY
;
819 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
820 (PVOID
)&PlugPlayData
,
821 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
822 if (NT_SUCCESS(Status
))
824 *pulLength
= PlugPlayData
.BufferSize
;
828 ret
= NtStatusToCrError(Status
);
833 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
838 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
845 DWORD
PNP_SetDeviceRegProp(
851 PNP_PROP_SIZE ulLength
,
854 CONFIGRET ret
= CR_SUCCESS
;
855 LPWSTR lpValueName
= NULL
;
858 UNREFERENCED_PARAMETER(hBinding
);
859 UNREFERENCED_PARAMETER(ulFlags
);
861 DPRINT("PNP_SetDeviceRegProp() called\n");
863 DPRINT("DeviceId: %S\n", pDeviceId
);
864 DPRINT("Property: %lu\n", ulProperty
);
865 DPRINT("DataType: %lu\n", ulDataType
);
866 DPRINT("Length: %lu\n", ulLength
);
870 case CM_DRP_DEVICEDESC
:
871 lpValueName
= L
"DeviceDesc";
874 case CM_DRP_HARDWAREID
:
875 lpValueName
= L
"HardwareID";
878 case CM_DRP_COMPATIBLEIDS
:
879 lpValueName
= L
"CompatibleIDs";
883 lpValueName
= L
"Service";
887 lpValueName
= L
"Class";
890 case CM_DRP_CLASSGUID
:
891 lpValueName
= L
"ClassGUID";
895 lpValueName
= L
"Driver";
898 case CM_DRP_CONFIGFLAGS
:
899 lpValueName
= L
"ConfigFlags";
903 lpValueName
= L
"Mfg";
906 case CM_DRP_FRIENDLYNAME
:
907 lpValueName
= L
"FriendlyName";
910 case CM_DRP_LOCATION_INFORMATION
:
911 lpValueName
= L
"LocationInformation";
914 case CM_DRP_UPPERFILTERS
:
915 lpValueName
= L
"UpperFilters";
918 case CM_DRP_LOWERFILTERS
:
919 lpValueName
= L
"LowerFilters";
922 case CM_DRP_SECURITY
:
923 lpValueName
= L
"Security";
927 lpValueName
= L
"DeviceType";
930 case CM_DRP_EXCLUSIVE
:
931 lpValueName
= L
"Exclusive";
934 case CM_DRP_CHARACTERISTICS
:
935 lpValueName
= L
"DeviceCharacteristics";
938 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
939 lpValueName
= L
"UINumberDescFormat";
942 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
943 lpValueName
= L
"RemovalPolicy";
947 return CR_INVALID_PROPERTY
;
950 DPRINT("Value name: %S\n", lpValueName
);
952 if (RegOpenKeyExW(hEnumKey
,
957 return CR_INVALID_DEVNODE
;
961 if (RegDeleteValueW(hKey
,
963 ret
= CR_REGISTRY_ERROR
;
967 if (RegSetValueExW(hKey
,
973 ret
= CR_REGISTRY_ERROR
;
978 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
985 DWORD
PNP_GetClassInstance(
988 LPWSTR pszClassInstance
,
989 PNP_RPC_STRING_LEN ulLength
)
992 return CR_CALL_NOT_IMPLEMENTED
;
1005 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1014 return CR_REGISTRY_ERROR
;
1016 /* FIXME: Set security key */
1025 DWORD
PNP_DeleteRegistryKey(
1028 LPWSTR pszParentKey
,
1033 return CR_CALL_NOT_IMPLEMENTED
;
1038 DWORD
PNP_GetClassCount(
1040 DWORD
*pulClassCount
,
1046 UNREFERENCED_PARAMETER(hBinding
);
1047 UNREFERENCED_PARAMETER(ulFlags
);
1049 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1054 if (dwError
!= ERROR_SUCCESS
)
1055 return CR_INVALID_DATA
;
1057 dwError
= RegQueryInfoKeyW(hKey
,
1070 if (dwError
!= ERROR_SUCCESS
)
1071 return CR_INVALID_DATA
;
1078 DWORD
PNP_GetClassName(
1080 LPWSTR pszClassGuid
,
1082 PNP_RPC_STRING_LEN
*pulLength
,
1085 WCHAR szKeyName
[MAX_PATH
];
1086 CONFIGRET ret
= CR_SUCCESS
;
1090 UNREFERENCED_PARAMETER(hBinding
);
1091 UNREFERENCED_PARAMETER(ulFlags
);
1093 DPRINT("PNP_GetClassName() called\n");
1095 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1096 if(lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1097 lstrcatW(szKeyName
, pszClassGuid
);
1098 else return CR_INVALID_DATA
;
1100 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1105 return CR_REGISTRY_ERROR
;
1107 dwSize
= *pulLength
* sizeof(WCHAR
);
1108 if (RegQueryValueExW(hKey
,
1116 ret
= CR_REGISTRY_ERROR
;
1120 *pulLength
= dwSize
/ sizeof(WCHAR
);
1125 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1132 DWORD
PNP_DeleteClassKey(
1134 LPWSTR pszClassGuid
,
1137 CONFIGRET ret
= CR_SUCCESS
;
1139 UNREFERENCED_PARAMETER(hBinding
);
1141 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1143 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1145 if (RegDeleteTreeW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1146 ret
= CR_REGISTRY_ERROR
;
1150 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1151 ret
= CR_REGISTRY_ERROR
;
1154 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1161 DWORD
PNP_GetInterfaceDeviceAlias(
1163 LPWSTR pszInterfaceDevice
,
1164 GUID
*AliasInterfaceGuid
,
1165 LPWSTR pszAliasInterfaceDevice
,
1166 PNP_RPC_STRING_LEN
*pulLength
,
1167 PNP_RPC_STRING_LEN
*pulTransferLen
,
1171 return CR_CALL_NOT_IMPLEMENTED
;
1176 DWORD
PNP_GetInterfaceDeviceList(
1178 GUID
*InterfaceGuid
,
1181 PNP_RPC_BUFFER_SIZE
*pulLength
,
1185 return CR_CALL_NOT_IMPLEMENTED
;
1190 DWORD
PNP_GetInterfaceDeviceListSize(
1192 PNP_RPC_BUFFER_SIZE
*pulLen
,
1193 GUID
*InterfaceGuid
,
1198 return CR_CALL_NOT_IMPLEMENTED
;
1203 DWORD
PNP_RegisterDeviceClassAssociation(
1206 GUID
*InterfaceGuid
,
1207 LPWSTR pszReference
,
1209 PNP_RPC_STRING_LEN
*pulLength
,
1210 PNP_RPC_STRING_LEN
*pulTransferLen
,
1214 return CR_CALL_NOT_IMPLEMENTED
;
1219 DWORD
PNP_UnregisterDeviceClassAssociation(
1221 LPWSTR pszInterfaceDevice
,
1225 return CR_CALL_NOT_IMPLEMENTED
;
1230 DWORD
PNP_GetClassRegProp(
1232 LPWSTR pszClassGuid
,
1234 DWORD
*pulRegDataType
,
1236 PNP_RPC_STRING_LEN
*pulTransferLen
,
1237 PNP_RPC_STRING_LEN
*pulLength
,
1240 CONFIGRET ret
= CR_SUCCESS
;
1241 LPWSTR lpValueName
= NULL
;
1242 HKEY hInstKey
= NULL
;
1243 HKEY hPropKey
= NULL
;
1246 UNREFERENCED_PARAMETER(hBinding
);
1248 DPRINT("PNP_GetClassRegProp() called\n");
1250 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1252 ret
= CR_INVALID_POINTER
;
1258 ret
= CR_INVALID_FLAG
;
1262 if (*pulLength
< *pulTransferLen
)
1263 *pulLength
= *pulTransferLen
;
1265 *pulTransferLen
= 0;
1269 case CM_CRP_SECURITY
:
1270 lpValueName
= L
"Security";
1273 case CM_CRP_DEVTYPE
:
1274 lpValueName
= L
"DeviceType";
1277 case CM_CRP_EXCLUSIVE
:
1278 lpValueName
= L
"Exclusive";
1281 case CM_CRP_CHARACTERISTICS
:
1282 lpValueName
= L
"DeviceCharacteristics";
1286 ret
= CR_INVALID_PROPERTY
;
1290 DPRINT("Value name: %S\n", lpValueName
);
1292 lError
= RegOpenKeyExW(hClassKey
,
1297 if (lError
!= ERROR_SUCCESS
)
1300 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1304 lError
= RegOpenKeyExW(hInstKey
,
1309 if (lError
!= ERROR_SUCCESS
)
1312 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1316 lError
= RegQueryValueExW(hPropKey
,
1322 if (lError
!= ERROR_SUCCESS
)
1324 if (lError
== ERROR_MORE_DATA
)
1326 ret
= CR_BUFFER_SMALL
;
1331 ret
= CR_NO_SUCH_VALUE
;
1336 if (ret
== CR_SUCCESS
)
1337 *pulTransferLen
= *pulLength
;
1339 if (hPropKey
!= NULL
)
1340 RegCloseKey(hPropKey
);
1342 if (hInstKey
!= NULL
)
1343 RegCloseKey(hInstKey
);
1345 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1352 DWORD
PNP_SetClassRegProp(
1354 LPWSTR pszClassGuid
,
1358 PNP_PROP_SIZE ulLength
,
1361 CONFIGRET ret
= CR_SUCCESS
;
1362 LPWSTR lpValueName
= NULL
;
1367 UNREFERENCED_PARAMETER(hBinding
);
1369 DPRINT("PNP_SetClassRegProp() called\n");
1372 return CR_INVALID_FLAG
;
1376 case CM_CRP_SECURITY
:
1377 lpValueName
= L
"Security";
1380 case CM_CRP_DEVTYPE
:
1381 lpValueName
= L
"DeviceType";
1384 case CM_CRP_EXCLUSIVE
:
1385 lpValueName
= L
"Exclusive";
1388 case CM_CRP_CHARACTERISTICS
:
1389 lpValueName
= L
"DeviceCharacteristics";
1393 return CR_INVALID_PROPERTY
;
1396 lError
= RegOpenKeyExW(hClassKey
,
1401 if (lError
!= ERROR_SUCCESS
)
1403 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1407 /* FIXME: Set security descriptor */
1408 lError
= RegCreateKeyExW(hInstKey
,
1412 REG_OPTION_NON_VOLATILE
,
1417 if (lError
!= ERROR_SUCCESS
)
1419 ret
= CR_REGISTRY_ERROR
;
1425 if (RegDeleteValueW(hPropKey
,
1427 ret
= CR_REGISTRY_ERROR
;
1431 if (RegSetValueExW(hPropKey
,
1437 ret
= CR_REGISTRY_ERROR
;
1441 if (hPropKey
!= NULL
)
1442 RegCloseKey(hPropKey
);
1444 if (hInstKey
!= NULL
)
1445 RegCloseKey(hInstKey
);
1452 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1453 OUT LPWSTR pszEnumerator
,
1454 OUT LPWSTR pszDevice
,
1455 OUT LPWSTR pszInstance
)
1457 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1458 LPWSTR lpEnumerator
= NULL
;
1459 LPWSTR lpDevice
= NULL
;
1460 LPWSTR lpInstance
= NULL
;
1463 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1469 lpEnumerator
= szLocalDeviceInstanceID
;
1471 ptr
= wcschr(lpEnumerator
, L
'\\');
1477 ptr
= wcschr(lpDevice
, L
'\\');
1485 if (lpEnumerator
!= NULL
)
1486 wcscpy(pszEnumerator
, lpEnumerator
);
1488 if (lpDevice
!= NULL
)
1489 wcscpy(pszDevice
, lpDevice
);
1491 if (lpInstance
!= NULL
)
1492 wcscpy(pszInstance
, lpInstance
);
1497 CreateDeviceInstance(LPWSTR pszDeviceID
)
1499 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1500 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1501 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1502 HKEY hKeyEnumerator
;
1508 /* Split the instance ID */
1509 SplitDeviceInstanceID(pszDeviceID
,
1514 /* Open or create the enumerator key */
1515 lError
= RegCreateKeyExW(hEnumKey
,
1519 REG_OPTION_NON_VOLATILE
,
1524 if (lError
!= ERROR_SUCCESS
)
1526 return CR_REGISTRY_ERROR
;
1529 /* Open or create the device key */
1530 lError
= RegCreateKeyExW(hKeyEnumerator
,
1534 REG_OPTION_NON_VOLATILE
,
1540 /* Close the enumerator key */
1541 RegCloseKey(hKeyEnumerator
);
1543 if (lError
!= ERROR_SUCCESS
)
1545 return CR_REGISTRY_ERROR
;
1548 /* Try to open the instance key and fail if it exists */
1549 lError
= RegOpenKeyExW(hKeyDevice
,
1554 if (lError
== ERROR_SUCCESS
)
1556 DPRINT1("Instance %S already exists!\n", szInstance
);
1557 RegCloseKey(hKeyInstance
);
1558 RegCloseKey(hKeyDevice
);
1559 return CR_ALREADY_SUCH_DEVINST
;
1562 /* Create a new instance key */
1563 lError
= RegCreateKeyExW(hKeyDevice
,
1567 REG_OPTION_NON_VOLATILE
,
1573 /* Close the device key */
1574 RegCloseKey(hKeyDevice
);
1576 if (lError
!= ERROR_SUCCESS
)
1578 return CR_REGISTRY_ERROR
;
1581 /* Create the 'Control' sub key */
1582 lError
= RegCreateKeyExW(hKeyInstance
,
1586 REG_OPTION_NON_VOLATILE
,
1591 if (lError
== ERROR_SUCCESS
)
1593 RegCloseKey(hKeyControl
);
1596 RegCloseKey(hKeyInstance
);
1598 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1603 DWORD
PNP_CreateDevInst(
1606 LPWSTR pszParentDeviceID
,
1607 PNP_RPC_STRING_LEN ulLength
,
1610 CONFIGRET ret
= CR_SUCCESS
;
1612 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1614 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1617 DPRINT1("CM_CREATE_DEVNODE_GENERATE_ID support not implemented yet!\n", ret
);
1618 ret
= CR_CALL_NOT_IMPLEMENTED
;
1622 /* Create the device instance */
1623 ret
= CreateDeviceInstance(pszDeviceID
);
1626 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1633 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1634 LPWSTR pszDeviceInstanceSource
)
1636 DPRINT("MoveDeviceInstance: not implemented\n");
1638 return CR_CALL_NOT_IMPLEMENTED
;
1643 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1646 DPRINT("SetupDeviceInstance: not implemented\n");
1648 return CR_CALL_NOT_IMPLEMENTED
;
1653 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1655 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1656 CONFIGRET ret
= CR_SUCCESS
;
1659 DPRINT("Enable device instance\n");
1661 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1662 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1663 if (!NT_SUCCESS(Status
))
1664 ret
= NtStatusToCrError(Status
);
1671 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1673 DPRINT("DisableDeviceInstance: not implemented\n");
1675 return CR_CALL_NOT_IMPLEMENTED
;
1680 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1682 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1684 return CR_CALL_NOT_IMPLEMENTED
;
1689 DWORD
PNP_DeviceInstanceAction(
1693 LPWSTR pszDeviceInstance1
,
1694 LPWSTR pszDeviceInstance2
)
1696 CONFIGRET ret
= CR_SUCCESS
;
1698 UNREFERENCED_PARAMETER(hBinding
);
1700 DPRINT("PNP_DeviceInstanceAction() called\n");
1704 case PNP_DEVINST_MOVE
:
1705 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1706 pszDeviceInstance2
);
1709 case PNP_DEVINST_SETUP
:
1710 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1714 case PNP_DEVINST_ENABLE
:
1715 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1718 case PNP_DEVINST_DISABLE
:
1719 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1722 case PNP_DEVINST_REENUMERATE
:
1723 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
1727 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
1728 ret
= CR_CALL_NOT_IMPLEMENTED
;
1731 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1738 DWORD
PNP_GetDeviceStatus(
1745 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1746 CONFIGRET ret
= CR_SUCCESS
;
1749 UNREFERENCED_PARAMETER(hBinding
);
1750 UNREFERENCED_PARAMETER(ulFlags
);
1752 DPRINT("PNP_GetDeviceStatus() called\n");
1754 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1756 PlugPlayData
.Operation
= 0; /* Get status */
1758 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1759 (PVOID
)&PlugPlayData
,
1760 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1761 if (NT_SUCCESS(Status
))
1763 *pulStatus
= PlugPlayData
.DeviceStatus
;
1764 *pulProblem
= PlugPlayData
.DeviceProblem
;
1768 ret
= NtStatusToCrError(Status
);
1771 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1778 DWORD
PNP_SetDeviceProblem(
1785 return CR_CALL_NOT_IMPLEMENTED
;
1790 DWORD
PNP_DisableDevInst(
1793 PPNP_VETO_TYPE pVetoType
,
1799 return CR_CALL_NOT_IMPLEMENTED
;
1803 DWORD
PNP_UninstallDevInst(
1809 return CR_CALL_NOT_IMPLEMENTED
;
1814 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1820 lpPtr
= lpDeviceIdList
;
1823 dwLength
= wcslen(lpPtr
);
1824 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1827 lpPtr
+= (dwLength
+ 1);
1835 AppendDeviceId(LPWSTR lpDeviceIdList
,
1836 LPDWORD lpDeviceIdListSize
,
1842 dwLen
= wcslen(lpDeviceId
);
1843 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1845 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1847 dwPos
+= (dwLen
+ 1);
1849 lpDeviceIdList
[dwPos
] = 0;
1851 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1862 CONFIGRET ret
= CR_SUCCESS
;
1865 DWORD dwDeviceIdListSize
;
1866 DWORD dwNewDeviceIdSize
;
1867 WCHAR
* pszDeviceIdList
= NULL
;
1869 UNREFERENCED_PARAMETER(hBinding
);
1871 DPRINT("PNP_AddID() called\n");
1872 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
1873 DPRINT(" DeviceId: %S\n", pszID
);
1874 DPRINT(" Flags: %lx\n", ulFlags
);
1876 if (RegOpenKeyExW(hEnumKey
,
1879 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1880 &hDeviceKey
) != ERROR_SUCCESS
)
1882 DPRINT("Failed to open the device key!\n");
1883 return CR_INVALID_DEVNODE
;
1886 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1888 if (RegQueryValueExW(hDeviceKey
,
1893 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1895 DPRINT("Failed to query the desired ID string!\n");
1896 ret
= CR_REGISTRY_ERROR
;
1900 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
1901 if (!dwNewDeviceIdSize
)
1903 ret
= CR_INVALID_POINTER
;
1907 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
1909 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
1910 if (!pszDeviceIdList
)
1912 DPRINT("Failed to allocate memory for the desired ID string!\n");
1913 ret
= CR_OUT_OF_MEMORY
;
1917 if (RegQueryValueExW(hDeviceKey
,
1921 (LPBYTE
)pszDeviceIdList
,
1922 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1924 DPRINT("Failed to query the desired ID string!\n");
1925 ret
= CR_REGISTRY_ERROR
;
1929 /* Check whether the device ID is already in use */
1930 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
1932 DPRINT("Device ID was found in the ID string!\n");
1937 /* Append the Device ID */
1938 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
1940 if (RegSetValueExW(hDeviceKey
,
1944 (LPBYTE
)pszDeviceIdList
,
1945 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1947 DPRINT("Failed to set the desired ID string!\n");
1948 ret
= CR_REGISTRY_ERROR
;
1952 RegCloseKey(hDeviceKey
);
1953 if (pszDeviceIdList
)
1954 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
1956 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1963 DWORD
PNP_RegisterDriver(
1969 return CR_CALL_NOT_IMPLEMENTED
;
1974 DWORD
PNP_QueryRemove(
1977 PPNP_VETO_TYPE pVetoType
,
1983 return CR_CALL_NOT_IMPLEMENTED
;
1988 DWORD
PNP_RequestDeviceEject(
1991 PPNP_VETO_TYPE pVetoType
,
1997 return CR_CALL_NOT_IMPLEMENTED
;
2002 PNP_IsDockStationPresent(handle_t hBinding
,
2009 CONFIGRET ret
= CR_SUCCESS
;
2011 UNREFERENCED_PARAMETER(hBinding
);
2013 DPRINT1("PNP_IsDockStationPresent() called\n");
2017 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2021 &hKey
) != ERROR_SUCCESS
)
2022 return CR_REGISTRY_ERROR
;
2024 dwSize
= sizeof(DWORD
);
2025 if (RegQueryValueExW(hKey
,
2030 &dwSize
) != ERROR_SUCCESS
)
2031 ret
= CR_REGISTRY_ERROR
;
2035 if (ret
== CR_SUCCESS
)
2037 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2039 ret
= CR_REGISTRY_ERROR
;
2041 else if (dwValue
!= 0)
2047 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2054 DWORD
PNP_RequestEjectPC(
2058 return CR_CALL_NOT_IMPLEMENTED
;
2063 DWORD
PNP_HwProfFlags(
2069 PPNP_VETO_TYPE pVetoType
,
2074 CONFIGRET ret
= CR_SUCCESS
;
2075 WCHAR szKeyName
[MAX_PATH
];
2080 UNREFERENCED_PARAMETER(hBinding
);
2082 DPRINT("PNP_HwProfFlags() called\n");
2087 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2092 L
"System\\CurrentControlSet\\HardwareProfiles\\%04u\\System\\CurrentControlSet\\Enum",
2096 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2100 &hKey
) != ERROR_SUCCESS
)
2101 return CR_REGISTRY_ERROR
;
2103 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2105 if (RegOpenKeyExW(hKey
,
2109 &hDeviceKey
) != ERROR_SUCCESS
)
2115 dwSize
= sizeof(DWORD
);
2116 if (!RegQueryValueExW(hDeviceKey
,
2121 &dwSize
) != ERROR_SUCCESS
)
2126 RegCloseKey(hDeviceKey
);
2129 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2131 /* FIXME: not implemented yet */
2132 ret
= CR_CALL_NOT_IMPLEMENTED
;
2142 DWORD
PNP_GetHwProfInfo(
2145 HWPROFILEINFO
*pHWProfileInfo
,
2146 DWORD ulProfileInfoSize
,
2149 WCHAR szProfileName
[5];
2150 HKEY hKeyConfig
= NULL
;
2151 HKEY hKeyProfiles
= NULL
;
2152 HKEY hKeyProfile
= NULL
;
2153 DWORD dwDisposition
;
2156 CONFIGRET ret
= CR_SUCCESS
;
2158 UNREFERENCED_PARAMETER(hBinding
);
2160 DPRINT("PNP_GetHwProfInfo() called\n");
2162 if (ulProfileInfoSize
== 0)
2164 ret
= CR_INVALID_DATA
;
2170 ret
= CR_INVALID_FLAG
;
2174 /* Initialize the profile information */
2175 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2176 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2177 pHWProfileInfo
->HWPI_dwFlags
= 0;
2179 /* Open the 'IDConfigDB' key */
2180 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2181 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2184 REG_OPTION_NON_VOLATILE
,
2189 if (lError
!= ERROR_SUCCESS
)
2191 ret
= CR_REGISTRY_ERROR
;
2195 /* Open the 'Hardware Profiles' subkey */
2196 lError
= RegCreateKeyExW(hKeyConfig
,
2197 L
"Hardware Profiles",
2200 REG_OPTION_NON_VOLATILE
,
2201 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2205 if (lError
!= ERROR_SUCCESS
)
2207 ret
= CR_REGISTRY_ERROR
;
2211 if (ulIndex
== (ULONG
)-1)
2213 dwSize
= sizeof(ULONG
);
2214 lError
= RegQueryValueExW(hKeyConfig
,
2218 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2220 if (lError
!= ERROR_SUCCESS
)
2222 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2223 ret
= CR_REGISTRY_ERROR
;
2229 /* FIXME: not implemented yet */
2230 ret
= CR_CALL_NOT_IMPLEMENTED
;
2234 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2236 lError
= RegOpenKeyExW(hKeyProfiles
,
2241 if (lError
!= ERROR_SUCCESS
)
2243 ret
= CR_REGISTRY_ERROR
;
2247 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2248 lError
= RegQueryValueExW(hKeyProfile
,
2252 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2254 if (lError
!= ERROR_SUCCESS
)
2256 ret
= CR_REGISTRY_ERROR
;
2261 if (hKeyProfile
!= NULL
)
2262 RegCloseKey(hKeyProfile
);
2264 if (hKeyProfiles
!= NULL
)
2265 RegCloseKey(hKeyProfiles
);
2267 if (hKeyConfig
!= NULL
)
2268 RegCloseKey(hKeyConfig
);
2275 DWORD
PNP_AddEmptyLogConf(
2279 DWORD
*pulLogConfTag
,
2283 return CR_CALL_NOT_IMPLEMENTED
;
2288 DWORD
PNP_FreeLogConf(
2291 DWORD ulLogConfType
,
2296 return CR_CALL_NOT_IMPLEMENTED
;
2301 DWORD
PNP_GetFirstLogConf(
2304 DWORD ulLogConfType
,
2305 DWORD
*pulLogConfTag
,
2309 return CR_CALL_NOT_IMPLEMENTED
;
2314 DWORD
PNP_GetNextLogConf(
2317 DWORD ulLogConfType
,
2323 return CR_CALL_NOT_IMPLEMENTED
;
2328 DWORD
PNP_GetLogConfPriority(
2337 return CR_CALL_NOT_IMPLEMENTED
;
2342 DWORD
PNP_AddResDes(
2346 DWORD ulLogConfType
,
2347 RESOURCEID ResourceID
,
2348 DWORD
*pulResourceTag
,
2350 PNP_RPC_BUFFER_SIZE ResourceLen
,
2354 return CR_CALL_NOT_IMPLEMENTED
;
2359 DWORD
PNP_FreeResDes(
2363 DWORD ulLogConfType
,
2364 RESOURCEID ResourceID
,
2365 DWORD ulResourceTag
,
2366 DWORD
*pulPreviousResType
,
2367 DWORD
*pulPreviousResTag
,
2371 return CR_CALL_NOT_IMPLEMENTED
;
2376 DWORD
PNP_GetNextResDes(
2380 DWORD ulLogConfType
,
2381 RESOURCEID ResourceID
,
2382 DWORD ulResourceTag
,
2383 DWORD
*pulNextResType
,
2384 DWORD
*pulNextResTag
,
2388 return CR_CALL_NOT_IMPLEMENTED
;
2393 DWORD
PNP_GetResDesData(
2397 DWORD ulLogConfType
,
2398 RESOURCEID ResourceID
,
2399 DWORD ulResourceTag
,
2401 PNP_RPC_BUFFER_SIZE BufferLen
,
2405 return CR_CALL_NOT_IMPLEMENTED
;
2410 DWORD
PNP_GetResDesDataSize(
2414 DWORD ulLogConfType
,
2415 RESOURCEID ResourceID
,
2416 DWORD ulResourceTag
,
2421 return CR_CALL_NOT_IMPLEMENTED
;
2426 DWORD
PNP_ModifyResDes(
2430 DWORD ulLogConfType
,
2431 RESOURCEID CurrentResourceID
,
2432 RESOURCEID NewResourceID
,
2433 DWORD ulResourceTag
,
2435 PNP_RPC_BUFFER_SIZE ResourceLen
,
2439 return CR_CALL_NOT_IMPLEMENTED
;
2444 DWORD
PNP_DetectResourceConflict(
2447 RESOURCEID ResourceID
,
2449 PNP_RPC_BUFFER_SIZE ResourceLen
,
2450 BOOL
*pbConflictDetected
,
2454 return CR_CALL_NOT_IMPLEMENTED
;
2459 DWORD
PNP_QueryResConfList(
2462 RESOURCEID ResourceID
,
2464 PNP_RPC_BUFFER_SIZE ResourceLen
,
2466 PNP_RPC_BUFFER_SIZE BufferLen
,
2470 return CR_CALL_NOT_IMPLEMENTED
;
2475 DWORD
PNP_SetHwProf(
2477 DWORD ulHardwareProfile
,
2481 return CR_CALL_NOT_IMPLEMENTED
;
2486 DWORD
PNP_QueryArbitratorFreeData(
2491 RESOURCEID ResourceID
,
2495 return CR_CALL_NOT_IMPLEMENTED
;
2500 DWORD
PNP_QueryArbitratorFreeSize(
2504 RESOURCEID ResourceID
,
2508 return CR_CALL_NOT_IMPLEMENTED
;
2518 return CR_CALL_NOT_IMPLEMENTED
;
2523 DWORD
PNP_RegisterNotification(
2527 return CR_CALL_NOT_IMPLEMENTED
;
2532 DWORD
PNP_UnregisterNotification(
2536 return CR_CALL_NOT_IMPLEMENTED
;
2541 DWORD
PNP_GetCustomDevProp(
2544 LPWSTR CustomPropName
,
2545 DWORD
*pulRegDataType
,
2547 PNP_RPC_STRING_LEN
*pulTransferLen
,
2548 PNP_RPC_STRING_LEN
*pulLength
,
2551 HKEY hDeviceKey
= NULL
;
2552 HKEY hParamKey
= NULL
;
2554 CONFIGRET ret
= CR_SUCCESS
;
2556 UNREFERENCED_PARAMETER(hBinding
);
2558 DPRINT("PNP_GetCustomDevProp() called\n");
2560 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2562 ret
= CR_INVALID_POINTER
;
2566 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2568 ret
= CR_INVALID_FLAG
;
2572 if (*pulLength
< *pulTransferLen
)
2573 *pulLength
= *pulTransferLen
;
2575 *pulTransferLen
= 0;
2577 lError
= RegOpenKeyExW(hEnumKey
,
2582 if (lError
!= ERROR_SUCCESS
)
2584 ret
= CR_REGISTRY_ERROR
;
2588 lError
= RegOpenKeyExW(hDeviceKey
,
2589 L
"Device Parameters",
2593 if (lError
!= ERROR_SUCCESS
)
2595 ret
= CR_REGISTRY_ERROR
;
2599 lError
= RegQueryValueExW(hParamKey
,
2605 if (lError
!= ERROR_SUCCESS
)
2607 if (lError
== ERROR_MORE_DATA
)
2609 ret
= CR_BUFFER_SMALL
;
2614 ret
= CR_NO_SUCH_VALUE
;
2619 if (ret
== CR_SUCCESS
)
2620 *pulTransferLen
= *pulLength
;
2622 if (hParamKey
!= NULL
)
2623 RegCloseKey(hParamKey
);
2625 if (hDeviceKey
!= NULL
)
2626 RegCloseKey(hDeviceKey
);
2628 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
2635 DWORD
PNP_GetVersionInternal(
2642 return CR_CALL_NOT_IMPLEMENTED
;
2647 DWORD
PNP_GetBlockedDriverInfo(
2650 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
2651 PNP_RPC_BUFFER_SIZE
*pulLength
,
2655 return CR_CALL_NOT_IMPLEMENTED
;
2660 DWORD
PNP_GetServerSideDeviceInstallFlags(
2662 DWORD
*pulSSDIFlags
,
2666 return CR_CALL_NOT_IMPLEMENTED
;
2671 DWORD
PNP_GetObjectPropKeys(
2675 LPWSTR PropertyCultureName
,
2676 PNP_PROP_COUNT
*PropertyCount
,
2677 PNP_PROP_COUNT
*TransferLen
,
2678 DEVPROPKEY
*PropertyKeys
,
2682 return CR_CALL_NOT_IMPLEMENTED
;
2687 DWORD
PNP_GetObjectProp(
2691 LPWSTR PropertyCultureName
,
2692 const DEVPROPKEY
*PropertyKey
,
2693 DEVPROPTYPE
*PropertyType
,
2694 PNP_PROP_SIZE
*PropertySize
,
2695 PNP_PROP_SIZE
*TransferLen
,
2696 BYTE
*PropertyBuffer
,
2700 return CR_CALL_NOT_IMPLEMENTED
;
2705 DWORD
PNP_SetObjectProp(
2709 LPWSTR PropertyCultureName
,
2710 const DEVPROPKEY
*PropertyKey
,
2711 DEVPROPTYPE PropertyType
,
2712 PNP_PROP_SIZE PropertySize
,
2713 BYTE
*PropertyBuffer
,
2717 return CR_CALL_NOT_IMPLEMENTED
;
2722 DWORD
PNP_InstallDevInst(
2726 return CR_CALL_NOT_IMPLEMENTED
;
2731 DWORD
PNP_ApplyPowerSettings(
2735 return CR_CALL_NOT_IMPLEMENTED
;
2740 DWORD
PNP_DriverStoreAddDriverPackage(
2744 return CR_CALL_NOT_IMPLEMENTED
;
2749 DWORD
PNP_DriverStoreDeleteDriverPackage(
2753 return CR_CALL_NOT_IMPLEMENTED
;
2758 DWORD
PNP_RegisterServiceNotification(
2762 return CR_CALL_NOT_IMPLEMENTED
;
2767 DWORD
PNP_SetActiveService(
2771 return CR_CALL_NOT_IMPLEMENTED
;
2776 DWORD
PNP_DeleteServiceDevices(
2780 return CR_CALL_NOT_IMPLEMENTED
;
2785 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
2787 BOOL DeviceInstalled
= FALSE
;
2790 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
2791 LPVOID Environment
= NULL
;
2792 PROCESS_INFORMATION ProcessInfo
;
2793 STARTUPINFOW StartupInfo
;
2797 /* The following lengths are constant (see below), they cannot overflow */
2798 WCHAR CommandLine
[116];
2799 WCHAR InstallEventName
[73];
2801 WCHAR UuidString
[39];
2803 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
2805 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
2807 if (RegOpenKeyExW(hEnumKey
,
2811 &DeviceKey
) == ERROR_SUCCESS
)
2813 if (RegQueryValueExW(DeviceKey
,
2818 NULL
) == ERROR_SUCCESS
)
2820 DPRINT("No need to install: %S\n", DeviceInstance
);
2821 RegCloseKey(DeviceKey
);
2825 RegCloseKey(DeviceKey
);
2828 DPRINT1("Installing: %S\n", DeviceInstance
);
2830 /* Create a random UUID for the named pipe */
2831 UuidCreate(&RandomUuid
);
2832 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2833 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
2834 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
2835 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
2836 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
2838 /* Create the named pipe */
2839 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
2840 wcscat(PipeName
, UuidString
);
2841 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
2843 if(hPipe
== INVALID_HANDLE_VALUE
)
2845 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
2849 /* Launch rundll32 to call ClientSideInstallW */
2850 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
2851 wcscat(CommandLine
, PipeName
);
2853 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
2854 StartupInfo
.cb
= sizeof(StartupInfo
);
2858 /* newdev has to run under the environment of the current user */
2859 if(!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
2861 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
2865 if(!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
2867 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
2873 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
2875 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
2876 (ShowWizard is only set to FALSE for these two modes) */
2877 ASSERT(!ShowWizard
);
2879 if(!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
2881 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
2886 /* Wait for the function to connect to our pipe */
2887 if(!ConnectNamedPipe(hPipe
, NULL
))
2889 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
2893 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
2894 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
2895 wcscat(InstallEventName
, UuidString
);
2897 Value
= sizeof(InstallEventName
);
2898 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2899 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
2901 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
2902 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
2903 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
2905 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
2906 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2907 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
2909 /* Wait for newdev.dll to finish processing */
2910 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
2912 /* The following check for success is probably not compatible to Windows, but should do its job */
2913 if(!GetExitCodeProcess(ProcessInfo
.hProcess
, &Value
))
2915 DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
2919 DeviceInstalled
= Value
;
2922 if(hPipe
!= INVALID_HANDLE_VALUE
)
2926 DestroyEnvironmentBlock(Environment
);
2928 if(ProcessInfo
.hProcess
)
2929 CloseHandle(ProcessInfo
.hProcess
);
2931 if(ProcessInfo
.hThread
)
2932 CloseHandle(ProcessInfo
.hThread
);
2934 DPRINT1("Success? %d\n", DeviceInstalled
);
2936 return DeviceInstalled
;
2952 return ERROR_INVALID_PARAMETER
;
2955 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
2956 if (rc
!= ERROR_SUCCESS
)
2958 if (dwType
!= REG_SZ
)
2959 return ERROR_FILE_NOT_FOUND
;
2960 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
2962 return ERROR_NOT_ENOUGH_MEMORY
;
2963 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
2964 if (rc
!= ERROR_SUCCESS
)
2966 HeapFree(GetProcessHeap(), 0, Value
);
2969 /* NULL-terminate the string */
2970 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
2973 return ERROR_SUCCESS
;
2981 DWORD regType
, active
, size
;
2985 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
2986 if (rc
!= ERROR_SUCCESS
)
2989 size
= sizeof(DWORD
);
2990 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
2991 if (rc
!= ERROR_SUCCESS
)
2993 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
2996 ret
= (active
!= 0);
3002 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3011 HKEY ControlKey
= NULL
;
3012 LPWSTR SystemStartOptions
= NULL
;
3013 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3014 BOOL ConsoleBoot
= FALSE
;
3019 L
"SYSTEM\\CurrentControlSet\\Control",
3024 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3025 if (rc
!= ERROR_SUCCESS
)
3028 /* Check for CONSOLE switch in SystemStartOptions */
3029 CurrentOption
= SystemStartOptions
;
3030 while (CurrentOption
)
3032 NextOption
= wcschr(CurrentOption
, L
' ');
3034 *NextOption
= L
'\0';
3035 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3037 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3041 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3045 if (ControlKey
!= NULL
)
3046 RegCloseKey(ControlKey
);
3047 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3052 /* Loop to install all queued devices installations */
3054 DeviceInstallThread(LPVOID lpParameter
)
3056 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3057 PSLIST_ENTRY ListEntry
;
3059 PLIST_ENTRY ListEntry
;
3061 DeviceInstallParams
* Params
;
3064 UNREFERENCED_PARAMETER(lpParameter
);
3066 WaitForSingleObject(hInstallEvent
, INFINITE
);
3068 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3072 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3073 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3075 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3078 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3080 if (ListEntry
== NULL
)
3082 SetEvent(hNoPendingInstalls
);
3083 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3087 ResetEvent(hNoPendingInstalls
);
3088 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3089 InstallDevice(Params
->DeviceIds
, showWizard
);
3098 PnpEventThread(LPVOID lpParameter
)
3100 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3103 RPC_STATUS RpcStatus
;
3105 UNREFERENCED_PARAMETER(lpParameter
);
3107 PnpEventSize
= 0x1000;
3108 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3109 if (PnpEvent
== NULL
)
3110 return ERROR_OUTOFMEMORY
;
3114 DPRINT("Calling NtGetPlugPlayEvent()\n");
3116 /* Wait for the next pnp event */
3117 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3119 /* Resize the buffer for the PnP event if it's too small. */
3120 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3122 PnpEventSize
+= 0x400;
3123 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3124 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3125 if (PnpEvent
== NULL
)
3126 return ERROR_OUTOFMEMORY
;
3130 if (!NT_SUCCESS(Status
))
3132 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3136 /* Process the pnp event */
3137 DPRINT("Received PnP Event\n");
3138 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3140 DeviceInstallParams
* Params
;
3142 DWORD DeviceIdLength
;
3144 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3146 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3149 /* Queue device install (will be dequeued by DeviceInstallThread */
3150 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3151 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3154 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3155 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3156 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3158 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3160 SetEvent(hDeviceInstallListNotEmpty
);
3164 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3166 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3169 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3171 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3173 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3175 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3177 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3179 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3181 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3183 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3185 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3187 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3189 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3191 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3195 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3196 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3197 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3198 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3199 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3202 /* Dequeue the current pnp event and signal the next one */
3203 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3206 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3208 return ERROR_SUCCESS
;
3213 UpdateServiceStatus(DWORD dwState
)
3215 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3216 ServiceStatus
.dwCurrentState
= dwState
;
3217 ServiceStatus
.dwControlsAccepted
= 0;
3218 ServiceStatus
.dwWin32ExitCode
= 0;
3219 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3220 ServiceStatus
.dwCheckPoint
= 0;
3222 if (dwState
== SERVICE_START_PENDING
||
3223 dwState
== SERVICE_STOP_PENDING
||
3224 dwState
== SERVICE_PAUSE_PENDING
||
3225 dwState
== SERVICE_CONTINUE_PENDING
)
3226 ServiceStatus
.dwWaitHint
= 10000;
3228 ServiceStatus
.dwWaitHint
= 0;
3230 SetServiceStatus(ServiceStatusHandle
,
3236 ServiceControlHandler(DWORD dwControl
,
3241 DPRINT1("ServiceControlHandler() called\n");
3245 case SERVICE_CONTROL_STOP
:
3246 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3247 /* Stop listening to RPC Messages */
3248 RpcMgmtStopServerListening(NULL
);
3249 UpdateServiceStatus(SERVICE_STOPPED
);
3250 return ERROR_SUCCESS
;
3252 case SERVICE_CONTROL_PAUSE
:
3253 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3254 UpdateServiceStatus(SERVICE_PAUSED
);
3255 return ERROR_SUCCESS
;
3257 case SERVICE_CONTROL_CONTINUE
:
3258 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3259 UpdateServiceStatus(SERVICE_RUNNING
);
3260 return ERROR_SUCCESS
;
3262 case SERVICE_CONTROL_INTERROGATE
:
3263 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3264 SetServiceStatus(ServiceStatusHandle
,
3266 return ERROR_SUCCESS
;
3268 case SERVICE_CONTROL_SHUTDOWN
:
3269 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3270 /* Stop listening to RPC Messages */
3271 RpcMgmtStopServerListening(NULL
);
3272 UpdateServiceStatus(SERVICE_STOPPED
);
3273 return ERROR_SUCCESS
;
3276 DPRINT1(" Control %lu received\n");
3277 return ERROR_CALL_NOT_IMPLEMENTED
;
3282 static VOID CALLBACK
3283 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3288 UNREFERENCED_PARAMETER(argc
);
3289 UNREFERENCED_PARAMETER(argv
);
3291 DPRINT("ServiceMain() called\n");
3293 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3294 ServiceControlHandler
,
3296 if (!ServiceStatusHandle
)
3298 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3302 UpdateServiceStatus(SERVICE_START_PENDING
);
3304 hThread
= CreateThread(NULL
,
3310 if (hThread
!= NULL
)
3311 CloseHandle(hThread
);
3313 hThread
= CreateThread(NULL
,
3319 if (hThread
!= NULL
)
3320 CloseHandle(hThread
);
3322 hThread
= CreateThread(NULL
,
3324 DeviceInstallThread
,
3328 if (hThread
!= NULL
)
3329 CloseHandle(hThread
);
3331 UpdateServiceStatus(SERVICE_RUNNING
);
3333 DPRINT("ServiceMain() done\n");
3338 wmain(int argc
, WCHAR
*argv
[])
3343 UNREFERENCED_PARAMETER(argc
);
3344 UNREFERENCED_PARAMETER(argv
);
3346 DPRINT("Umpnpmgr: main() started\n");
3348 /* We need this privilege for using CreateProcessAsUserW */
3349 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3351 hInstallEvent
= CreateEvent(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3352 if (hInstallEvent
== NULL
)
3354 dwError
= GetLastError();
3355 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3359 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
3360 if (hDeviceInstallListNotEmpty
== NULL
)
3362 dwError
= GetLastError();
3363 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3367 hNoPendingInstalls
= CreateEventW(NULL
,
3370 L
"Global\\PnP_No_Pending_Install_Events");
3371 if (hNoPendingInstalls
== NULL
)
3373 dwError
= GetLastError();
3374 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3378 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3379 InitializeSListHead(&DeviceInstallListHead
);
3381 InitializeListHead(&DeviceInstallListHead
);
3384 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3385 L
"System\\CurrentControlSet\\Enum",
3389 if (dwError
!= ERROR_SUCCESS
)
3391 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3395 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3396 L
"System\\CurrentControlSet\\Control\\Class",
3400 if (dwError
!= ERROR_SUCCESS
)
3402 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3406 StartServiceCtrlDispatcher(ServiceTable
);
3408 DPRINT("Umpnpmgr: main() done\n");