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>
53 /* GLOBALS ******************************************************************/
55 static VOID CALLBACK
ServiceMain(DWORD argc
, LPWSTR
*argv
);
56 static WCHAR ServiceName
[] = L
"PlugPlay";
57 static SERVICE_TABLE_ENTRYW ServiceTable
[] =
59 {ServiceName
, ServiceMain
},
63 static SERVICE_STATUS_HANDLE ServiceStatusHandle
;
64 static SERVICE_STATUS ServiceStatus
;
66 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
68 static HKEY hEnumKey
= NULL
;
69 static HKEY hClassKey
= NULL
;
71 static HANDLE hUserToken
= NULL
;
72 static HANDLE hInstallEvent
= NULL
;
73 static HANDLE hNoPendingInstalls
= NULL
;
75 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
76 static SLIST_HEADER DeviceInstallListHead
;
78 static LIST_ENTRY DeviceInstallListHead
;
80 static HANDLE hDeviceInstallListNotEmpty
;
84 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
85 SLIST_ENTRY ListEntry
;
90 } DeviceInstallParams
;
92 /* FUNCTIONS *****************************************************************/
95 RpcServerThread(LPVOID lpParameter
)
98 BOOLEAN RegisteredProtSeq
= FALSE
;
100 UNREFERENCED_PARAMETER(lpParameter
);
102 DPRINT("RpcServerThread() called\n");
105 /* XP-compatible protocol sequence/endpoint */
106 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
109 NULL
); // Security descriptor
110 if (Status
== RPC_S_OK
)
111 RegisteredProtSeq
= TRUE
;
113 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
116 /* Vista-compatible protocol sequence/endpoint */
117 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
120 NULL
); // Security descriptor
121 if (Status
== RPC_S_OK
)
122 RegisteredProtSeq
= TRUE
;
124 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
126 /* Make sure there's a usable endpoint */
127 if (RegisteredProtSeq
== FALSE
)
130 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
133 if (Status
!= RPC_S_OK
)
135 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
139 Status
= RpcServerListen(1,
142 if (Status
!= RPC_S_OK
)
144 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
148 /* ROS HACK (this should never happen...) */
149 DPRINT1("*** Other devices won't be installed correctly. If something\n");
150 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
152 DPRINT("RpcServerThread() done\n");
158 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
160 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
164 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
166 HeapFree(GetProcessHeap(), 0, ptr
);
170 static CONFIGRET WINAPI
171 NtStatusToCrError(NTSTATUS Status
)
175 case STATUS_NO_SUCH_DEVICE
:
176 return CR_NO_SUCH_DEVINST
;
179 /* FIXME: add more mappings */
180 DPRINT1("Unable to map status 0x%08lx\n", Status
);
187 DWORD
PNP_Disconnect(
190 UNREFERENCED_PARAMETER(hBinding
);
199 UNREFERENCED_PARAMETER(hBinding
);
205 DWORD
PNP_GetVersion(
209 UNREFERENCED_PARAMETER(hBinding
);
217 DWORD
PNP_GetGlobalState(
222 UNREFERENCED_PARAMETER(hBinding
);
223 UNREFERENCED_PARAMETER(ulFlags
);
225 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
231 DWORD
PNP_InitDetection(
234 UNREFERENCED_PARAMETER(hBinding
);
236 DPRINT("PNP_InitDetection() called\n");
242 DWORD
PNP_ReportLogOn(
247 DWORD ReturnValue
= CR_FAILURE
;
250 UNREFERENCED_PARAMETER(hBinding
);
251 UNREFERENCED_PARAMETER(Admin
);
253 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
255 /* Get the users token */
256 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
260 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
266 CloseHandle(hUserToken
);
270 if(!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
272 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
276 /* Trigger the installer thread */
278 SetEvent(hInstallEvent
);
280 ReturnValue
= CR_SUCCESS
;
284 CloseHandle(hProcess
);
291 DWORD
PNP_ValidateDeviceInstance(
296 CONFIGRET ret
= CR_SUCCESS
;
297 HKEY hDeviceKey
= NULL
;
299 UNREFERENCED_PARAMETER(hBinding
);
300 UNREFERENCED_PARAMETER(ulFlags
);
302 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
305 if (RegOpenKeyExW(hEnumKey
,
311 DPRINT("Could not open the Device Key!\n");
312 ret
= CR_NO_SUCH_DEVNODE
;
316 /* FIXME: add more tests */
319 if (hDeviceKey
!= NULL
)
320 RegCloseKey(hDeviceKey
);
322 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
329 DWORD
PNP_GetRootDeviceInstance(
332 PNP_RPC_STRING_LEN ulLength
)
334 CONFIGRET ret
= CR_SUCCESS
;
336 UNREFERENCED_PARAMETER(hBinding
);
338 DPRINT("PNP_GetRootDeviceInstance() called\n");
342 ret
= CR_INVALID_POINTER
;
345 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
347 ret
= CR_BUFFER_SMALL
;
355 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
362 DWORD
PNP_GetRelatedDeviceInstance(
364 DWORD ulRelationship
,
366 LPWSTR pRelatedDeviceId
,
367 PNP_RPC_STRING_LEN
*pulLength
,
370 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
371 CONFIGRET ret
= CR_SUCCESS
;
374 UNREFERENCED_PARAMETER(hBinding
);
375 UNREFERENCED_PARAMETER(ulFlags
);
377 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
378 DPRINT(" Relationship %ld\n", ulRelationship
);
379 DPRINT(" DeviceId %S\n", pDeviceID
);
381 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
384 PlugPlayData
.Relation
= ulRelationship
;
386 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
387 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
389 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
390 (PVOID
)&PlugPlayData
,
391 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
392 if (!NT_SUCCESS(Status
))
394 ret
= NtStatusToCrError(Status
);
397 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
398 if (ret
== CR_SUCCESS
)
400 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
408 DWORD
PNP_EnumerateSubKeys(
413 PNP_RPC_STRING_LEN ulLength
,
414 PNP_RPC_STRING_LEN
*pulRequiredLen
,
417 CONFIGRET ret
= CR_SUCCESS
;
421 UNREFERENCED_PARAMETER(hBinding
);
422 UNREFERENCED_PARAMETER(ulFlags
);
424 DPRINT("PNP_EnumerateSubKeys() called\n");
428 case PNP_ENUMERATOR_SUBKEYS
:
432 case PNP_CLASS_SUBKEYS
:
440 *pulRequiredLen
= ulLength
;
441 dwError
= RegEnumKeyExW(hKey
,
449 if (dwError
!= ERROR_SUCCESS
)
451 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
458 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
465 DWORD
PNP_GetDeviceList(
469 PNP_RPC_STRING_LEN
*pulLength
,
473 return CR_CALL_NOT_IMPLEMENTED
;
478 DWORD
PNP_GetDeviceListSize(
481 PNP_RPC_BUFFER_SIZE
*pulLen
,
485 return CR_CALL_NOT_IMPLEMENTED
;
496 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
497 CONFIGRET ret
= CR_SUCCESS
;
500 UNREFERENCED_PARAMETER(hBinding
);
501 UNREFERENCED_PARAMETER(ulFlags
);
503 DPRINT("PNP_GetDepth() called\n");
505 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
508 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
509 (PVOID
)&PlugPlayData
,
510 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
511 if (NT_SUCCESS(Status
))
513 *pulDepth
= PlugPlayData
.Depth
;
517 ret
= NtStatusToCrError(Status
);
520 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
527 DWORD
PNP_GetDeviceRegProp(
531 DWORD
*pulRegDataType
,
533 PNP_PROP_SIZE
*pulTransferLen
,
534 PNP_PROP_SIZE
*pulLength
,
537 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
538 CONFIGRET ret
= CR_SUCCESS
;
539 LPWSTR lpValueName
= NULL
;
544 UNREFERENCED_PARAMETER(hBinding
);
546 DPRINT("PNP_GetDeviceRegProp() called\n");
548 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
550 ret
= CR_INVALID_POINTER
;
556 ret
= CR_INVALID_FLAG
;
560 /* FIXME: Check pDeviceID */
562 if (*pulLength
< *pulTransferLen
)
563 *pulLength
= *pulTransferLen
;
569 case CM_DRP_DEVICEDESC
:
570 lpValueName
= L
"DeviceDesc";
573 case CM_DRP_HARDWAREID
:
574 lpValueName
= L
"HardwareID";
577 case CM_DRP_COMPATIBLEIDS
:
578 lpValueName
= L
"CompatibleIDs";
582 lpValueName
= L
"Service";
586 lpValueName
= L
"Class";
589 case CM_DRP_CLASSGUID
:
590 lpValueName
= L
"ClassGUID";
594 lpValueName
= L
"Driver";
597 case CM_DRP_CONFIGFLAGS
:
598 lpValueName
= L
"ConfigFlags";
602 lpValueName
= L
"Mfg";
605 case CM_DRP_FRIENDLYNAME
:
606 lpValueName
= L
"FriendlyName";
609 case CM_DRP_LOCATION_INFORMATION
:
610 lpValueName
= L
"LocationInformation";
613 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
617 case CM_DRP_CAPABILITIES
:
618 lpValueName
= L
"Capabilities";
621 case CM_DRP_UI_NUMBER
:
625 case CM_DRP_UPPERFILTERS
:
626 lpValueName
= L
"UpperFilters";
629 case CM_DRP_LOWERFILTERS
:
630 lpValueName
= L
"LowerFilters";
633 case CM_DRP_BUSTYPEGUID
:
637 case CM_DRP_LEGACYBUSTYPE
:
641 case CM_DRP_BUSNUMBER
:
645 case CM_DRP_ENUMERATOR_NAME
:
649 case CM_DRP_SECURITY
:
650 lpValueName
= L
"Security";
654 lpValueName
= L
"DeviceType";
657 case CM_DRP_EXCLUSIVE
:
658 lpValueName
= L
"Exclusive";
661 case CM_DRP_CHARACTERISTICS
:
662 lpValueName
= L
"DeviceCharacteristics";
669 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
670 lpValueName
= L
"UINumberDescFormat";
673 case CM_DRP_DEVICE_POWER_DATA
:
677 case CM_DRP_REMOVAL_POLICY
:
681 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
685 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
686 lpValueName
= L
"RemovalPolicy";
689 case CM_DRP_INSTALL_STATE
:
693 #if (WINVER >= _WIN32_WINNT_WS03)
694 case CM_DRP_LOCATION_PATHS
:
699 #if (WINVER >= _WIN32_WINNT_WIN7)
700 case CM_DRP_BASE_CONTAINERID
:
706 ret
= CR_INVALID_PROPERTY
;
710 DPRINT("Value name: %S\n", lpValueName
);
714 /* Retrieve information from the Registry */
715 lError
= RegOpenKeyExW(hEnumKey
,
720 if (lError
!= ERROR_SUCCESS
)
724 ret
= CR_INVALID_DEVNODE
;
728 lError
= RegQueryValueExW(hKey
,
734 if (lError
!= ERROR_SUCCESS
)
736 if (lError
== ERROR_MORE_DATA
)
738 ret
= CR_BUFFER_SMALL
;
743 ret
= CR_NO_SUCH_VALUE
;
749 /* Retrieve information from the Device Node */
750 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
752 PlugPlayData
.Buffer
= Buffer
;
753 PlugPlayData
.BufferSize
= *pulLength
;
757 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
758 PlugPlayData
.Property
= 0xb; // DevicePropertyPhysicalDeviceObjectName;
761 case CM_DRP_UI_NUMBER
:
762 PlugPlayData
.Property
= 0x11; // DevicePropertyUINumber;
765 case CM_DRP_BUSTYPEGUID
:
766 PlugPlayData
.Property
= 0xc; // DevicePropertyBusTypeGuid;
769 case CM_DRP_LEGACYBUSTYPE
:
770 PlugPlayData
.Property
= 0xd; // DevicePropertyLegacyBusType;
773 case CM_DRP_BUSNUMBER
:
774 PlugPlayData
.Property
= 0xe; // DevicePropertyBusNumber;
777 case CM_DRP_ENUMERATOR_NAME
:
778 PlugPlayData
.Property
= 0xf; // DevicePropertyEnumeratorName;
782 PlugPlayData
.Property
= 0x10; // DevicePropertyAddress;
786 /* FIXME: This property is not supported by IoGetDeviceProperty */
787 case CM_DRP_DEVICE_POWER_DATA
:
790 case CM_DRP_REMOVAL_POLICY
:
791 PlugPlayData
.Property
= 0x12; // DevicePropertyRemovalPolicy
795 /* FIXME: This property is not supported by IoGetDeviceProperty */
796 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
799 case CM_DRP_INSTALL_STATE
:
800 PlugPlayData
.Property
= 0x12; // DevicePropertyInstallState;
804 /* FIXME: This property is not supported by IoGetDeviceProperty */
805 #if (WINVER >= _WIN32_WINNT_WS03)
806 case CM_DRP_LOCATION_PATHS
:
810 #if (WINVER >= _WIN32_WINNT_WIN7)
811 case CM_DRP_BASE_CONTAINERID
:
812 PlugPlayData
.Property
= 0x16; // DevicePropertyContainerID;
817 return CR_INVALID_PROPERTY
;
820 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
821 (PVOID
)&PlugPlayData
,
822 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
823 if (NT_SUCCESS(Status
))
825 *pulLength
= PlugPlayData
.BufferSize
;
829 ret
= NtStatusToCrError(Status
);
834 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
839 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
846 DWORD
PNP_SetDeviceRegProp(
852 PNP_PROP_SIZE ulLength
,
855 CONFIGRET ret
= CR_SUCCESS
;
856 LPWSTR lpValueName
= NULL
;
859 UNREFERENCED_PARAMETER(hBinding
);
860 UNREFERENCED_PARAMETER(ulFlags
);
862 DPRINT("PNP_SetDeviceRegProp() called\n");
864 DPRINT("DeviceId: %S\n", pDeviceId
);
865 DPRINT("Property: %lu\n", ulProperty
);
866 DPRINT("DataType: %lu\n", ulDataType
);
867 DPRINT("Length: %lu\n", ulLength
);
871 case CM_DRP_DEVICEDESC
:
872 lpValueName
= L
"DeviceDesc";
875 case CM_DRP_HARDWAREID
:
876 lpValueName
= L
"HardwareID";
879 case CM_DRP_COMPATIBLEIDS
:
880 lpValueName
= L
"CompatibleIDs";
884 lpValueName
= L
"Service";
888 lpValueName
= L
"Class";
891 case CM_DRP_CLASSGUID
:
892 lpValueName
= L
"ClassGUID";
896 lpValueName
= L
"Driver";
899 case CM_DRP_CONFIGFLAGS
:
900 lpValueName
= L
"ConfigFlags";
904 lpValueName
= L
"Mfg";
907 case CM_DRP_FRIENDLYNAME
:
908 lpValueName
= L
"FriendlyName";
911 case CM_DRP_LOCATION_INFORMATION
:
912 lpValueName
= L
"LocationInformation";
915 case CM_DRP_UPPERFILTERS
:
916 lpValueName
= L
"UpperFilters";
919 case CM_DRP_LOWERFILTERS
:
920 lpValueName
= L
"LowerFilters";
923 case CM_DRP_SECURITY
:
924 lpValueName
= L
"Security";
928 lpValueName
= L
"DeviceType";
931 case CM_DRP_EXCLUSIVE
:
932 lpValueName
= L
"Exclusive";
935 case CM_DRP_CHARACTERISTICS
:
936 lpValueName
= L
"DeviceCharacteristics";
939 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
940 lpValueName
= L
"UINumberDescFormat";
943 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
944 lpValueName
= L
"RemovalPolicy";
948 return CR_INVALID_PROPERTY
;
951 DPRINT("Value name: %S\n", lpValueName
);
953 if (RegOpenKeyExW(hEnumKey
,
958 return CR_INVALID_DEVNODE
;
962 if (RegDeleteValueW(hKey
,
964 ret
= CR_REGISTRY_ERROR
;
968 if (RegSetValueExW(hKey
,
974 ret
= CR_REGISTRY_ERROR
;
979 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
986 DWORD
PNP_GetClassInstance(
989 LPWSTR pszClassInstance
,
990 PNP_RPC_STRING_LEN ulLength
)
993 return CR_CALL_NOT_IMPLEMENTED
;
1006 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1015 return CR_REGISTRY_ERROR
;
1017 /* FIXME: Set security key */
1026 DWORD
PNP_DeleteRegistryKey(
1029 LPWSTR pszParentKey
,
1034 return CR_CALL_NOT_IMPLEMENTED
;
1039 DWORD
PNP_GetClassCount(
1041 DWORD
*pulClassCount
,
1047 UNREFERENCED_PARAMETER(hBinding
);
1048 UNREFERENCED_PARAMETER(ulFlags
);
1050 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1055 if (dwError
!= ERROR_SUCCESS
)
1056 return CR_INVALID_DATA
;
1058 dwError
= RegQueryInfoKeyW(hKey
,
1071 if (dwError
!= ERROR_SUCCESS
)
1072 return CR_INVALID_DATA
;
1079 DWORD
PNP_GetClassName(
1081 LPWSTR pszClassGuid
,
1083 PNP_RPC_STRING_LEN
*pulLength
,
1086 WCHAR szKeyName
[MAX_PATH
];
1087 CONFIGRET ret
= CR_SUCCESS
;
1091 UNREFERENCED_PARAMETER(hBinding
);
1092 UNREFERENCED_PARAMETER(ulFlags
);
1094 DPRINT("PNP_GetClassName() called\n");
1096 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1097 if(lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1098 lstrcatW(szKeyName
, pszClassGuid
);
1099 else return CR_INVALID_DATA
;
1101 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1106 return CR_REGISTRY_ERROR
;
1108 dwSize
= *pulLength
* sizeof(WCHAR
);
1109 if (RegQueryValueExW(hKey
,
1117 ret
= CR_REGISTRY_ERROR
;
1121 *pulLength
= dwSize
/ sizeof(WCHAR
);
1126 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1133 DWORD
PNP_DeleteClassKey(
1135 LPWSTR pszClassGuid
,
1138 CONFIGRET ret
= CR_SUCCESS
;
1140 UNREFERENCED_PARAMETER(hBinding
);
1142 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1144 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1146 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1147 ret
= CR_REGISTRY_ERROR
;
1151 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1152 ret
= CR_REGISTRY_ERROR
;
1155 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1162 DWORD
PNP_GetInterfaceDeviceAlias(
1164 LPWSTR pszInterfaceDevice
,
1165 GUID
*AliasInterfaceGuid
,
1166 LPWSTR pszAliasInterfaceDevice
,
1167 PNP_RPC_STRING_LEN
*pulLength
,
1168 PNP_RPC_STRING_LEN
*pulTransferLen
,
1172 return CR_CALL_NOT_IMPLEMENTED
;
1177 DWORD
PNP_GetInterfaceDeviceList(
1179 GUID
*InterfaceGuid
,
1182 PNP_RPC_BUFFER_SIZE
*pulLength
,
1186 return CR_CALL_NOT_IMPLEMENTED
;
1191 DWORD
PNP_GetInterfaceDeviceListSize(
1193 PNP_RPC_BUFFER_SIZE
*pulLen
,
1194 GUID
*InterfaceGuid
,
1199 return CR_CALL_NOT_IMPLEMENTED
;
1204 DWORD
PNP_RegisterDeviceClassAssociation(
1207 GUID
*InterfaceGuid
,
1208 LPWSTR pszReference
,
1210 PNP_RPC_STRING_LEN
*pulLength
,
1211 PNP_RPC_STRING_LEN
*pulTransferLen
,
1215 return CR_CALL_NOT_IMPLEMENTED
;
1220 DWORD
PNP_UnregisterDeviceClassAssociation(
1222 LPWSTR pszInterfaceDevice
,
1226 return CR_CALL_NOT_IMPLEMENTED
;
1231 DWORD
PNP_GetClassRegProp(
1233 LPWSTR pszClassGuid
,
1235 DWORD
*pulRegDataType
,
1237 PNP_RPC_STRING_LEN
*pulTransferLen
,
1238 PNP_RPC_STRING_LEN
*pulLength
,
1241 CONFIGRET ret
= CR_SUCCESS
;
1242 LPWSTR lpValueName
= NULL
;
1243 HKEY hInstKey
= NULL
;
1244 HKEY hPropKey
= NULL
;
1247 UNREFERENCED_PARAMETER(hBinding
);
1249 DPRINT("PNP_GetClassRegProp() called\n");
1251 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1253 ret
= CR_INVALID_POINTER
;
1259 ret
= CR_INVALID_FLAG
;
1263 if (*pulLength
< *pulTransferLen
)
1264 *pulLength
= *pulTransferLen
;
1266 *pulTransferLen
= 0;
1270 case CM_CRP_SECURITY
:
1271 lpValueName
= L
"Security";
1274 case CM_CRP_DEVTYPE
:
1275 lpValueName
= L
"DeviceType";
1278 case CM_CRP_EXCLUSIVE
:
1279 lpValueName
= L
"Exclusive";
1282 case CM_CRP_CHARACTERISTICS
:
1283 lpValueName
= L
"DeviceCharacteristics";
1287 ret
= CR_INVALID_PROPERTY
;
1291 DPRINT("Value name: %S\n", lpValueName
);
1293 lError
= RegOpenKeyExW(hClassKey
,
1298 if (lError
!= ERROR_SUCCESS
)
1301 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1305 lError
= RegOpenKeyExW(hInstKey
,
1310 if (lError
!= ERROR_SUCCESS
)
1313 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1317 lError
= RegQueryValueExW(hPropKey
,
1323 if (lError
!= ERROR_SUCCESS
)
1325 if (lError
== ERROR_MORE_DATA
)
1327 ret
= CR_BUFFER_SMALL
;
1332 ret
= CR_NO_SUCH_VALUE
;
1337 if (ret
== CR_SUCCESS
)
1338 *pulTransferLen
= *pulLength
;
1340 if (hPropKey
!= NULL
)
1341 RegCloseKey(hPropKey
);
1343 if (hInstKey
!= NULL
)
1344 RegCloseKey(hInstKey
);
1346 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1353 DWORD
PNP_SetClassRegProp(
1355 LPWSTR pszClassGuid
,
1359 PNP_PROP_SIZE ulLength
,
1362 CONFIGRET ret
= CR_SUCCESS
;
1363 LPWSTR lpValueName
= NULL
;
1368 UNREFERENCED_PARAMETER(hBinding
);
1370 DPRINT("PNP_SetClassRegProp() called\n");
1373 return CR_INVALID_FLAG
;
1377 case CM_CRP_SECURITY
:
1378 lpValueName
= L
"Security";
1381 case CM_CRP_DEVTYPE
:
1382 lpValueName
= L
"DeviceType";
1385 case CM_CRP_EXCLUSIVE
:
1386 lpValueName
= L
"Exclusive";
1389 case CM_CRP_CHARACTERISTICS
:
1390 lpValueName
= L
"DeviceCharacteristics";
1394 return CR_INVALID_PROPERTY
;
1397 lError
= RegOpenKeyExW(hClassKey
,
1402 if (lError
!= ERROR_SUCCESS
)
1404 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1408 /* FIXME: Set security descriptor */
1409 lError
= RegCreateKeyExW(hInstKey
,
1413 REG_OPTION_NON_VOLATILE
,
1418 if (lError
!= ERROR_SUCCESS
)
1420 ret
= CR_REGISTRY_ERROR
;
1426 if (RegDeleteValueW(hPropKey
,
1428 ret
= CR_REGISTRY_ERROR
;
1432 if (RegSetValueExW(hPropKey
,
1438 ret
= CR_REGISTRY_ERROR
;
1442 if (hPropKey
!= NULL
)
1443 RegCloseKey(hPropKey
);
1445 if (hInstKey
!= NULL
)
1446 RegCloseKey(hInstKey
);
1453 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1454 OUT LPWSTR pszEnumerator
,
1455 OUT LPWSTR pszDevice
,
1456 OUT LPWSTR pszInstance
)
1458 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1459 LPWSTR lpEnumerator
= NULL
;
1460 LPWSTR lpDevice
= NULL
;
1461 LPWSTR lpInstance
= NULL
;
1464 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1470 lpEnumerator
= szLocalDeviceInstanceID
;
1472 ptr
= wcschr(lpEnumerator
, L
'\\');
1478 ptr
= wcschr(lpDevice
, L
'\\');
1486 if (lpEnumerator
!= NULL
)
1487 wcscpy(pszEnumerator
, lpEnumerator
);
1489 if (lpDevice
!= NULL
)
1490 wcscpy(pszDevice
, lpDevice
);
1492 if (lpInstance
!= NULL
)
1493 wcscpy(pszInstance
, lpInstance
);
1498 CreateDeviceInstance(LPWSTR pszDeviceID
)
1500 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1501 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1502 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1503 HKEY hKeyEnumerator
;
1509 /* Split the instance ID */
1510 SplitDeviceInstanceID(pszDeviceID
,
1515 /* Open or create the enumerator key */
1516 lError
= RegCreateKeyExW(hEnumKey
,
1520 REG_OPTION_NON_VOLATILE
,
1525 if (lError
!= ERROR_SUCCESS
)
1527 return CR_REGISTRY_ERROR
;
1530 /* Open or create the device key */
1531 lError
= RegCreateKeyExW(hKeyEnumerator
,
1535 REG_OPTION_NON_VOLATILE
,
1541 /* Close the enumerator key */
1542 RegCloseKey(hKeyEnumerator
);
1544 if (lError
!= ERROR_SUCCESS
)
1546 return CR_REGISTRY_ERROR
;
1549 /* Try to open the instance key and fail if it exists */
1550 lError
= RegOpenKeyExW(hKeyDevice
,
1555 if (lError
== ERROR_SUCCESS
)
1557 DPRINT1("Instance %S already exists!\n", szInstance
);
1558 RegCloseKey(hKeyInstance
);
1559 RegCloseKey(hKeyDevice
);
1560 return CR_ALREADY_SUCH_DEVINST
;
1563 /* Create a new instance key */
1564 lError
= RegCreateKeyExW(hKeyDevice
,
1568 REG_OPTION_NON_VOLATILE
,
1574 /* Close the device key */
1575 RegCloseKey(hKeyDevice
);
1577 if (lError
!= ERROR_SUCCESS
)
1579 return CR_REGISTRY_ERROR
;
1582 /* Create the 'Control' sub key */
1583 lError
= RegCreateKeyExW(hKeyInstance
,
1587 REG_OPTION_NON_VOLATILE
,
1592 if (lError
== ERROR_SUCCESS
)
1594 RegCloseKey(hKeyControl
);
1597 RegCloseKey(hKeyInstance
);
1599 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1604 DWORD
PNP_CreateDevInst(
1607 LPWSTR pszParentDeviceID
,
1608 PNP_RPC_STRING_LEN ulLength
,
1611 CONFIGRET ret
= CR_SUCCESS
;
1613 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1615 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1617 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1618 DWORD dwInstanceNumber
;
1620 /* Generated ID is: Root\<Device ID>\<Instance number> */
1621 dwInstanceNumber
= 0;
1624 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1625 pszDeviceID
, dwInstanceNumber
);
1627 /* Try to create a device instance with this ID */
1628 ret
= CreateDeviceInstance(szGeneratedInstance
);
1632 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1634 if (ret
== CR_SUCCESS
)
1636 /* pszDeviceID is an out parameter too for generated IDs */
1637 if (wcslen(szGeneratedInstance
) > ulLength
)
1639 ret
= CR_BUFFER_SMALL
;
1643 wcscpy(pszDeviceID
, szGeneratedInstance
);
1649 /* Create the device instance */
1650 ret
= CreateDeviceInstance(pszDeviceID
);
1653 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1660 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1661 LPWSTR pszDeviceInstanceSource
)
1663 DPRINT("MoveDeviceInstance: not implemented\n");
1665 return CR_CALL_NOT_IMPLEMENTED
;
1670 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1673 DPRINT("SetupDeviceInstance: not implemented\n");
1675 return CR_CALL_NOT_IMPLEMENTED
;
1680 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1682 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1683 CONFIGRET ret
= CR_SUCCESS
;
1686 DPRINT("Enable device instance\n");
1688 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1689 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1690 if (!NT_SUCCESS(Status
))
1691 ret
= NtStatusToCrError(Status
);
1698 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1700 DPRINT("DisableDeviceInstance: not implemented\n");
1702 return CR_CALL_NOT_IMPLEMENTED
;
1707 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1709 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1711 return CR_CALL_NOT_IMPLEMENTED
;
1716 DWORD
PNP_DeviceInstanceAction(
1720 LPWSTR pszDeviceInstance1
,
1721 LPWSTR pszDeviceInstance2
)
1723 CONFIGRET ret
= CR_SUCCESS
;
1725 UNREFERENCED_PARAMETER(hBinding
);
1727 DPRINT("PNP_DeviceInstanceAction() called\n");
1731 case PNP_DEVINST_MOVE
:
1732 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1733 pszDeviceInstance2
);
1736 case PNP_DEVINST_SETUP
:
1737 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1741 case PNP_DEVINST_ENABLE
:
1742 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1745 case PNP_DEVINST_DISABLE
:
1746 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1749 case PNP_DEVINST_REENUMERATE
:
1750 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
1754 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
1755 ret
= CR_CALL_NOT_IMPLEMENTED
;
1758 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1765 DWORD
PNP_GetDeviceStatus(
1772 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1773 CONFIGRET ret
= CR_SUCCESS
;
1776 UNREFERENCED_PARAMETER(hBinding
);
1777 UNREFERENCED_PARAMETER(ulFlags
);
1779 DPRINT("PNP_GetDeviceStatus() called\n");
1781 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1783 PlugPlayData
.Operation
= 0; /* Get status */
1785 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
1786 (PVOID
)&PlugPlayData
,
1787 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
1788 if (NT_SUCCESS(Status
))
1790 *pulStatus
= PlugPlayData
.DeviceStatus
;
1791 *pulProblem
= PlugPlayData
.DeviceProblem
;
1795 ret
= NtStatusToCrError(Status
);
1798 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
1805 DWORD
PNP_SetDeviceProblem(
1812 return CR_CALL_NOT_IMPLEMENTED
;
1817 DWORD
PNP_DisableDevInst(
1820 PPNP_VETO_TYPE pVetoType
,
1826 return CR_CALL_NOT_IMPLEMENTED
;
1830 DWORD
PNP_UninstallDevInst(
1836 return CR_CALL_NOT_IMPLEMENTED
;
1841 CheckForDeviceId(LPWSTR lpDeviceIdList
,
1847 lpPtr
= lpDeviceIdList
;
1850 dwLength
= wcslen(lpPtr
);
1851 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
1854 lpPtr
+= (dwLength
+ 1);
1862 AppendDeviceId(LPWSTR lpDeviceIdList
,
1863 LPDWORD lpDeviceIdListSize
,
1869 dwLen
= wcslen(lpDeviceId
);
1870 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
1872 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
1874 dwPos
+= (dwLen
+ 1);
1876 lpDeviceIdList
[dwPos
] = 0;
1878 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
1889 CONFIGRET ret
= CR_SUCCESS
;
1892 DWORD dwDeviceIdListSize
;
1893 DWORD dwNewDeviceIdSize
;
1894 WCHAR
* pszDeviceIdList
= NULL
;
1896 UNREFERENCED_PARAMETER(hBinding
);
1898 DPRINT("PNP_AddID() called\n");
1899 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
1900 DPRINT(" DeviceId: %S\n", pszID
);
1901 DPRINT(" Flags: %lx\n", ulFlags
);
1903 if (RegOpenKeyExW(hEnumKey
,
1906 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
1907 &hDeviceKey
) != ERROR_SUCCESS
)
1909 DPRINT("Failed to open the device key!\n");
1910 return CR_INVALID_DEVNODE
;
1913 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
1915 if (RegQueryValueExW(hDeviceKey
,
1920 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1922 DPRINT("Failed to query the desired ID string!\n");
1923 ret
= CR_REGISTRY_ERROR
;
1927 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
1928 if (!dwNewDeviceIdSize
)
1930 ret
= CR_INVALID_POINTER
;
1934 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
1936 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
1937 if (!pszDeviceIdList
)
1939 DPRINT("Failed to allocate memory for the desired ID string!\n");
1940 ret
= CR_OUT_OF_MEMORY
;
1944 if (RegQueryValueExW(hDeviceKey
,
1948 (LPBYTE
)pszDeviceIdList
,
1949 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
1951 DPRINT("Failed to query the desired ID string!\n");
1952 ret
= CR_REGISTRY_ERROR
;
1956 /* Check whether the device ID is already in use */
1957 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
1959 DPRINT("Device ID was found in the ID string!\n");
1964 /* Append the Device ID */
1965 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
1967 if (RegSetValueExW(hDeviceKey
,
1971 (LPBYTE
)pszDeviceIdList
,
1972 dwDeviceIdListSize
) != ERROR_SUCCESS
)
1974 DPRINT("Failed to set the desired ID string!\n");
1975 ret
= CR_REGISTRY_ERROR
;
1979 RegCloseKey(hDeviceKey
);
1980 if (pszDeviceIdList
)
1981 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
1983 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
1990 DWORD
PNP_RegisterDriver(
1996 return CR_CALL_NOT_IMPLEMENTED
;
2001 DWORD
PNP_QueryRemove(
2004 PPNP_VETO_TYPE pVetoType
,
2010 return CR_CALL_NOT_IMPLEMENTED
;
2015 DWORD
PNP_RequestDeviceEject(
2018 PPNP_VETO_TYPE pVetoType
,
2024 return CR_CALL_NOT_IMPLEMENTED
;
2029 PNP_IsDockStationPresent(handle_t hBinding
,
2036 CONFIGRET ret
= CR_SUCCESS
;
2038 UNREFERENCED_PARAMETER(hBinding
);
2040 DPRINT1("PNP_IsDockStationPresent() called\n");
2044 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2048 &hKey
) != ERROR_SUCCESS
)
2049 return CR_REGISTRY_ERROR
;
2051 dwSize
= sizeof(DWORD
);
2052 if (RegQueryValueExW(hKey
,
2057 &dwSize
) != ERROR_SUCCESS
)
2058 ret
= CR_REGISTRY_ERROR
;
2062 if (ret
== CR_SUCCESS
)
2064 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2066 ret
= CR_REGISTRY_ERROR
;
2068 else if (dwValue
!= 0)
2074 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2081 DWORD
PNP_RequestEjectPC(
2085 return CR_CALL_NOT_IMPLEMENTED
;
2090 DWORD
PNP_HwProfFlags(
2096 PPNP_VETO_TYPE pVetoType
,
2101 CONFIGRET ret
= CR_SUCCESS
;
2102 WCHAR szKeyName
[MAX_PATH
];
2107 UNREFERENCED_PARAMETER(hBinding
);
2109 DPRINT("PNP_HwProfFlags() called\n");
2114 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2119 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2123 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2127 &hKey
) != ERROR_SUCCESS
)
2128 return CR_REGISTRY_ERROR
;
2130 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2132 if (RegOpenKeyExW(hKey
,
2136 &hDeviceKey
) != ERROR_SUCCESS
)
2142 dwSize
= sizeof(DWORD
);
2143 if (!RegQueryValueExW(hDeviceKey
,
2148 &dwSize
) != ERROR_SUCCESS
)
2153 RegCloseKey(hDeviceKey
);
2156 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2158 /* FIXME: not implemented yet */
2159 ret
= CR_CALL_NOT_IMPLEMENTED
;
2169 DWORD
PNP_GetHwProfInfo(
2172 HWPROFILEINFO
*pHWProfileInfo
,
2173 DWORD ulProfileInfoSize
,
2176 WCHAR szProfileName
[5];
2177 HKEY hKeyConfig
= NULL
;
2178 HKEY hKeyProfiles
= NULL
;
2179 HKEY hKeyProfile
= NULL
;
2180 DWORD dwDisposition
;
2183 CONFIGRET ret
= CR_SUCCESS
;
2185 UNREFERENCED_PARAMETER(hBinding
);
2187 DPRINT("PNP_GetHwProfInfo() called\n");
2189 if (ulProfileInfoSize
== 0)
2191 ret
= CR_INVALID_DATA
;
2197 ret
= CR_INVALID_FLAG
;
2201 /* Initialize the profile information */
2202 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2203 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2204 pHWProfileInfo
->HWPI_dwFlags
= 0;
2206 /* Open the 'IDConfigDB' key */
2207 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2208 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2211 REG_OPTION_NON_VOLATILE
,
2216 if (lError
!= ERROR_SUCCESS
)
2218 ret
= CR_REGISTRY_ERROR
;
2222 /* Open the 'Hardware Profiles' subkey */
2223 lError
= RegCreateKeyExW(hKeyConfig
,
2224 L
"Hardware Profiles",
2227 REG_OPTION_NON_VOLATILE
,
2228 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2232 if (lError
!= ERROR_SUCCESS
)
2234 ret
= CR_REGISTRY_ERROR
;
2238 if (ulIndex
== (ULONG
)-1)
2240 dwSize
= sizeof(ULONG
);
2241 lError
= RegQueryValueExW(hKeyConfig
,
2245 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2247 if (lError
!= ERROR_SUCCESS
)
2249 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2250 ret
= CR_REGISTRY_ERROR
;
2256 /* FIXME: not implemented yet */
2257 ret
= CR_CALL_NOT_IMPLEMENTED
;
2261 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2263 lError
= RegOpenKeyExW(hKeyProfiles
,
2268 if (lError
!= ERROR_SUCCESS
)
2270 ret
= CR_REGISTRY_ERROR
;
2274 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2275 lError
= RegQueryValueExW(hKeyProfile
,
2279 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2281 if (lError
!= ERROR_SUCCESS
)
2283 ret
= CR_REGISTRY_ERROR
;
2288 if (hKeyProfile
!= NULL
)
2289 RegCloseKey(hKeyProfile
);
2291 if (hKeyProfiles
!= NULL
)
2292 RegCloseKey(hKeyProfiles
);
2294 if (hKeyConfig
!= NULL
)
2295 RegCloseKey(hKeyConfig
);
2302 DWORD
PNP_AddEmptyLogConf(
2306 DWORD
*pulLogConfTag
,
2310 return CR_CALL_NOT_IMPLEMENTED
;
2315 DWORD
PNP_FreeLogConf(
2318 DWORD ulLogConfType
,
2323 return CR_CALL_NOT_IMPLEMENTED
;
2328 DWORD
PNP_GetFirstLogConf(
2331 DWORD ulLogConfType
,
2332 DWORD
*pulLogConfTag
,
2336 return CR_CALL_NOT_IMPLEMENTED
;
2341 DWORD
PNP_GetNextLogConf(
2344 DWORD ulLogConfType
,
2350 return CR_CALL_NOT_IMPLEMENTED
;
2355 DWORD
PNP_GetLogConfPriority(
2364 return CR_CALL_NOT_IMPLEMENTED
;
2369 DWORD
PNP_AddResDes(
2373 DWORD ulLogConfType
,
2374 RESOURCEID ResourceID
,
2375 DWORD
*pulResourceTag
,
2377 PNP_RPC_BUFFER_SIZE ResourceLen
,
2381 return CR_CALL_NOT_IMPLEMENTED
;
2386 DWORD
PNP_FreeResDes(
2390 DWORD ulLogConfType
,
2391 RESOURCEID ResourceID
,
2392 DWORD ulResourceTag
,
2393 DWORD
*pulPreviousResType
,
2394 DWORD
*pulPreviousResTag
,
2398 return CR_CALL_NOT_IMPLEMENTED
;
2403 DWORD
PNP_GetNextResDes(
2407 DWORD ulLogConfType
,
2408 RESOURCEID ResourceID
,
2409 DWORD ulResourceTag
,
2410 DWORD
*pulNextResType
,
2411 DWORD
*pulNextResTag
,
2415 return CR_CALL_NOT_IMPLEMENTED
;
2420 DWORD
PNP_GetResDesData(
2424 DWORD ulLogConfType
,
2425 RESOURCEID ResourceID
,
2426 DWORD ulResourceTag
,
2428 PNP_RPC_BUFFER_SIZE BufferLen
,
2432 return CR_CALL_NOT_IMPLEMENTED
;
2437 DWORD
PNP_GetResDesDataSize(
2441 DWORD ulLogConfType
,
2442 RESOURCEID ResourceID
,
2443 DWORD ulResourceTag
,
2448 return CR_CALL_NOT_IMPLEMENTED
;
2453 DWORD
PNP_ModifyResDes(
2457 DWORD ulLogConfType
,
2458 RESOURCEID CurrentResourceID
,
2459 RESOURCEID NewResourceID
,
2460 DWORD ulResourceTag
,
2462 PNP_RPC_BUFFER_SIZE ResourceLen
,
2466 return CR_CALL_NOT_IMPLEMENTED
;
2471 DWORD
PNP_DetectResourceConflict(
2474 RESOURCEID ResourceID
,
2476 PNP_RPC_BUFFER_SIZE ResourceLen
,
2477 BOOL
*pbConflictDetected
,
2481 return CR_CALL_NOT_IMPLEMENTED
;
2486 DWORD
PNP_QueryResConfList(
2489 RESOURCEID ResourceID
,
2491 PNP_RPC_BUFFER_SIZE ResourceLen
,
2493 PNP_RPC_BUFFER_SIZE BufferLen
,
2497 return CR_CALL_NOT_IMPLEMENTED
;
2502 DWORD
PNP_SetHwProf(
2504 DWORD ulHardwareProfile
,
2508 return CR_CALL_NOT_IMPLEMENTED
;
2513 DWORD
PNP_QueryArbitratorFreeData(
2518 RESOURCEID ResourceID
,
2522 return CR_CALL_NOT_IMPLEMENTED
;
2527 DWORD
PNP_QueryArbitratorFreeSize(
2531 RESOURCEID ResourceID
,
2535 return CR_CALL_NOT_IMPLEMENTED
;
2545 return CR_CALL_NOT_IMPLEMENTED
;
2550 DWORD
PNP_RegisterNotification(
2554 return CR_CALL_NOT_IMPLEMENTED
;
2559 DWORD
PNP_UnregisterNotification(
2563 return CR_CALL_NOT_IMPLEMENTED
;
2568 DWORD
PNP_GetCustomDevProp(
2571 LPWSTR CustomPropName
,
2572 DWORD
*pulRegDataType
,
2574 PNP_RPC_STRING_LEN
*pulTransferLen
,
2575 PNP_RPC_STRING_LEN
*pulLength
,
2578 HKEY hDeviceKey
= NULL
;
2579 HKEY hParamKey
= NULL
;
2581 CONFIGRET ret
= CR_SUCCESS
;
2583 UNREFERENCED_PARAMETER(hBinding
);
2585 DPRINT("PNP_GetCustomDevProp() called\n");
2587 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2589 ret
= CR_INVALID_POINTER
;
2593 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2595 ret
= CR_INVALID_FLAG
;
2599 if (*pulLength
< *pulTransferLen
)
2600 *pulLength
= *pulTransferLen
;
2602 *pulTransferLen
= 0;
2604 lError
= RegOpenKeyExW(hEnumKey
,
2609 if (lError
!= ERROR_SUCCESS
)
2611 ret
= CR_REGISTRY_ERROR
;
2615 lError
= RegOpenKeyExW(hDeviceKey
,
2616 L
"Device Parameters",
2620 if (lError
!= ERROR_SUCCESS
)
2622 ret
= CR_REGISTRY_ERROR
;
2626 lError
= RegQueryValueExW(hParamKey
,
2632 if (lError
!= ERROR_SUCCESS
)
2634 if (lError
== ERROR_MORE_DATA
)
2636 ret
= CR_BUFFER_SMALL
;
2641 ret
= CR_NO_SUCH_VALUE
;
2646 if (ret
== CR_SUCCESS
)
2647 *pulTransferLen
= *pulLength
;
2649 if (hParamKey
!= NULL
)
2650 RegCloseKey(hParamKey
);
2652 if (hDeviceKey
!= NULL
)
2653 RegCloseKey(hDeviceKey
);
2655 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
2662 DWORD
PNP_GetVersionInternal(
2669 return CR_CALL_NOT_IMPLEMENTED
;
2674 DWORD
PNP_GetBlockedDriverInfo(
2677 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
2678 PNP_RPC_BUFFER_SIZE
*pulLength
,
2682 return CR_CALL_NOT_IMPLEMENTED
;
2687 DWORD
PNP_GetServerSideDeviceInstallFlags(
2689 DWORD
*pulSSDIFlags
,
2693 return CR_CALL_NOT_IMPLEMENTED
;
2698 DWORD
PNP_GetObjectPropKeys(
2702 LPWSTR PropertyCultureName
,
2703 PNP_PROP_COUNT
*PropertyCount
,
2704 PNP_PROP_COUNT
*TransferLen
,
2705 DEVPROPKEY
*PropertyKeys
,
2709 return CR_CALL_NOT_IMPLEMENTED
;
2714 DWORD
PNP_GetObjectProp(
2718 LPWSTR PropertyCultureName
,
2719 const DEVPROPKEY
*PropertyKey
,
2720 DEVPROPTYPE
*PropertyType
,
2721 PNP_PROP_SIZE
*PropertySize
,
2722 PNP_PROP_SIZE
*TransferLen
,
2723 BYTE
*PropertyBuffer
,
2727 return CR_CALL_NOT_IMPLEMENTED
;
2732 DWORD
PNP_SetObjectProp(
2736 LPWSTR PropertyCultureName
,
2737 const DEVPROPKEY
*PropertyKey
,
2738 DEVPROPTYPE PropertyType
,
2739 PNP_PROP_SIZE PropertySize
,
2740 BYTE
*PropertyBuffer
,
2744 return CR_CALL_NOT_IMPLEMENTED
;
2749 DWORD
PNP_InstallDevInst(
2753 return CR_CALL_NOT_IMPLEMENTED
;
2758 DWORD
PNP_ApplyPowerSettings(
2762 return CR_CALL_NOT_IMPLEMENTED
;
2767 DWORD
PNP_DriverStoreAddDriverPackage(
2771 return CR_CALL_NOT_IMPLEMENTED
;
2776 DWORD
PNP_DriverStoreDeleteDriverPackage(
2780 return CR_CALL_NOT_IMPLEMENTED
;
2785 DWORD
PNP_RegisterServiceNotification(
2789 return CR_CALL_NOT_IMPLEMENTED
;
2794 DWORD
PNP_SetActiveService(
2798 return CR_CALL_NOT_IMPLEMENTED
;
2803 DWORD
PNP_DeleteServiceDevices(
2807 return CR_CALL_NOT_IMPLEMENTED
;
2812 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
2814 BOOL DeviceInstalled
= FALSE
;
2817 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
2818 LPVOID Environment
= NULL
;
2819 PROCESS_INFORMATION ProcessInfo
;
2820 STARTUPINFOW StartupInfo
;
2824 /* The following lengths are constant (see below), they cannot overflow */
2825 WCHAR CommandLine
[116];
2826 WCHAR InstallEventName
[73];
2828 WCHAR UuidString
[39];
2830 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
2832 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
2834 if (RegOpenKeyExW(hEnumKey
,
2838 &DeviceKey
) == ERROR_SUCCESS
)
2840 if (RegQueryValueExW(DeviceKey
,
2845 NULL
) == ERROR_SUCCESS
)
2847 DPRINT("No need to install: %S\n", DeviceInstance
);
2848 RegCloseKey(DeviceKey
);
2852 RegCloseKey(DeviceKey
);
2855 DPRINT1("Installing: %S\n", DeviceInstance
);
2857 /* Create a random UUID for the named pipe */
2858 UuidCreate(&RandomUuid
);
2859 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
2860 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
2861 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
2862 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
2863 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
2865 /* Create the named pipe */
2866 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
2867 wcscat(PipeName
, UuidString
);
2868 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
2870 if(hPipe
== INVALID_HANDLE_VALUE
)
2872 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
2876 /* Launch rundll32 to call ClientSideInstallW */
2877 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
2878 wcscat(CommandLine
, PipeName
);
2880 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
2881 StartupInfo
.cb
= sizeof(StartupInfo
);
2885 /* newdev has to run under the environment of the current user */
2886 if(!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
2888 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
2892 if(!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
2894 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
2900 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
2902 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
2903 (ShowWizard is only set to FALSE for these two modes) */
2904 ASSERT(!ShowWizard
);
2906 if(!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
2908 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
2913 /* Wait for the function to connect to our pipe */
2914 if(!ConnectNamedPipe(hPipe
, NULL
))
2916 if (GetLastError() != ERROR_PIPE_CONNECTED
)
2918 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
2923 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
2924 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
2925 wcscat(InstallEventName
, UuidString
);
2927 Value
= sizeof(InstallEventName
);
2928 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2929 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
2931 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
2932 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
2933 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
2935 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
2936 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
2937 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
2939 /* Wait for newdev.dll to finish processing */
2940 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
2942 /* The following check for success is probably not compatible to Windows, but should do its job */
2943 if(!GetExitCodeProcess(ProcessInfo
.hProcess
, &Value
))
2945 DPRINT1("GetExitCodeProcess failed with error %u\n", GetLastError());
2949 DeviceInstalled
= Value
;
2952 if(hPipe
!= INVALID_HANDLE_VALUE
)
2956 DestroyEnvironmentBlock(Environment
);
2958 if(ProcessInfo
.hProcess
)
2959 CloseHandle(ProcessInfo
.hProcess
);
2961 if(ProcessInfo
.hThread
)
2962 CloseHandle(ProcessInfo
.hThread
);
2964 DPRINT1("Success? %d\n", DeviceInstalled
);
2966 return DeviceInstalled
;
2982 return ERROR_INVALID_PARAMETER
;
2985 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
2986 if (rc
!= ERROR_SUCCESS
)
2988 if (dwType
!= REG_SZ
)
2989 return ERROR_FILE_NOT_FOUND
;
2990 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
2992 return ERROR_NOT_ENOUGH_MEMORY
;
2993 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
2994 if (rc
!= ERROR_SUCCESS
)
2996 HeapFree(GetProcessHeap(), 0, Value
);
2999 /* NULL-terminate the string */
3000 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3003 return ERROR_SUCCESS
;
3011 DWORD regType
, active
, size
;
3015 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3016 if (rc
!= ERROR_SUCCESS
)
3019 size
= sizeof(DWORD
);
3020 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3021 if (rc
!= ERROR_SUCCESS
)
3023 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3026 ret
= (active
!= 0);
3032 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3041 HKEY ControlKey
= NULL
;
3042 LPWSTR SystemStartOptions
= NULL
;
3043 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3044 BOOL ConsoleBoot
= FALSE
;
3049 L
"SYSTEM\\CurrentControlSet\\Control",
3054 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3055 if (rc
!= ERROR_SUCCESS
)
3058 /* Check for CONSOLE switch in SystemStartOptions */
3059 CurrentOption
= SystemStartOptions
;
3060 while (CurrentOption
)
3062 NextOption
= wcschr(CurrentOption
, L
' ');
3064 *NextOption
= L
'\0';
3065 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3067 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3071 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3075 if (ControlKey
!= NULL
)
3076 RegCloseKey(ControlKey
);
3077 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3082 /* Loop to install all queued devices installations */
3084 DeviceInstallThread(LPVOID lpParameter
)
3086 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3087 PSLIST_ENTRY ListEntry
;
3089 PLIST_ENTRY ListEntry
;
3091 DeviceInstallParams
* Params
;
3094 UNREFERENCED_PARAMETER(lpParameter
);
3096 WaitForSingleObject(hInstallEvent
, INFINITE
);
3098 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3102 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3103 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3105 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3108 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3110 if (ListEntry
== NULL
)
3112 SetEvent(hNoPendingInstalls
);
3113 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3117 ResetEvent(hNoPendingInstalls
);
3118 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3119 InstallDevice(Params
->DeviceIds
, showWizard
);
3128 PnpEventThread(LPVOID lpParameter
)
3130 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3133 RPC_STATUS RpcStatus
;
3135 UNREFERENCED_PARAMETER(lpParameter
);
3137 PnpEventSize
= 0x1000;
3138 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3139 if (PnpEvent
== NULL
)
3140 return ERROR_OUTOFMEMORY
;
3144 DPRINT("Calling NtGetPlugPlayEvent()\n");
3146 /* Wait for the next pnp event */
3147 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3149 /* Resize the buffer for the PnP event if it's too small. */
3150 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3152 PnpEventSize
+= 0x400;
3153 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3154 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3155 if (PnpEvent
== NULL
)
3156 return ERROR_OUTOFMEMORY
;
3160 if (!NT_SUCCESS(Status
))
3162 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3166 /* Process the pnp event */
3167 DPRINT("Received PnP Event\n");
3168 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3170 DeviceInstallParams
* Params
;
3172 DWORD DeviceIdLength
;
3174 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3176 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3179 /* Queue device install (will be dequeued by DeviceInstallThread */
3180 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3181 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3184 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3185 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3186 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3188 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3190 SetEvent(hDeviceInstallListNotEmpty
);
3194 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3196 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3199 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3201 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3203 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3205 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3207 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3209 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3211 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3213 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3215 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3217 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3219 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3221 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3225 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3226 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3227 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3228 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3229 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3232 /* Dequeue the current pnp event and signal the next one */
3233 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3236 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3238 return ERROR_SUCCESS
;
3243 UpdateServiceStatus(DWORD dwState
)
3245 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3246 ServiceStatus
.dwCurrentState
= dwState
;
3247 ServiceStatus
.dwControlsAccepted
= 0;
3248 ServiceStatus
.dwWin32ExitCode
= 0;
3249 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3250 ServiceStatus
.dwCheckPoint
= 0;
3252 if (dwState
== SERVICE_START_PENDING
||
3253 dwState
== SERVICE_STOP_PENDING
||
3254 dwState
== SERVICE_PAUSE_PENDING
||
3255 dwState
== SERVICE_CONTINUE_PENDING
)
3256 ServiceStatus
.dwWaitHint
= 10000;
3258 ServiceStatus
.dwWaitHint
= 0;
3260 SetServiceStatus(ServiceStatusHandle
,
3266 ServiceControlHandler(DWORD dwControl
,
3271 DPRINT1("ServiceControlHandler() called\n");
3275 case SERVICE_CONTROL_STOP
:
3276 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3277 /* Stop listening to RPC Messages */
3278 RpcMgmtStopServerListening(NULL
);
3279 UpdateServiceStatus(SERVICE_STOPPED
);
3280 return ERROR_SUCCESS
;
3282 case SERVICE_CONTROL_PAUSE
:
3283 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3284 UpdateServiceStatus(SERVICE_PAUSED
);
3285 return ERROR_SUCCESS
;
3287 case SERVICE_CONTROL_CONTINUE
:
3288 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3289 UpdateServiceStatus(SERVICE_RUNNING
);
3290 return ERROR_SUCCESS
;
3292 case SERVICE_CONTROL_INTERROGATE
:
3293 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3294 SetServiceStatus(ServiceStatusHandle
,
3296 return ERROR_SUCCESS
;
3298 case SERVICE_CONTROL_SHUTDOWN
:
3299 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3300 /* Stop listening to RPC Messages */
3301 RpcMgmtStopServerListening(NULL
);
3302 UpdateServiceStatus(SERVICE_STOPPED
);
3303 return ERROR_SUCCESS
;
3306 DPRINT1(" Control %lu received\n");
3307 return ERROR_CALL_NOT_IMPLEMENTED
;
3312 static VOID CALLBACK
3313 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3318 UNREFERENCED_PARAMETER(argc
);
3319 UNREFERENCED_PARAMETER(argv
);
3321 DPRINT("ServiceMain() called\n");
3323 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3324 ServiceControlHandler
,
3326 if (!ServiceStatusHandle
)
3328 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3332 UpdateServiceStatus(SERVICE_START_PENDING
);
3334 hThread
= CreateThread(NULL
,
3340 if (hThread
!= NULL
)
3341 CloseHandle(hThread
);
3343 hThread
= CreateThread(NULL
,
3349 if (hThread
!= NULL
)
3350 CloseHandle(hThread
);
3352 hThread
= CreateThread(NULL
,
3354 DeviceInstallThread
,
3358 if (hThread
!= NULL
)
3359 CloseHandle(hThread
);
3361 UpdateServiceStatus(SERVICE_RUNNING
);
3363 DPRINT("ServiceMain() done\n");
3368 wmain(int argc
, WCHAR
*argv
[])
3373 UNREFERENCED_PARAMETER(argc
);
3374 UNREFERENCED_PARAMETER(argv
);
3376 DPRINT("Umpnpmgr: main() started\n");
3378 /* We need this privilege for using CreateProcessAsUserW */
3379 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3381 hInstallEvent
= CreateEvent(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3382 if (hInstallEvent
== NULL
)
3384 dwError
= GetLastError();
3385 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3389 hDeviceInstallListNotEmpty
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
3390 if (hDeviceInstallListNotEmpty
== NULL
)
3392 dwError
= GetLastError();
3393 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3397 hNoPendingInstalls
= CreateEventW(NULL
,
3400 L
"Global\\PnP_No_Pending_Install_Events");
3401 if (hNoPendingInstalls
== NULL
)
3403 dwError
= GetLastError();
3404 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3408 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3409 InitializeSListHead(&DeviceInstallListHead
);
3411 InitializeListHead(&DeviceInstallListHead
);
3414 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3415 L
"System\\CurrentControlSet\\Enum",
3419 if (dwError
!= ERROR_SUCCESS
)
3421 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3425 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3426 L
"System\\CurrentControlSet\\Control\\Class",
3430 if (dwError
!= ERROR_SUCCESS
)
3432 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3436 StartServiceCtrlDispatcher(ServiceTable
);
3438 DPRINT("Umpnpmgr: main() done\n");