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
)
1616 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1617 DWORD dwInstanceNumber
;
1619 /* Generated ID is: Root\<Device ID>\<Instance number> */
1620 dwInstanceNumber
= 0;
1623 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04d",
1624 pszDeviceID
, dwInstanceNumber
);
1626 /* Try to create a device instance with this ID */
1627 ret
= CreateDeviceInstance(szGeneratedInstance
);
1631 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1633 if (ret
== CR_SUCCESS
)
1635 /* pszDeviceID is an out parameter too for generated IDs */
1636 if (wcslen(szGeneratedInstance
) > ulLength
)
1638 ret
= CR_BUFFER_SMALL
;
1642 wcscpy(pszDeviceID
, szGeneratedInstance
);
1648 /* Create the device instance */
1649 ret
= CreateDeviceInstance(pszDeviceID
);
1652 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1659 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1660 LPWSTR pszDeviceInstanceSource
)
1662 DPRINT("MoveDeviceInstance: not implemented\n");
1664 return CR_CALL_NOT_IMPLEMENTED
;
1669 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1672 DPRINT("SetupDeviceInstance: not implemented\n");
1674 return CR_CALL_NOT_IMPLEMENTED
;
1679 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1681 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1682 CONFIGRET ret
= CR_SUCCESS
;
1685 DPRINT("Enable device instance\n");
1687 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1688 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1689 if (!NT_SUCCESS(Status
))
1690 ret
= NtStatusToCrError(Status
);
1697 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1699 DPRINT("DisableDeviceInstance: not implemented\n");
1701 return CR_CALL_NOT_IMPLEMENTED
;
1706 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1708 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1710 return CR_CALL_NOT_IMPLEMENTED
;
1715 DWORD
PNP_DeviceInstanceAction(
1719 LPWSTR pszDeviceInstance1
,
1720 LPWSTR pszDeviceInstance2
)
1722 CONFIGRET ret
= CR_SUCCESS
;
1724 UNREFERENCED_PARAMETER(hBinding
);
1726 DPRINT("PNP_DeviceInstanceAction() called\n");
1730 case PNP_DEVINST_MOVE
:
1731 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1732 pszDeviceInstance2
);
1735 case PNP_DEVINST_SETUP
:
1736 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1740 case PNP_DEVINST_ENABLE
:
1741 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1744 case PNP_DEVINST_DISABLE
:
1745 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1748 case PNP_DEVINST_REENUMERATE
:
1749 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
1753 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
1754 ret
= CR_CALL_NOT_IMPLEMENTED
;
1757 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1764 DWORD
PNP_GetDeviceStatus(
1771 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1772 CONFIGRET ret
= CR_SUCCESS
;
1775 UNREFERENCED_PARAMETER(hBinding
);
1776 UNREFERENCED_PARAMETER(ulFlags
);
1778 DPRINT("PNP_GetDeviceStatus() called\n");
1780 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1782 PlugPlayData
.Operation
= 0; /* Get status */
1784 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1785 (PVOID
)&PlugPlayData
,
1786 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1787 if (NT_SUCCESS(Status
))
1789 *pulStatus
= PlugPlayData
.DeviceStatus
;
1790 *pulProblem
= PlugPlayData
.DeviceProblem
;
1794 ret
= NtStatusToCrError(Status
);
1797 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1804 DWORD
PNP_SetDeviceProblem(
1811 return CR_CALL_NOT_IMPLEMENTED
;
1816 DWORD
PNP_DisableDevInst(
1819 PPNP_VETO_TYPE pVetoType
,
1825 return CR_CALL_NOT_IMPLEMENTED
;
1829 DWORD
PNP_UninstallDevInst(
1835 return CR_CALL_NOT_IMPLEMENTED
;
1840 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1846 lpPtr
= lpDeviceIdList
;
1849 dwLength
= wcslen(lpPtr
);
1850 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1853 lpPtr
+= (dwLength
+ 1);
1861 AppendDeviceId(LPWSTR lpDeviceIdList
,
1862 LPDWORD lpDeviceIdListSize
,
1868 dwLen
= wcslen(lpDeviceId
);
1869 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1871 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1873 dwPos
+= (dwLen
+ 1);
1875 lpDeviceIdList
[dwPos
] = 0;
1877 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1888 CONFIGRET ret
= CR_SUCCESS
;
1891 DWORD dwDeviceIdListSize
;
1892 DWORD dwNewDeviceIdSize
;
1893 WCHAR
* pszDeviceIdList
= NULL
;
1895 UNREFERENCED_PARAMETER(hBinding
);
1897 DPRINT("PNP_AddID() called\n");
1898 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
1899 DPRINT(" DeviceId: %S\n", pszID
);
1900 DPRINT(" Flags: %lx\n", ulFlags
);
1902 if (RegOpenKeyExW(hEnumKey
,
1905 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1906 &hDeviceKey
) != ERROR_SUCCESS
)
1908 DPRINT("Failed to open the device key!\n");
1909 return CR_INVALID_DEVNODE
;
1912 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1914 if (RegQueryValueExW(hDeviceKey
,
1919 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1921 DPRINT("Failed to query the desired ID string!\n");
1922 ret
= CR_REGISTRY_ERROR
;
1926 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
1927 if (!dwNewDeviceIdSize
)
1929 ret
= CR_INVALID_POINTER
;
1933 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
1935 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
1936 if (!pszDeviceIdList
)
1938 DPRINT("Failed to allocate memory for the desired ID string!\n");
1939 ret
= CR_OUT_OF_MEMORY
;
1943 if (RegQueryValueExW(hDeviceKey
,
1947 (LPBYTE
)pszDeviceIdList
,
1948 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1950 DPRINT("Failed to query the desired ID string!\n");
1951 ret
= CR_REGISTRY_ERROR
;
1955 /* Check whether the device ID is already in use */
1956 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
1958 DPRINT("Device ID was found in the ID string!\n");
1963 /* Append the Device ID */
1964 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
1966 if (RegSetValueExW(hDeviceKey
,
1970 (LPBYTE
)pszDeviceIdList
,
1971 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1973 DPRINT("Failed to set the desired ID string!\n");
1974 ret
= CR_REGISTRY_ERROR
;
1978 RegCloseKey(hDeviceKey
);
1979 if (pszDeviceIdList
)
1980 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
1982 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1989 DWORD
PNP_RegisterDriver(
1995 return CR_CALL_NOT_IMPLEMENTED
;
2000 DWORD
PNP_QueryRemove(
2003 PPNP_VETO_TYPE pVetoType
,
2009 return CR_CALL_NOT_IMPLEMENTED
;
2014 DWORD
PNP_RequestDeviceEject(
2017 PPNP_VETO_TYPE pVetoType
,
2023 return CR_CALL_NOT_IMPLEMENTED
;
2028 PNP_IsDockStationPresent(handle_t hBinding
,
2035 CONFIGRET ret
= CR_SUCCESS
;
2037 UNREFERENCED_PARAMETER(hBinding
);
2039 DPRINT1("PNP_IsDockStationPresent() called\n");
2043 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2047 &hKey
) != ERROR_SUCCESS
)
2048 return CR_REGISTRY_ERROR
;
2050 dwSize
= sizeof(DWORD
);
2051 if (RegQueryValueExW(hKey
,
2056 &dwSize
) != ERROR_SUCCESS
)
2057 ret
= CR_REGISTRY_ERROR
;
2061 if (ret
== CR_SUCCESS
)
2063 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2065 ret
= CR_REGISTRY_ERROR
;
2067 else if (dwValue
!= 0)
2073 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2080 DWORD
PNP_RequestEjectPC(
2084 return CR_CALL_NOT_IMPLEMENTED
;
2089 DWORD
PNP_HwProfFlags(
2095 PPNP_VETO_TYPE pVetoType
,
2100 CONFIGRET ret
= CR_SUCCESS
;
2101 WCHAR szKeyName
[MAX_PATH
];
2106 UNREFERENCED_PARAMETER(hBinding
);
2108 DPRINT("PNP_HwProfFlags() called\n");
2113 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2118 L
"System\\CurrentControlSet\\HardwareProfiles\\%04u\\System\\CurrentControlSet\\Enum",
2122 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2126 &hKey
) != ERROR_SUCCESS
)
2127 return CR_REGISTRY_ERROR
;
2129 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2131 if (RegOpenKeyExW(hKey
,
2135 &hDeviceKey
) != ERROR_SUCCESS
)
2141 dwSize
= sizeof(DWORD
);
2142 if (!RegQueryValueExW(hDeviceKey
,
2147 &dwSize
) != ERROR_SUCCESS
)
2152 RegCloseKey(hDeviceKey
);
2155 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2157 /* FIXME: not implemented yet */
2158 ret
= CR_CALL_NOT_IMPLEMENTED
;
2168 DWORD
PNP_GetHwProfInfo(
2171 HWPROFILEINFO
*pHWProfileInfo
,
2172 DWORD ulProfileInfoSize
,
2175 WCHAR szProfileName
[5];
2176 HKEY hKeyConfig
= NULL
;
2177 HKEY hKeyProfiles
= NULL
;
2178 HKEY hKeyProfile
= NULL
;
2179 DWORD dwDisposition
;
2182 CONFIGRET ret
= CR_SUCCESS
;
2184 UNREFERENCED_PARAMETER(hBinding
);
2186 DPRINT("PNP_GetHwProfInfo() called\n");
2188 if (ulProfileInfoSize
== 0)
2190 ret
= CR_INVALID_DATA
;
2196 ret
= CR_INVALID_FLAG
;
2200 /* Initialize the profile information */
2201 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2202 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2203 pHWProfileInfo
->HWPI_dwFlags
= 0;
2205 /* Open the 'IDConfigDB' key */
2206 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2207 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2210 REG_OPTION_NON_VOLATILE
,
2215 if (lError
!= ERROR_SUCCESS
)
2217 ret
= CR_REGISTRY_ERROR
;
2221 /* Open the 'Hardware Profiles' subkey */
2222 lError
= RegCreateKeyExW(hKeyConfig
,
2223 L
"Hardware Profiles",
2226 REG_OPTION_NON_VOLATILE
,
2227 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2231 if (lError
!= ERROR_SUCCESS
)
2233 ret
= CR_REGISTRY_ERROR
;
2237 if (ulIndex
== (ULONG
)-1)
2239 dwSize
= sizeof(ULONG
);
2240 lError
= RegQueryValueExW(hKeyConfig
,
2244 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2246 if (lError
!= ERROR_SUCCESS
)
2248 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2249 ret
= CR_REGISTRY_ERROR
;
2255 /* FIXME: not implemented yet */
2256 ret
= CR_CALL_NOT_IMPLEMENTED
;
2260 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2262 lError
= RegOpenKeyExW(hKeyProfiles
,
2267 if (lError
!= ERROR_SUCCESS
)
2269 ret
= CR_REGISTRY_ERROR
;
2273 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2274 lError
= RegQueryValueExW(hKeyProfile
,
2278 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2280 if (lError
!= ERROR_SUCCESS
)
2282 ret
= CR_REGISTRY_ERROR
;
2287 if (hKeyProfile
!= NULL
)
2288 RegCloseKey(hKeyProfile
);
2290 if (hKeyProfiles
!= NULL
)
2291 RegCloseKey(hKeyProfiles
);
2293 if (hKeyConfig
!= NULL
)
2294 RegCloseKey(hKeyConfig
);
2301 DWORD
PNP_AddEmptyLogConf(
2305 DWORD
*pulLogConfTag
,
2309 return CR_CALL_NOT_IMPLEMENTED
;
2314 DWORD
PNP_FreeLogConf(
2317 DWORD ulLogConfType
,
2322 return CR_CALL_NOT_IMPLEMENTED
;
2327 DWORD
PNP_GetFirstLogConf(
2330 DWORD ulLogConfType
,
2331 DWORD
*pulLogConfTag
,
2335 return CR_CALL_NOT_IMPLEMENTED
;
2340 DWORD
PNP_GetNextLogConf(
2343 DWORD ulLogConfType
,
2349 return CR_CALL_NOT_IMPLEMENTED
;
2354 DWORD
PNP_GetLogConfPriority(
2363 return CR_CALL_NOT_IMPLEMENTED
;
2368 DWORD
PNP_AddResDes(
2372 DWORD ulLogConfType
,
2373 RESOURCEID ResourceID
,
2374 DWORD
*pulResourceTag
,
2376 PNP_RPC_BUFFER_SIZE ResourceLen
,
2380 return CR_CALL_NOT_IMPLEMENTED
;
2385 DWORD
PNP_FreeResDes(
2389 DWORD ulLogConfType
,
2390 RESOURCEID ResourceID
,
2391 DWORD ulResourceTag
,
2392 DWORD
*pulPreviousResType
,
2393 DWORD
*pulPreviousResTag
,
2397 return CR_CALL_NOT_IMPLEMENTED
;
2402 DWORD
PNP_GetNextResDes(
2406 DWORD ulLogConfType
,
2407 RESOURCEID ResourceID
,
2408 DWORD ulResourceTag
,
2409 DWORD
*pulNextResType
,
2410 DWORD
*pulNextResTag
,
2414 return CR_CALL_NOT_IMPLEMENTED
;
2419 DWORD
PNP_GetResDesData(
2423 DWORD ulLogConfType
,
2424 RESOURCEID ResourceID
,
2425 DWORD ulResourceTag
,
2427 PNP_RPC_BUFFER_SIZE BufferLen
,
2431 return CR_CALL_NOT_IMPLEMENTED
;
2436 DWORD
PNP_GetResDesDataSize(
2440 DWORD ulLogConfType
,
2441 RESOURCEID ResourceID
,
2442 DWORD ulResourceTag
,
2447 return CR_CALL_NOT_IMPLEMENTED
;
2452 DWORD
PNP_ModifyResDes(
2456 DWORD ulLogConfType
,
2457 RESOURCEID CurrentResourceID
,
2458 RESOURCEID NewResourceID
,
2459 DWORD ulResourceTag
,
2461 PNP_RPC_BUFFER_SIZE ResourceLen
,
2465 return CR_CALL_NOT_IMPLEMENTED
;
2470 DWORD
PNP_DetectResourceConflict(
2473 RESOURCEID ResourceID
,
2475 PNP_RPC_BUFFER_SIZE ResourceLen
,
2476 BOOL
*pbConflictDetected
,
2480 return CR_CALL_NOT_IMPLEMENTED
;
2485 DWORD
PNP_QueryResConfList(
2488 RESOURCEID ResourceID
,
2490 PNP_RPC_BUFFER_SIZE ResourceLen
,
2492 PNP_RPC_BUFFER_SIZE BufferLen
,
2496 return CR_CALL_NOT_IMPLEMENTED
;
2501 DWORD
PNP_SetHwProf(
2503 DWORD ulHardwareProfile
,
2507 return CR_CALL_NOT_IMPLEMENTED
;
2512 DWORD
PNP_QueryArbitratorFreeData(
2517 RESOURCEID ResourceID
,
2521 return CR_CALL_NOT_IMPLEMENTED
;
2526 DWORD
PNP_QueryArbitratorFreeSize(
2530 RESOURCEID ResourceID
,
2534 return CR_CALL_NOT_IMPLEMENTED
;
2544 return CR_CALL_NOT_IMPLEMENTED
;
2549 DWORD
PNP_RegisterNotification(
2553 return CR_CALL_NOT_IMPLEMENTED
;
2558 DWORD
PNP_UnregisterNotification(
2562 return CR_CALL_NOT_IMPLEMENTED
;
2567 DWORD
PNP_GetCustomDevProp(
2570 LPWSTR CustomPropName
,
2571 DWORD
*pulRegDataType
,
2573 PNP_RPC_STRING_LEN
*pulTransferLen
,
2574 PNP_RPC_STRING_LEN
*pulLength
,
2577 HKEY hDeviceKey
= NULL
;
2578 HKEY hParamKey
= NULL
;
2580 CONFIGRET ret
= CR_SUCCESS
;
2582 UNREFERENCED_PARAMETER(hBinding
);
2584 DPRINT("PNP_GetCustomDevProp() called\n");
2586 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2588 ret
= CR_INVALID_POINTER
;
2592 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2594 ret
= CR_INVALID_FLAG
;
2598 if (*pulLength
< *pulTransferLen
)
2599 *pulLength
= *pulTransferLen
;
2601 *pulTransferLen
= 0;
2603 lError
= RegOpenKeyExW(hEnumKey
,
2608 if (lError
!= ERROR_SUCCESS
)
2610 ret
= CR_REGISTRY_ERROR
;
2614 lError
= RegOpenKeyExW(hDeviceKey
,
2615 L
"Device Parameters",
2619 if (lError
!= ERROR_SUCCESS
)
2621 ret
= CR_REGISTRY_ERROR
;
2625 lError
= RegQueryValueExW(hParamKey
,
2631 if (lError
!= ERROR_SUCCESS
)
2633 if (lError
== ERROR_MORE_DATA
)
2635 ret
= CR_BUFFER_SMALL
;
2640 ret
= CR_NO_SUCH_VALUE
;
2645 if (ret
== CR_SUCCESS
)
2646 *pulTransferLen
= *pulLength
;
2648 if (hParamKey
!= NULL
)
2649 RegCloseKey(hParamKey
);
2651 if (hDeviceKey
!= NULL
)
2652 RegCloseKey(hDeviceKey
);
2654 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
2661 DWORD
PNP_GetVersionInternal(
2668 return CR_CALL_NOT_IMPLEMENTED
;
2673 DWORD
PNP_GetBlockedDriverInfo(
2676 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
2677 PNP_RPC_BUFFER_SIZE
*pulLength
,
2681 return CR_CALL_NOT_IMPLEMENTED
;
2686 DWORD
PNP_GetServerSideDeviceInstallFlags(
2688 DWORD
*pulSSDIFlags
,
2692 return CR_CALL_NOT_IMPLEMENTED
;
2697 DWORD
PNP_GetObjectPropKeys(
2701 LPWSTR PropertyCultureName
,
2702 PNP_PROP_COUNT
*PropertyCount
,
2703 PNP_PROP_COUNT
*TransferLen
,
2704 DEVPROPKEY
*PropertyKeys
,
2708 return CR_CALL_NOT_IMPLEMENTED
;
2713 DWORD
PNP_GetObjectProp(
2717 LPWSTR PropertyCultureName
,
2718 const DEVPROPKEY
*PropertyKey
,
2719 DEVPROPTYPE
*PropertyType
,
2720 PNP_PROP_SIZE
*PropertySize
,
2721 PNP_PROP_SIZE
*TransferLen
,
2722 BYTE
*PropertyBuffer
,
2726 return CR_CALL_NOT_IMPLEMENTED
;
2731 DWORD
PNP_SetObjectProp(
2735 LPWSTR PropertyCultureName
,
2736 const DEVPROPKEY
*PropertyKey
,
2737 DEVPROPTYPE PropertyType
,
2738 PNP_PROP_SIZE PropertySize
,
2739 BYTE
*PropertyBuffer
,
2743 return CR_CALL_NOT_IMPLEMENTED
;
2748 DWORD
PNP_InstallDevInst(
2752 return CR_CALL_NOT_IMPLEMENTED
;
2757 DWORD
PNP_ApplyPowerSettings(
2761 return CR_CALL_NOT_IMPLEMENTED
;
2766 DWORD
PNP_DriverStoreAddDriverPackage(
2770 return CR_CALL_NOT_IMPLEMENTED
;
2775 DWORD
PNP_DriverStoreDeleteDriverPackage(
2779 return CR_CALL_NOT_IMPLEMENTED
;
2784 DWORD
PNP_RegisterServiceNotification(
2788 return CR_CALL_NOT_IMPLEMENTED
;
2793 DWORD
PNP_SetActiveService(
2797 return CR_CALL_NOT_IMPLEMENTED
;
2802 DWORD
PNP_DeleteServiceDevices(
2806 return CR_CALL_NOT_IMPLEMENTED
;
2811 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
2813 BOOL DeviceInstalled
= FALSE
;
2816 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
2817 LPVOID Environment
= NULL
;
2818 PROCESS_INFORMATION ProcessInfo
;
2819 STARTUPINFOW StartupInfo
;
2823 /* The following lengths are constant (see below), they cannot overflow */
2824 WCHAR CommandLine
[116];
2825 WCHAR InstallEventName
[73];
2827 WCHAR UuidString
[39];
2829 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
2831 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
2833 if (RegOpenKeyExW(hEnumKey
,
2837 &DeviceKey
) == ERROR_SUCCESS
)
2839 if (RegQueryValueExW(DeviceKey
,
2844 NULL
) == ERROR_SUCCESS
)
2846 DPRINT("No need to install: %S\n", DeviceInstance
);
2847 RegCloseKey(DeviceKey
);
2851 RegCloseKey(DeviceKey
);
2854 DPRINT1("Installing: %S\n", DeviceInstance
);
2856 /* Create a random UUID for the named pipe */
2857 UuidCreate(&RandomUuid
);
2858 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2859 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
2860 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
2861 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
2862 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
2864 /* Create the named pipe */
2865 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
2866 wcscat(PipeName
, UuidString
);
2867 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
2869 if(hPipe
== INVALID_HANDLE_VALUE
)
2871 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
2875 /* Launch rundll32 to call ClientSideInstallW */
2876 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
2877 wcscat(CommandLine
, PipeName
);
2879 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
2880 StartupInfo
.cb
= sizeof(StartupInfo
);
2884 /* newdev has to run under the environment of the current user */
2885 if(!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
2887 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
2891 if(!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
2893 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
2899 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
2901 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
2902 (ShowWizard is only set to FALSE for these two modes) */
2903 ASSERT(!ShowWizard
);
2905 if(!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
2907 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
2912 /* Wait for the function to connect to our pipe */
2913 if(!ConnectNamedPipe(hPipe
, NULL
))
2915 if (GetLastError() != ERROR_PIPE_CONNECTED
)
2917 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
2922 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
2923 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
2924 wcscat(InstallEventName
, UuidString
);
2926 Value
= sizeof(InstallEventName
);
2927 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2928 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
2930 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
2931 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
2932 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
2934 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
2935 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2936 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
2938 /* Wait for newdev.dll to finish processing */
2939 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
2941 /* The following check for success is probably not compatible to Windows, but should do its job */
2942 if(!GetExitCodeProcess(ProcessInfo
.hProcess
, &Value
))
2944 DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
2948 DeviceInstalled
= Value
;
2951 if(hPipe
!= INVALID_HANDLE_VALUE
)
2955 DestroyEnvironmentBlock(Environment
);
2957 if(ProcessInfo
.hProcess
)
2958 CloseHandle(ProcessInfo
.hProcess
);
2960 if(ProcessInfo
.hThread
)
2961 CloseHandle(ProcessInfo
.hThread
);
2963 DPRINT1("Success? %d\n", DeviceInstalled
);
2965 return DeviceInstalled
;
2981 return ERROR_INVALID_PARAMETER
;
2984 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
2985 if (rc
!= ERROR_SUCCESS
)
2987 if (dwType
!= REG_SZ
)
2988 return ERROR_FILE_NOT_FOUND
;
2989 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
2991 return ERROR_NOT_ENOUGH_MEMORY
;
2992 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
2993 if (rc
!= ERROR_SUCCESS
)
2995 HeapFree(GetProcessHeap(), 0, Value
);
2998 /* NULL-terminate the string */
2999 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3002 return ERROR_SUCCESS
;
3010 DWORD regType
, active
, size
;
3014 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3015 if (rc
!= ERROR_SUCCESS
)
3018 size
= sizeof(DWORD
);
3019 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3020 if (rc
!= ERROR_SUCCESS
)
3022 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3025 ret
= (active
!= 0);
3031 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3040 HKEY ControlKey
= NULL
;
3041 LPWSTR SystemStartOptions
= NULL
;
3042 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3043 BOOL ConsoleBoot
= FALSE
;
3048 L
"SYSTEM\\CurrentControlSet\\Control",
3053 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3054 if (rc
!= ERROR_SUCCESS
)
3057 /* Check for CONSOLE switch in SystemStartOptions */
3058 CurrentOption
= SystemStartOptions
;
3059 while (CurrentOption
)
3061 NextOption
= wcschr(CurrentOption
, L
' ');
3063 *NextOption
= L
'\0';
3064 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3066 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3070 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3074 if (ControlKey
!= NULL
)
3075 RegCloseKey(ControlKey
);
3076 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3081 /* Loop to install all queued devices installations */
3083 DeviceInstallThread(LPVOID lpParameter
)
3085 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3086 PSLIST_ENTRY ListEntry
;
3088 PLIST_ENTRY ListEntry
;
3090 DeviceInstallParams
* Params
;
3093 UNREFERENCED_PARAMETER(lpParameter
);
3095 WaitForSingleObject(hInstallEvent
, INFINITE
);
3097 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3101 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3102 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3104 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3107 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3109 if (ListEntry
== NULL
)
3111 SetEvent(hNoPendingInstalls
);
3112 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3116 ResetEvent(hNoPendingInstalls
);
3117 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3118 InstallDevice(Params
->DeviceIds
, showWizard
);
3127 PnpEventThread(LPVOID lpParameter
)
3129 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3132 RPC_STATUS RpcStatus
;
3134 UNREFERENCED_PARAMETER(lpParameter
);
3136 PnpEventSize
= 0x1000;
3137 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3138 if (PnpEvent
== NULL
)
3139 return ERROR_OUTOFMEMORY
;
3143 DPRINT("Calling NtGetPlugPlayEvent()\n");
3145 /* Wait for the next pnp event */
3146 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3148 /* Resize the buffer for the PnP event if it's too small. */
3149 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3151 PnpEventSize
+= 0x400;
3152 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3153 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3154 if (PnpEvent
== NULL
)
3155 return ERROR_OUTOFMEMORY
;
3159 if (!NT_SUCCESS(Status
))
3161 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3165 /* Process the pnp event */
3166 DPRINT("Received PnP Event\n");
3167 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3169 DeviceInstallParams
* Params
;
3171 DWORD DeviceIdLength
;
3173 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3175 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3178 /* Queue device install (will be dequeued by DeviceInstallThread */
3179 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3180 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3183 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3184 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3185 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3187 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3189 SetEvent(hDeviceInstallListNotEmpty
);
3193 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3195 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3198 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3200 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3202 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3204 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3206 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3208 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3210 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3212 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3214 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3216 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3218 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3220 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3224 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3225 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3226 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3227 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3228 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3231 /* Dequeue the current pnp event and signal the next one */
3232 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3235 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3237 return ERROR_SUCCESS
;
3242 UpdateServiceStatus(DWORD dwState
)
3244 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3245 ServiceStatus
.dwCurrentState
= dwState
;
3246 ServiceStatus
.dwControlsAccepted
= 0;
3247 ServiceStatus
.dwWin32ExitCode
= 0;
3248 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3249 ServiceStatus
.dwCheckPoint
= 0;
3251 if (dwState
== SERVICE_START_PENDING
||
3252 dwState
== SERVICE_STOP_PENDING
||
3253 dwState
== SERVICE_PAUSE_PENDING
||
3254 dwState
== SERVICE_CONTINUE_PENDING
)
3255 ServiceStatus
.dwWaitHint
= 10000;
3257 ServiceStatus
.dwWaitHint
= 0;
3259 SetServiceStatus(ServiceStatusHandle
,
3265 ServiceControlHandler(DWORD dwControl
,
3270 DPRINT1("ServiceControlHandler() called\n");
3274 case SERVICE_CONTROL_STOP
:
3275 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3276 /* Stop listening to RPC Messages */
3277 RpcMgmtStopServerListening(NULL
);
3278 UpdateServiceStatus(SERVICE_STOPPED
);
3279 return ERROR_SUCCESS
;
3281 case SERVICE_CONTROL_PAUSE
:
3282 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3283 UpdateServiceStatus(SERVICE_PAUSED
);
3284 return ERROR_SUCCESS
;
3286 case SERVICE_CONTROL_CONTINUE
:
3287 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3288 UpdateServiceStatus(SERVICE_RUNNING
);
3289 return ERROR_SUCCESS
;
3291 case SERVICE_CONTROL_INTERROGATE
:
3292 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3293 SetServiceStatus(ServiceStatusHandle
,
3295 return ERROR_SUCCESS
;
3297 case SERVICE_CONTROL_SHUTDOWN
:
3298 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3299 /* Stop listening to RPC Messages */
3300 RpcMgmtStopServerListening(NULL
);
3301 UpdateServiceStatus(SERVICE_STOPPED
);
3302 return ERROR_SUCCESS
;
3305 DPRINT1(" Control %lu received\n");
3306 return ERROR_CALL_NOT_IMPLEMENTED
;
3311 static VOID CALLBACK
3312 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3317 UNREFERENCED_PARAMETER(argc
);
3318 UNREFERENCED_PARAMETER(argv
);
3320 DPRINT("ServiceMain() called\n");
3322 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3323 ServiceControlHandler
,
3325 if (!ServiceStatusHandle
)
3327 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3331 UpdateServiceStatus(SERVICE_START_PENDING
);
3333 hThread
= CreateThread(NULL
,
3339 if (hThread
!= NULL
)
3340 CloseHandle(hThread
);
3342 hThread
= CreateThread(NULL
,
3348 if (hThread
!= NULL
)
3349 CloseHandle(hThread
);
3351 hThread
= CreateThread(NULL
,
3353 DeviceInstallThread
,
3357 if (hThread
!= NULL
)
3358 CloseHandle(hThread
);
3360 UpdateServiceStatus(SERVICE_RUNNING
);
3362 DPRINT("ServiceMain() done\n");
3367 wmain(int argc
, WCHAR
*argv
[])
3372 UNREFERENCED_PARAMETER(argc
);
3373 UNREFERENCED_PARAMETER(argv
);
3375 DPRINT("Umpnpmgr: main() started\n");
3377 /* We need this privilege for using CreateProcessAsUserW */
3378 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3380 hInstallEvent
= CreateEvent(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3381 if (hInstallEvent
== NULL
)
3383 dwError
= GetLastError();
3384 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3388 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
3389 if (hDeviceInstallListNotEmpty
== NULL
)
3391 dwError
= GetLastError();
3392 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3396 hNoPendingInstalls
= CreateEventW(NULL
,
3399 L
"Global\\PnP_No_Pending_Install_Events");
3400 if (hNoPendingInstalls
== NULL
)
3402 dwError
= GetLastError();
3403 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3407 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3408 InitializeSListHead(&DeviceInstallListHead
);
3410 InitializeListHead(&DeviceInstallListHead
);
3413 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3414 L
"System\\CurrentControlSet\\Enum",
3418 if (dwError
!= ERROR_SUCCESS
)
3420 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3424 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3425 L
"System\\CurrentControlSet\\Control\\Class",
3429 if (dwError
!= ERROR_SUCCESS
)
3431 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3435 StartServiceCtrlDispatcher(ServiceTable
);
3437 DPRINT("Umpnpmgr: main() done\n");