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: base/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 *****************************************************************/
31 //#define HAVE_SLIST_ENTRY_IMPLEMENTED
32 #define WIN32_NO_STATUS
34 #define COM_NO_WINDOWS_H
44 #include <umpnpmgr/sysguid.h>
54 /* GLOBALS ******************************************************************/
56 static WCHAR ServiceName
[] = L
"PlugPlay";
58 static SERVICE_STATUS_HANDLE ServiceStatusHandle
;
59 static SERVICE_STATUS ServiceStatus
;
61 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
63 static HKEY hEnumKey
= NULL
;
64 static HKEY hClassKey
= NULL
;
66 static HANDLE hUserToken
= NULL
;
67 static HANDLE hInstallEvent
= NULL
;
68 static HANDLE hNoPendingInstalls
= NULL
;
70 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
71 static SLIST_HEADER DeviceInstallListHead
;
73 static LIST_ENTRY DeviceInstallListHead
;
75 static HANDLE hDeviceInstallListNotEmpty
;
79 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
80 SLIST_ENTRY ListEntry
;
85 } DeviceInstallParams
;
87 /* FUNCTIONS *****************************************************************/
90 RpcServerThread(LPVOID lpParameter
)
93 BOOLEAN RegisteredProtSeq
= FALSE
;
95 UNREFERENCED_PARAMETER(lpParameter
);
97 DPRINT("RpcServerThread() called\n");
100 /* 2k/XP/2k3-compatible protocol sequence/endpoint */
101 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
104 NULL
); // Security descriptor
105 if (Status
== RPC_S_OK
)
106 RegisteredProtSeq
= TRUE
;
108 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
111 /* Vista/7-compatible protocol sequence/endpoint */
112 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
115 NULL
); // Security descriptor
116 if (Status
== RPC_S_OK
)
117 RegisteredProtSeq
= TRUE
;
119 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
121 /* Make sure there's a usable endpoint */
122 if (RegisteredProtSeq
== FALSE
)
125 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
128 if (Status
!= RPC_S_OK
)
130 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
134 Status
= RpcServerListen(1,
137 if (Status
!= RPC_S_OK
)
139 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
143 /* ROS HACK (this should never happen...) */
144 DPRINT1("*** Other devices won't be installed correctly. If something\n");
145 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
147 DPRINT("RpcServerThread() done\n");
153 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
155 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
159 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
161 HeapFree(GetProcessHeap(), 0, ptr
);
165 static CONFIGRET WINAPI
166 NtStatusToCrError(NTSTATUS Status
)
170 case STATUS_NO_SUCH_DEVICE
:
171 return CR_NO_SUCH_DEVINST
;
172 case STATUS_NOT_IMPLEMENTED
:
173 return CR_CALL_NOT_IMPLEMENTED
;
176 /* FIXME: add more mappings */
177 DPRINT1("Unable to map status 0x%08lx\n", Status
);
189 UNREFERENCED_PARAMETER(hBinding
);
200 UNREFERENCED_PARAMETER(hBinding
);
212 UNREFERENCED_PARAMETER(hBinding
);
227 UNREFERENCED_PARAMETER(hBinding
);
228 UNREFERENCED_PARAMETER(ulFlags
);
230 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
241 UNREFERENCED_PARAMETER(hBinding
);
243 DPRINT("PNP_InitDetection() called\n");
256 DWORD ReturnValue
= CR_FAILURE
;
259 UNREFERENCED_PARAMETER(hBinding
);
260 UNREFERENCED_PARAMETER(Admin
);
262 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
264 /* Get the users token */
265 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
269 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
275 CloseHandle(hUserToken
);
279 if (!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
281 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
285 /* Trigger the installer thread */
287 SetEvent(hInstallEvent
);
289 ReturnValue
= CR_SUCCESS
;
293 CloseHandle(hProcess
);
302 PNP_ValidateDeviceInstance(
307 CONFIGRET ret
= CR_SUCCESS
;
308 HKEY hDeviceKey
= NULL
;
310 UNREFERENCED_PARAMETER(hBinding
);
311 UNREFERENCED_PARAMETER(ulFlags
);
313 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
316 if (RegOpenKeyExW(hEnumKey
,
322 DPRINT("Could not open the Device Key!\n");
323 ret
= CR_NO_SUCH_DEVNODE
;
327 /* FIXME: add more tests */
330 if (hDeviceKey
!= NULL
)
331 RegCloseKey(hDeviceKey
);
333 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
342 PNP_GetRootDeviceInstance(
345 PNP_RPC_STRING_LEN ulLength
)
347 CONFIGRET ret
= CR_SUCCESS
;
349 UNREFERENCED_PARAMETER(hBinding
);
351 DPRINT("PNP_GetRootDeviceInstance() called\n");
355 ret
= CR_INVALID_POINTER
;
358 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
360 ret
= CR_BUFFER_SMALL
;
368 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
377 PNP_GetRelatedDeviceInstance(
379 DWORD ulRelationship
,
381 LPWSTR pRelatedDeviceId
,
382 PNP_RPC_STRING_LEN
*pulLength
,
385 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
386 CONFIGRET ret
= CR_SUCCESS
;
389 UNREFERENCED_PARAMETER(hBinding
);
390 UNREFERENCED_PARAMETER(ulFlags
);
392 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
393 DPRINT(" Relationship %ld\n", ulRelationship
);
394 DPRINT(" DeviceId %S\n", pDeviceID
);
396 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
399 PlugPlayData
.Relation
= ulRelationship
;
401 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
402 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
404 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
405 (PVOID
)&PlugPlayData
,
406 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
407 if (!NT_SUCCESS(Status
))
409 ret
= NtStatusToCrError(Status
);
412 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
413 if (ret
== CR_SUCCESS
)
415 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
425 PNP_EnumerateSubKeys(
430 PNP_RPC_STRING_LEN ulLength
,
431 PNP_RPC_STRING_LEN
*pulRequiredLen
,
434 CONFIGRET ret
= CR_SUCCESS
;
438 UNREFERENCED_PARAMETER(hBinding
);
439 UNREFERENCED_PARAMETER(ulFlags
);
441 DPRINT("PNP_EnumerateSubKeys() called\n");
445 case PNP_ENUMERATOR_SUBKEYS
:
449 case PNP_CLASS_SUBKEYS
:
457 *pulRequiredLen
= ulLength
;
458 dwError
= RegEnumKeyExW(hKey
,
466 if (dwError
!= ERROR_SUCCESS
)
468 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
475 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
488 PNP_RPC_STRING_LEN
*pulLength
,
491 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
492 CONFIGRET ret
= CR_CALL_NOT_IMPLEMENTED
;
495 DPRINT("PNP_GetDeviceList() called\n");
497 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
498 return CR_INVALID_FLAG
;
500 if (pulLength
== NULL
|| pszFilter
== NULL
)
501 return CR_INVALID_POINTER
;
503 // if (Buffer == NULL)
509 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
510 CM_GETIDLIST_FILTER_POWERRELATIONS
|
511 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
512 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
514 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
516 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
518 PlugPlayData
.Relations
= 3;
520 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
523 PlugPlayData
.Relations
= 0;
525 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
527 PlugPlayData
.Relations
= 1;
529 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
531 PlugPlayData
.Relations
= 0;
534 PlugPlayData
.BufferSize
= *pulLength
;
535 PlugPlayData
.Buffer
= Buffer
;
537 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
538 (PVOID
)&PlugPlayData
,
539 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
540 if (NT_SUCCESS(Status
))
542 *pulLength
= PlugPlayData
.BufferSize
;
546 ret
= NtStatusToCrError(Status
);
549 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
553 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
557 else /* CM_GETIDLIST_FILTER_NONE */
569 PNP_GetDeviceListSize(
572 PNP_RPC_BUFFER_SIZE
*pulLength
,
575 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
576 CONFIGRET ret
= CR_CALL_NOT_IMPLEMENTED
;
579 DPRINT("PNP_GetDeviceListSize() called\n");
581 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
582 return CR_INVALID_FLAG
;
584 if (pulLength
== NULL
|| pszFilter
== NULL
)
585 return CR_INVALID_POINTER
;
590 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
591 CM_GETIDLIST_FILTER_POWERRELATIONS
|
592 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
593 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
595 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
597 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
599 PlugPlayData
.Relations
= 3;
601 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
604 PlugPlayData
.Relations
= 0;
606 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
608 PlugPlayData
.Relations
= 1;
610 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
612 PlugPlayData
.Relations
= 0;
615 PlugPlayData
.BufferSize
= 0;
616 PlugPlayData
.Buffer
= NULL
;
618 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
619 (PVOID
)&PlugPlayData
,
620 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
621 if (NT_SUCCESS(Status
))
623 *pulLength
= PlugPlayData
.BufferSize
;
627 ret
= NtStatusToCrError(Status
);
630 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
634 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
638 else /* CM_GETIDLIST_FILTER_NONE */
656 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
657 CONFIGRET ret
= CR_SUCCESS
;
660 UNREFERENCED_PARAMETER(hBinding
);
661 UNREFERENCED_PARAMETER(ulFlags
);
663 DPRINT("PNP_GetDepth() called\n");
665 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
668 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
669 (PVOID
)&PlugPlayData
,
670 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
671 if (NT_SUCCESS(Status
))
673 *pulDepth
= PlugPlayData
.Depth
;
677 ret
= NtStatusToCrError(Status
);
680 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
689 PNP_GetDeviceRegProp(
693 DWORD
*pulRegDataType
,
695 PNP_PROP_SIZE
*pulTransferLen
,
696 PNP_PROP_SIZE
*pulLength
,
699 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
700 CONFIGRET ret
= CR_SUCCESS
;
701 LPWSTR lpValueName
= NULL
;
706 UNREFERENCED_PARAMETER(hBinding
);
708 DPRINT("PNP_GetDeviceRegProp() called\n");
710 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
712 ret
= CR_INVALID_POINTER
;
718 ret
= CR_INVALID_FLAG
;
722 /* FIXME: Check pDeviceID */
724 if (*pulLength
< *pulTransferLen
)
725 *pulLength
= *pulTransferLen
;
731 case CM_DRP_DEVICEDESC
:
732 lpValueName
= L
"DeviceDesc";
735 case CM_DRP_HARDWAREID
:
736 lpValueName
= L
"HardwareID";
739 case CM_DRP_COMPATIBLEIDS
:
740 lpValueName
= L
"CompatibleIDs";
744 lpValueName
= L
"Service";
748 lpValueName
= L
"Class";
751 case CM_DRP_CLASSGUID
:
752 lpValueName
= L
"ClassGUID";
756 lpValueName
= L
"Driver";
759 case CM_DRP_CONFIGFLAGS
:
760 lpValueName
= L
"ConfigFlags";
764 lpValueName
= L
"Mfg";
767 case CM_DRP_FRIENDLYNAME
:
768 lpValueName
= L
"FriendlyName";
771 case CM_DRP_LOCATION_INFORMATION
:
772 lpValueName
= L
"LocationInformation";
775 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
779 case CM_DRP_CAPABILITIES
:
780 lpValueName
= L
"Capabilities";
783 case CM_DRP_UI_NUMBER
:
787 case CM_DRP_UPPERFILTERS
:
788 lpValueName
= L
"UpperFilters";
791 case CM_DRP_LOWERFILTERS
:
792 lpValueName
= L
"LowerFilters";
795 case CM_DRP_BUSTYPEGUID
:
799 case CM_DRP_LEGACYBUSTYPE
:
803 case CM_DRP_BUSNUMBER
:
807 case CM_DRP_ENUMERATOR_NAME
:
811 case CM_DRP_SECURITY
:
812 lpValueName
= L
"Security";
816 lpValueName
= L
"DeviceType";
819 case CM_DRP_EXCLUSIVE
:
820 lpValueName
= L
"Exclusive";
823 case CM_DRP_CHARACTERISTICS
:
824 lpValueName
= L
"DeviceCharacteristics";
831 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
832 lpValueName
= L
"UINumberDescFormat";
835 case CM_DRP_DEVICE_POWER_DATA
:
839 case CM_DRP_REMOVAL_POLICY
:
843 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
847 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
848 lpValueName
= L
"RemovalPolicy";
851 case CM_DRP_INSTALL_STATE
:
855 #if (WINVER >= _WIN32_WINNT_WS03)
856 case CM_DRP_LOCATION_PATHS
:
861 #if (WINVER >= _WIN32_WINNT_WIN7)
862 case CM_DRP_BASE_CONTAINERID
:
868 ret
= CR_INVALID_PROPERTY
;
872 DPRINT("Value name: %S\n", lpValueName
);
876 /* Retrieve information from the Registry */
877 lError
= RegOpenKeyExW(hEnumKey
,
882 if (lError
!= ERROR_SUCCESS
)
886 ret
= CR_INVALID_DEVNODE
;
890 lError
= RegQueryValueExW(hKey
,
896 if (lError
!= ERROR_SUCCESS
)
898 if (lError
== ERROR_MORE_DATA
)
900 ret
= CR_BUFFER_SMALL
;
905 ret
= CR_NO_SUCH_VALUE
;
911 /* Retrieve information from the Device Node */
912 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
914 PlugPlayData
.Buffer
= Buffer
;
915 PlugPlayData
.BufferSize
= *pulLength
;
919 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
920 PlugPlayData
.Property
= 0xb; // DevicePropertyPhysicalDeviceObjectName;
923 case CM_DRP_UI_NUMBER
:
924 PlugPlayData
.Property
= 0x11; // DevicePropertyUINumber;
927 case CM_DRP_BUSTYPEGUID
:
928 PlugPlayData
.Property
= 0xc; // DevicePropertyBusTypeGuid;
931 case CM_DRP_LEGACYBUSTYPE
:
932 PlugPlayData
.Property
= 0xd; // DevicePropertyLegacyBusType;
935 case CM_DRP_BUSNUMBER
:
936 PlugPlayData
.Property
= 0xe; // DevicePropertyBusNumber;
939 case CM_DRP_ENUMERATOR_NAME
:
940 PlugPlayData
.Property
= 0xf; // DevicePropertyEnumeratorName;
944 PlugPlayData
.Property
= 0x10; // DevicePropertyAddress;
948 /* FIXME: This property is not supported by IoGetDeviceProperty */
949 case CM_DRP_DEVICE_POWER_DATA
:
952 case CM_DRP_REMOVAL_POLICY
:
953 PlugPlayData
.Property
= 0x12; // DevicePropertyRemovalPolicy
957 /* FIXME: This property is not supported by IoGetDeviceProperty */
958 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
961 case CM_DRP_INSTALL_STATE
:
962 PlugPlayData
.Property
= 0x12; // DevicePropertyInstallState;
966 /* FIXME: This property is not supported by IoGetDeviceProperty */
967 #if (WINVER >= _WIN32_WINNT_WS03)
968 case CM_DRP_LOCATION_PATHS
:
972 #if (WINVER >= _WIN32_WINNT_WIN7)
973 case CM_DRP_BASE_CONTAINERID
:
974 PlugPlayData
.Property
= 0x16; // DevicePropertyContainerID;
979 return CR_INVALID_PROPERTY
;
982 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
983 (PVOID
)&PlugPlayData
,
984 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
985 if (NT_SUCCESS(Status
))
987 *pulLength
= PlugPlayData
.BufferSize
;
991 ret
= NtStatusToCrError(Status
);
996 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1001 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1010 PNP_SetDeviceRegProp(
1016 PNP_PROP_SIZE ulLength
,
1019 CONFIGRET ret
= CR_SUCCESS
;
1020 LPWSTR lpValueName
= NULL
;
1023 UNREFERENCED_PARAMETER(hBinding
);
1024 UNREFERENCED_PARAMETER(ulFlags
);
1026 DPRINT("PNP_SetDeviceRegProp() called\n");
1028 DPRINT("DeviceId: %S\n", pDeviceId
);
1029 DPRINT("Property: %lu\n", ulProperty
);
1030 DPRINT("DataType: %lu\n", ulDataType
);
1031 DPRINT("Length: %lu\n", ulLength
);
1035 case CM_DRP_DEVICEDESC
:
1036 lpValueName
= L
"DeviceDesc";
1039 case CM_DRP_HARDWAREID
:
1040 lpValueName
= L
"HardwareID";
1043 case CM_DRP_COMPATIBLEIDS
:
1044 lpValueName
= L
"CompatibleIDs";
1047 case CM_DRP_SERVICE
:
1048 lpValueName
= L
"Service";
1052 lpValueName
= L
"Class";
1055 case CM_DRP_CLASSGUID
:
1056 lpValueName
= L
"ClassGUID";
1060 lpValueName
= L
"Driver";
1063 case CM_DRP_CONFIGFLAGS
:
1064 lpValueName
= L
"ConfigFlags";
1068 lpValueName
= L
"Mfg";
1071 case CM_DRP_FRIENDLYNAME
:
1072 lpValueName
= L
"FriendlyName";
1075 case CM_DRP_LOCATION_INFORMATION
:
1076 lpValueName
= L
"LocationInformation";
1079 case CM_DRP_UPPERFILTERS
:
1080 lpValueName
= L
"UpperFilters";
1083 case CM_DRP_LOWERFILTERS
:
1084 lpValueName
= L
"LowerFilters";
1087 case CM_DRP_SECURITY
:
1088 lpValueName
= L
"Security";
1091 case CM_DRP_DEVTYPE
:
1092 lpValueName
= L
"DeviceType";
1095 case CM_DRP_EXCLUSIVE
:
1096 lpValueName
= L
"Exclusive";
1099 case CM_DRP_CHARACTERISTICS
:
1100 lpValueName
= L
"DeviceCharacteristics";
1103 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1104 lpValueName
= L
"UINumberDescFormat";
1107 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1108 lpValueName
= L
"RemovalPolicy";
1112 return CR_INVALID_PROPERTY
;
1115 DPRINT("Value name: %S\n", lpValueName
);
1117 if (RegOpenKeyExW(hEnumKey
,
1122 return CR_INVALID_DEVNODE
;
1126 if (RegDeleteValueW(hKey
,
1128 ret
= CR_REGISTRY_ERROR
;
1132 if (RegSetValueExW(hKey
,
1138 ret
= CR_REGISTRY_ERROR
;
1143 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1152 PNP_GetClassInstance(
1155 LPWSTR pszClassInstance
,
1156 PNP_RPC_STRING_LEN ulLength
)
1159 return CR_CALL_NOT_IMPLEMENTED
;
1174 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1183 return CR_REGISTRY_ERROR
;
1185 /* FIXME: Set security key */
1196 PNP_DeleteRegistryKey(
1199 LPWSTR pszParentKey
,
1204 return CR_CALL_NOT_IMPLEMENTED
;
1213 DWORD
*pulClassCount
,
1219 UNREFERENCED_PARAMETER(hBinding
);
1220 UNREFERENCED_PARAMETER(ulFlags
);
1222 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1227 if (dwError
!= ERROR_SUCCESS
)
1228 return CR_INVALID_DATA
;
1230 dwError
= RegQueryInfoKeyW(hKey
,
1243 if (dwError
!= ERROR_SUCCESS
)
1244 return CR_INVALID_DATA
;
1255 LPWSTR pszClassGuid
,
1257 PNP_RPC_STRING_LEN
*pulLength
,
1260 WCHAR szKeyName
[MAX_PATH
];
1261 CONFIGRET ret
= CR_SUCCESS
;
1265 UNREFERENCED_PARAMETER(hBinding
);
1266 UNREFERENCED_PARAMETER(ulFlags
);
1268 DPRINT("PNP_GetClassName() called\n");
1270 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1271 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1272 lstrcatW(szKeyName
, pszClassGuid
);
1274 return CR_INVALID_DATA
;
1276 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1281 return CR_REGISTRY_ERROR
;
1283 dwSize
= *pulLength
* sizeof(WCHAR
);
1284 if (RegQueryValueExW(hKey
,
1292 ret
= CR_REGISTRY_ERROR
;
1296 *pulLength
= dwSize
/ sizeof(WCHAR
);
1301 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1312 LPWSTR pszClassGuid
,
1315 CONFIGRET ret
= CR_SUCCESS
;
1317 UNREFERENCED_PARAMETER(hBinding
);
1319 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1321 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1323 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1324 ret
= CR_REGISTRY_ERROR
;
1328 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1329 ret
= CR_REGISTRY_ERROR
;
1332 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1341 PNP_GetInterfaceDeviceAlias(
1343 LPWSTR pszInterfaceDevice
,
1344 GUID
*AliasInterfaceGuid
,
1345 LPWSTR pszAliasInterfaceDevice
,
1346 PNP_RPC_STRING_LEN
*pulLength
,
1347 PNP_RPC_STRING_LEN
*pulTransferLen
,
1351 return CR_CALL_NOT_IMPLEMENTED
;
1358 PNP_GetInterfaceDeviceList(
1360 GUID
*InterfaceGuid
,
1363 PNP_RPC_BUFFER_SIZE
*pulLength
,
1367 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1368 DWORD ret
= CR_SUCCESS
;
1370 UNREFERENCED_PARAMETER(hBinding
);
1372 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1375 PlugPlayData
.Flags
= ulFlags
;
1376 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1377 PlugPlayData
.Buffer
= Buffer
;
1378 PlugPlayData
.BufferSize
= *pulLength
;
1380 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1381 (PVOID
)&PlugPlayData
,
1382 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1383 if (NT_SUCCESS(Status
))
1385 *pulLength
= PlugPlayData
.BufferSize
;
1389 ret
= NtStatusToCrError(Status
);
1392 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1400 PNP_GetInterfaceDeviceListSize(
1402 PNP_RPC_BUFFER_SIZE
*pulLen
,
1403 GUID
*InterfaceGuid
,
1408 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1409 DWORD ret
= CR_SUCCESS
;
1411 UNREFERENCED_PARAMETER(hBinding
);
1413 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1415 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1418 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1419 PlugPlayData
.Buffer
= NULL
;
1420 PlugPlayData
.BufferSize
= 0;
1421 PlugPlayData
.Flags
= ulFlags
;
1423 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1424 (PVOID
)&PlugPlayData
,
1425 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1426 if (NT_SUCCESS(Status
))
1428 *pulLen
= PlugPlayData
.BufferSize
;
1432 ret
= NtStatusToCrError(Status
);
1435 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1443 PNP_RegisterDeviceClassAssociation(
1446 GUID
*InterfaceGuid
,
1447 LPWSTR pszReference
,
1449 PNP_RPC_STRING_LEN
*pulLength
,
1450 PNP_RPC_STRING_LEN
*pulTransferLen
,
1454 return CR_CALL_NOT_IMPLEMENTED
;
1461 PNP_UnregisterDeviceClassAssociation(
1463 LPWSTR pszInterfaceDevice
,
1467 return CR_CALL_NOT_IMPLEMENTED
;
1474 PNP_GetClassRegProp(
1476 LPWSTR pszClassGuid
,
1478 DWORD
*pulRegDataType
,
1480 PNP_RPC_STRING_LEN
*pulTransferLen
,
1481 PNP_RPC_STRING_LEN
*pulLength
,
1484 CONFIGRET ret
= CR_SUCCESS
;
1485 LPWSTR lpValueName
= NULL
;
1486 HKEY hInstKey
= NULL
;
1487 HKEY hPropKey
= NULL
;
1490 UNREFERENCED_PARAMETER(hBinding
);
1492 DPRINT("PNP_GetClassRegProp() called\n");
1494 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1496 ret
= CR_INVALID_POINTER
;
1502 ret
= CR_INVALID_FLAG
;
1506 if (*pulLength
< *pulTransferLen
)
1507 *pulLength
= *pulTransferLen
;
1509 *pulTransferLen
= 0;
1513 case CM_CRP_SECURITY
:
1514 lpValueName
= L
"Security";
1517 case CM_CRP_DEVTYPE
:
1518 lpValueName
= L
"DeviceType";
1521 case CM_CRP_EXCLUSIVE
:
1522 lpValueName
= L
"Exclusive";
1525 case CM_CRP_CHARACTERISTICS
:
1526 lpValueName
= L
"DeviceCharacteristics";
1530 ret
= CR_INVALID_PROPERTY
;
1534 DPRINT("Value name: %S\n", lpValueName
);
1536 lError
= RegOpenKeyExW(hClassKey
,
1541 if (lError
!= ERROR_SUCCESS
)
1544 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1548 lError
= RegOpenKeyExW(hInstKey
,
1553 if (lError
!= ERROR_SUCCESS
)
1556 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1560 lError
= RegQueryValueExW(hPropKey
,
1566 if (lError
!= ERROR_SUCCESS
)
1568 if (lError
== ERROR_MORE_DATA
)
1570 ret
= CR_BUFFER_SMALL
;
1575 ret
= CR_NO_SUCH_VALUE
;
1580 if (ret
== CR_SUCCESS
)
1581 *pulTransferLen
= *pulLength
;
1583 if (hPropKey
!= NULL
)
1584 RegCloseKey(hPropKey
);
1586 if (hInstKey
!= NULL
)
1587 RegCloseKey(hInstKey
);
1589 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1598 PNP_SetClassRegProp(
1600 LPWSTR pszClassGuid
,
1604 PNP_PROP_SIZE ulLength
,
1607 CONFIGRET ret
= CR_SUCCESS
;
1608 LPWSTR lpValueName
= NULL
;
1613 UNREFERENCED_PARAMETER(hBinding
);
1615 DPRINT("PNP_SetClassRegProp() called\n");
1618 return CR_INVALID_FLAG
;
1622 case CM_CRP_SECURITY
:
1623 lpValueName
= L
"Security";
1626 case CM_CRP_DEVTYPE
:
1627 lpValueName
= L
"DeviceType";
1630 case CM_CRP_EXCLUSIVE
:
1631 lpValueName
= L
"Exclusive";
1634 case CM_CRP_CHARACTERISTICS
:
1635 lpValueName
= L
"DeviceCharacteristics";
1639 return CR_INVALID_PROPERTY
;
1642 lError
= RegOpenKeyExW(hClassKey
,
1647 if (lError
!= ERROR_SUCCESS
)
1649 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1653 /* FIXME: Set security descriptor */
1654 lError
= RegCreateKeyExW(hInstKey
,
1658 REG_OPTION_NON_VOLATILE
,
1663 if (lError
!= ERROR_SUCCESS
)
1665 ret
= CR_REGISTRY_ERROR
;
1671 if (RegDeleteValueW(hPropKey
,
1673 ret
= CR_REGISTRY_ERROR
;
1677 if (RegSetValueExW(hPropKey
,
1683 ret
= CR_REGISTRY_ERROR
;
1687 if (hPropKey
!= NULL
)
1688 RegCloseKey(hPropKey
);
1690 if (hInstKey
!= NULL
)
1691 RegCloseKey(hInstKey
);
1698 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1699 OUT LPWSTR pszEnumerator
,
1700 OUT LPWSTR pszDevice
,
1701 OUT LPWSTR pszInstance
)
1703 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1704 LPWSTR lpEnumerator
= NULL
;
1705 LPWSTR lpDevice
= NULL
;
1706 LPWSTR lpInstance
= NULL
;
1709 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1715 lpEnumerator
= szLocalDeviceInstanceID
;
1717 ptr
= wcschr(lpEnumerator
, L
'\\');
1723 ptr
= wcschr(lpDevice
, L
'\\');
1731 if (lpEnumerator
!= NULL
)
1732 wcscpy(pszEnumerator
, lpEnumerator
);
1734 if (lpDevice
!= NULL
)
1735 wcscpy(pszDevice
, lpDevice
);
1737 if (lpInstance
!= NULL
)
1738 wcscpy(pszInstance
, lpInstance
);
1743 CreateDeviceInstance(LPWSTR pszDeviceID
)
1745 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1746 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1747 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1748 HKEY hKeyEnumerator
;
1754 /* Split the instance ID */
1755 SplitDeviceInstanceID(pszDeviceID
,
1760 /* Open or create the enumerator key */
1761 lError
= RegCreateKeyExW(hEnumKey
,
1765 REG_OPTION_NON_VOLATILE
,
1770 if (lError
!= ERROR_SUCCESS
)
1772 return CR_REGISTRY_ERROR
;
1775 /* Open or create the device key */
1776 lError
= RegCreateKeyExW(hKeyEnumerator
,
1780 REG_OPTION_NON_VOLATILE
,
1786 /* Close the enumerator key */
1787 RegCloseKey(hKeyEnumerator
);
1789 if (lError
!= ERROR_SUCCESS
)
1791 return CR_REGISTRY_ERROR
;
1794 /* Try to open the instance key and fail if it exists */
1795 lError
= RegOpenKeyExW(hKeyDevice
,
1800 if (lError
== ERROR_SUCCESS
)
1802 DPRINT1("Instance %S already exists!\n", szInstance
);
1803 RegCloseKey(hKeyInstance
);
1804 RegCloseKey(hKeyDevice
);
1805 return CR_ALREADY_SUCH_DEVINST
;
1808 /* Create a new instance key */
1809 lError
= RegCreateKeyExW(hKeyDevice
,
1813 REG_OPTION_NON_VOLATILE
,
1819 /* Close the device key */
1820 RegCloseKey(hKeyDevice
);
1822 if (lError
!= ERROR_SUCCESS
)
1824 return CR_REGISTRY_ERROR
;
1827 /* Create the 'Control' sub key */
1828 lError
= RegCreateKeyExW(hKeyInstance
,
1832 REG_OPTION_NON_VOLATILE
,
1837 if (lError
== ERROR_SUCCESS
)
1839 RegCloseKey(hKeyControl
);
1842 RegCloseKey(hKeyInstance
);
1844 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1854 LPWSTR pszParentDeviceID
,
1855 PNP_RPC_STRING_LEN ulLength
,
1858 CONFIGRET ret
= CR_SUCCESS
;
1860 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1862 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1864 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1865 DWORD dwInstanceNumber
;
1867 /* Generated ID is: Root\<Device ID>\<Instance number> */
1868 dwInstanceNumber
= 0;
1871 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1872 pszDeviceID
, dwInstanceNumber
);
1874 /* Try to create a device instance with this ID */
1875 ret
= CreateDeviceInstance(szGeneratedInstance
);
1879 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1881 if (ret
== CR_SUCCESS
)
1883 /* pszDeviceID is an out parameter too for generated IDs */
1884 if (wcslen(szGeneratedInstance
) > ulLength
)
1886 ret
= CR_BUFFER_SMALL
;
1890 wcscpy(pszDeviceID
, szGeneratedInstance
);
1896 /* Create the device instance */
1897 ret
= CreateDeviceInstance(pszDeviceID
);
1900 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1907 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1908 LPWSTR pszDeviceInstanceSource
)
1910 DPRINT("MoveDeviceInstance: not implemented\n");
1912 return CR_CALL_NOT_IMPLEMENTED
;
1917 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1920 DPRINT("SetupDeviceInstance: not implemented\n");
1922 return CR_CALL_NOT_IMPLEMENTED
;
1927 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1929 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1930 CONFIGRET ret
= CR_SUCCESS
;
1933 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
1935 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1936 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1937 if (!NT_SUCCESS(Status
))
1938 ret
= NtStatusToCrError(Status
);
1945 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1947 DPRINT("DisableDeviceInstance: not implemented\n");
1949 return CR_CALL_NOT_IMPLEMENTED
;
1954 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1956 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1958 return CR_CALL_NOT_IMPLEMENTED
;
1965 PNP_DeviceInstanceAction(
1969 LPWSTR pszDeviceInstance1
,
1970 LPWSTR pszDeviceInstance2
)
1972 CONFIGRET ret
= CR_SUCCESS
;
1974 UNREFERENCED_PARAMETER(hBinding
);
1976 DPRINT("PNP_DeviceInstanceAction() called\n");
1980 case PNP_DEVINST_MOVE
:
1981 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1982 pszDeviceInstance2
);
1985 case PNP_DEVINST_SETUP
:
1986 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1990 case PNP_DEVINST_ENABLE
:
1991 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1994 case PNP_DEVINST_DISABLE
:
1995 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1998 case PNP_DEVINST_REENUMERATE
:
1999 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
2003 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2004 ret
= CR_CALL_NOT_IMPLEMENTED
;
2007 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2016 PNP_GetDeviceStatus(
2023 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
2024 CONFIGRET ret
= CR_SUCCESS
;
2027 UNREFERENCED_PARAMETER(hBinding
);
2028 UNREFERENCED_PARAMETER(ulFlags
);
2030 DPRINT("PNP_GetDeviceStatus() called\n");
2032 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2034 PlugPlayData
.Operation
= 0; /* Get status */
2036 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2037 (PVOID
)&PlugPlayData
,
2038 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2039 if (NT_SUCCESS(Status
))
2041 *pulStatus
= PlugPlayData
.DeviceStatus
;
2042 *pulProblem
= PlugPlayData
.DeviceProblem
;
2046 ret
= NtStatusToCrError(Status
);
2049 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2058 PNP_SetDeviceProblem(
2065 return CR_CALL_NOT_IMPLEMENTED
;
2075 PPNP_VETO_TYPE pVetoType
,
2081 return CR_CALL_NOT_IMPLEMENTED
;
2087 PNP_UninstallDevInst(
2093 return CR_CALL_NOT_IMPLEMENTED
;
2098 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2104 lpPtr
= lpDeviceIdList
;
2107 dwLength
= wcslen(lpPtr
);
2108 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2111 lpPtr
+= (dwLength
+ 1);
2119 AppendDeviceId(LPWSTR lpDeviceIdList
,
2120 LPDWORD lpDeviceIdListSize
,
2126 dwLen
= wcslen(lpDeviceId
);
2127 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2129 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2131 dwPos
+= (dwLen
+ 1);
2133 lpDeviceIdList
[dwPos
] = 0;
2135 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2148 CONFIGRET ret
= CR_SUCCESS
;
2151 DWORD dwDeviceIdListSize
;
2152 DWORD dwNewDeviceIdSize
;
2153 WCHAR
* pszDeviceIdList
= NULL
;
2155 UNREFERENCED_PARAMETER(hBinding
);
2157 DPRINT("PNP_AddID() called\n");
2158 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2159 DPRINT(" DeviceId: %S\n", pszID
);
2160 DPRINT(" Flags: %lx\n", ulFlags
);
2162 if (RegOpenKeyExW(hEnumKey
,
2165 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2166 &hDeviceKey
) != ERROR_SUCCESS
)
2168 DPRINT("Failed to open the device key!\n");
2169 return CR_INVALID_DEVNODE
;
2172 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2174 if (RegQueryValueExW(hDeviceKey
,
2179 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2181 DPRINT("Failed to query the desired ID string!\n");
2182 ret
= CR_REGISTRY_ERROR
;
2186 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2187 if (!dwNewDeviceIdSize
)
2189 ret
= CR_INVALID_POINTER
;
2193 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2195 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2196 if (!pszDeviceIdList
)
2198 DPRINT("Failed to allocate memory for the desired ID string!\n");
2199 ret
= CR_OUT_OF_MEMORY
;
2203 if (RegQueryValueExW(hDeviceKey
,
2207 (LPBYTE
)pszDeviceIdList
,
2208 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2210 DPRINT("Failed to query the desired ID string!\n");
2211 ret
= CR_REGISTRY_ERROR
;
2215 /* Check whether the device ID is already in use */
2216 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2218 DPRINT("Device ID was found in the ID string!\n");
2223 /* Append the Device ID */
2224 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2226 if (RegSetValueExW(hDeviceKey
,
2230 (LPBYTE
)pszDeviceIdList
,
2231 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2233 DPRINT("Failed to set the desired ID string!\n");
2234 ret
= CR_REGISTRY_ERROR
;
2238 RegCloseKey(hDeviceKey
);
2239 if (pszDeviceIdList
)
2240 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2242 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2257 return CR_CALL_NOT_IMPLEMENTED
;
2267 PPNP_VETO_TYPE pVetoType
,
2273 return CR_CALL_NOT_IMPLEMENTED
;
2280 PNP_RequestDeviceEject(
2283 PPNP_VETO_TYPE pVetoType
,
2289 return CR_CALL_NOT_IMPLEMENTED
;
2296 PNP_IsDockStationPresent(
2304 CONFIGRET ret
= CR_SUCCESS
;
2306 UNREFERENCED_PARAMETER(hBinding
);
2308 DPRINT1("PNP_IsDockStationPresent() called\n");
2312 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2316 &hKey
) != ERROR_SUCCESS
)
2317 return CR_REGISTRY_ERROR
;
2319 dwSize
= sizeof(DWORD
);
2320 if (RegQueryValueExW(hKey
,
2325 &dwSize
) != ERROR_SUCCESS
)
2326 ret
= CR_REGISTRY_ERROR
;
2330 if (ret
== CR_SUCCESS
)
2332 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2334 ret
= CR_REGISTRY_ERROR
;
2336 else if (dwValue
!= 0)
2342 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2355 return CR_CALL_NOT_IMPLEMENTED
;
2368 PPNP_VETO_TYPE pVetoType
,
2373 CONFIGRET ret
= CR_SUCCESS
;
2374 WCHAR szKeyName
[MAX_PATH
];
2379 UNREFERENCED_PARAMETER(hBinding
);
2381 DPRINT("PNP_HwProfFlags() called\n");
2386 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2391 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2395 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2399 &hKey
) != ERROR_SUCCESS
)
2400 return CR_REGISTRY_ERROR
;
2402 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2404 if (RegOpenKeyExW(hKey
,
2408 &hDeviceKey
) != ERROR_SUCCESS
)
2414 dwSize
= sizeof(DWORD
);
2415 if (!RegQueryValueExW(hDeviceKey
,
2420 &dwSize
) != ERROR_SUCCESS
)
2425 RegCloseKey(hDeviceKey
);
2428 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2430 /* FIXME: not implemented yet */
2431 ret
= CR_CALL_NOT_IMPLEMENTED
;
2446 HWPROFILEINFO
*pHWProfileInfo
,
2447 DWORD ulProfileInfoSize
,
2450 WCHAR szProfileName
[5];
2451 HKEY hKeyConfig
= NULL
;
2452 HKEY hKeyProfiles
= NULL
;
2453 HKEY hKeyProfile
= NULL
;
2454 DWORD dwDisposition
;
2457 CONFIGRET ret
= CR_SUCCESS
;
2459 UNREFERENCED_PARAMETER(hBinding
);
2461 DPRINT("PNP_GetHwProfInfo() called\n");
2463 if (ulProfileInfoSize
== 0)
2465 ret
= CR_INVALID_DATA
;
2471 ret
= CR_INVALID_FLAG
;
2475 /* Initialize the profile information */
2476 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2477 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2478 pHWProfileInfo
->HWPI_dwFlags
= 0;
2480 /* Open the 'IDConfigDB' key */
2481 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2482 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2485 REG_OPTION_NON_VOLATILE
,
2490 if (lError
!= ERROR_SUCCESS
)
2492 ret
= CR_REGISTRY_ERROR
;
2496 /* Open the 'Hardware Profiles' subkey */
2497 lError
= RegCreateKeyExW(hKeyConfig
,
2498 L
"Hardware Profiles",
2501 REG_OPTION_NON_VOLATILE
,
2502 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2506 if (lError
!= ERROR_SUCCESS
)
2508 ret
= CR_REGISTRY_ERROR
;
2512 if (ulIndex
== (ULONG
)-1)
2514 dwSize
= sizeof(ULONG
);
2515 lError
= RegQueryValueExW(hKeyConfig
,
2519 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2521 if (lError
!= ERROR_SUCCESS
)
2523 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2524 ret
= CR_REGISTRY_ERROR
;
2530 /* FIXME: not implemented yet */
2531 ret
= CR_CALL_NOT_IMPLEMENTED
;
2535 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2537 lError
= RegOpenKeyExW(hKeyProfiles
,
2542 if (lError
!= ERROR_SUCCESS
)
2544 ret
= CR_REGISTRY_ERROR
;
2548 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2549 lError
= RegQueryValueExW(hKeyProfile
,
2553 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2555 if (lError
!= ERROR_SUCCESS
)
2557 ret
= CR_REGISTRY_ERROR
;
2562 if (hKeyProfile
!= NULL
)
2563 RegCloseKey(hKeyProfile
);
2565 if (hKeyProfiles
!= NULL
)
2566 RegCloseKey(hKeyProfiles
);
2568 if (hKeyConfig
!= NULL
)
2569 RegCloseKey(hKeyConfig
);
2578 PNP_AddEmptyLogConf(
2582 DWORD
*pulLogConfTag
,
2586 return CR_CALL_NOT_IMPLEMENTED
;
2596 DWORD ulLogConfType
,
2601 return CR_CALL_NOT_IMPLEMENTED
;
2608 PNP_GetFirstLogConf(
2611 DWORD ulLogConfType
,
2612 DWORD
*pulLogConfTag
,
2616 return CR_CALL_NOT_IMPLEMENTED
;
2626 DWORD ulLogConfType
,
2632 return CR_CALL_NOT_IMPLEMENTED
;
2639 PNP_GetLogConfPriority(
2648 return CR_CALL_NOT_IMPLEMENTED
;
2659 DWORD ulLogConfType
,
2660 RESOURCEID ResourceID
,
2661 DWORD
*pulResourceTag
,
2663 PNP_RPC_BUFFER_SIZE ResourceLen
,
2667 return CR_CALL_NOT_IMPLEMENTED
;
2678 DWORD ulLogConfType
,
2679 RESOURCEID ResourceID
,
2680 DWORD ulResourceTag
,
2681 DWORD
*pulPreviousResType
,
2682 DWORD
*pulPreviousResTag
,
2686 return CR_CALL_NOT_IMPLEMENTED
;
2697 DWORD ulLogConfType
,
2698 RESOURCEID ResourceID
,
2699 DWORD ulResourceTag
,
2700 DWORD
*pulNextResType
,
2701 DWORD
*pulNextResTag
,
2705 return CR_CALL_NOT_IMPLEMENTED
;
2716 DWORD ulLogConfType
,
2717 RESOURCEID ResourceID
,
2718 DWORD ulResourceTag
,
2720 PNP_RPC_BUFFER_SIZE BufferLen
,
2724 return CR_CALL_NOT_IMPLEMENTED
;
2731 PNP_GetResDesDataSize(
2735 DWORD ulLogConfType
,
2736 RESOURCEID ResourceID
,
2737 DWORD ulResourceTag
,
2742 return CR_CALL_NOT_IMPLEMENTED
;
2753 DWORD ulLogConfType
,
2754 RESOURCEID CurrentResourceID
,
2755 RESOURCEID NewResourceID
,
2756 DWORD ulResourceTag
,
2758 PNP_RPC_BUFFER_SIZE ResourceLen
,
2762 return CR_CALL_NOT_IMPLEMENTED
;
2769 PNP_DetectResourceConflict(
2772 RESOURCEID ResourceID
,
2774 PNP_RPC_BUFFER_SIZE ResourceLen
,
2775 BOOL
*pbConflictDetected
,
2779 return CR_CALL_NOT_IMPLEMENTED
;
2786 PNP_QueryResConfList(
2789 RESOURCEID ResourceID
,
2791 PNP_RPC_BUFFER_SIZE ResourceLen
,
2793 PNP_RPC_BUFFER_SIZE BufferLen
,
2797 return CR_CALL_NOT_IMPLEMENTED
;
2806 DWORD ulHardwareProfile
,
2810 return CR_CALL_NOT_IMPLEMENTED
;
2817 PNP_QueryArbitratorFreeData(
2822 RESOURCEID ResourceID
,
2826 return CR_CALL_NOT_IMPLEMENTED
;
2833 PNP_QueryArbitratorFreeSize(
2837 RESOURCEID ResourceID
,
2841 return CR_CALL_NOT_IMPLEMENTED
;
2852 return CR_CALL_NOT_IMPLEMENTED
;
2859 PNP_RegisterNotification(
2865 PNOTIFY_DATA pNotifyData
;
2868 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
2869 hBinding
, ulFlags
, pulNotify
);
2872 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
2873 if (pNotifyData
== NULL
)
2874 return CR_OUT_OF_MEMORY
;
2876 *pulNotify
= (DWORD
)pNotifyData
;
2888 PNP_UnregisterNotification(
2892 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
2893 hBinding
, ulNotify
);
2897 return CR_CALL_NOT_IMPLEMENTED
;
2907 PNP_GetCustomDevProp(
2910 LPWSTR CustomPropName
,
2911 DWORD
*pulRegDataType
,
2913 PNP_RPC_STRING_LEN
*pulTransferLen
,
2914 PNP_RPC_STRING_LEN
*pulLength
,
2917 HKEY hDeviceKey
= NULL
;
2918 HKEY hParamKey
= NULL
;
2920 CONFIGRET ret
= CR_SUCCESS
;
2922 UNREFERENCED_PARAMETER(hBinding
);
2924 DPRINT("PNP_GetCustomDevProp() called\n");
2926 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2928 ret
= CR_INVALID_POINTER
;
2932 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2934 ret
= CR_INVALID_FLAG
;
2938 if (*pulLength
< *pulTransferLen
)
2939 *pulLength
= *pulTransferLen
;
2941 *pulTransferLen
= 0;
2943 lError
= RegOpenKeyExW(hEnumKey
,
2948 if (lError
!= ERROR_SUCCESS
)
2950 ret
= CR_REGISTRY_ERROR
;
2954 lError
= RegOpenKeyExW(hDeviceKey
,
2955 L
"Device Parameters",
2959 if (lError
!= ERROR_SUCCESS
)
2961 ret
= CR_REGISTRY_ERROR
;
2965 lError
= RegQueryValueExW(hParamKey
,
2971 if (lError
!= ERROR_SUCCESS
)
2973 if (lError
== ERROR_MORE_DATA
)
2975 ret
= CR_BUFFER_SMALL
;
2980 ret
= CR_NO_SUCH_VALUE
;
2985 if (ret
== CR_SUCCESS
)
2986 *pulTransferLen
= *pulLength
;
2988 if (hParamKey
!= NULL
)
2989 RegCloseKey(hParamKey
);
2991 if (hDeviceKey
!= NULL
)
2992 RegCloseKey(hDeviceKey
);
2994 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3003 PNP_GetVersionInternal(
3015 PNP_GetBlockedDriverInfo(
3018 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3019 PNP_RPC_BUFFER_SIZE
*pulLength
,
3023 return CR_CALL_NOT_IMPLEMENTED
;
3030 PNP_GetServerSideDeviceInstallFlags(
3032 DWORD
*pulSSDIFlags
,
3036 return CR_CALL_NOT_IMPLEMENTED
;
3043 PNP_GetObjectPropKeys(
3047 LPWSTR PropertyCultureName
,
3048 PNP_PROP_COUNT
*PropertyCount
,
3049 PNP_PROP_COUNT
*TransferLen
,
3050 DEVPROPKEY
*PropertyKeys
,
3054 return CR_CALL_NOT_IMPLEMENTED
;
3065 LPWSTR PropertyCultureName
,
3066 const DEVPROPKEY
*PropertyKey
,
3067 DEVPROPTYPE
*PropertyType
,
3068 PNP_PROP_SIZE
*PropertySize
,
3069 PNP_PROP_SIZE
*TransferLen
,
3070 BYTE
*PropertyBuffer
,
3074 return CR_CALL_NOT_IMPLEMENTED
;
3085 LPWSTR PropertyCultureName
,
3086 const DEVPROPKEY
*PropertyKey
,
3087 DEVPROPTYPE PropertyType
,
3088 PNP_PROP_SIZE PropertySize
,
3089 BYTE
*PropertyBuffer
,
3093 return CR_CALL_NOT_IMPLEMENTED
;
3104 return CR_CALL_NOT_IMPLEMENTED
;
3111 PNP_ApplyPowerSettings(
3115 return CR_CALL_NOT_IMPLEMENTED
;
3122 PNP_DriverStoreAddDriverPackage(
3126 return CR_CALL_NOT_IMPLEMENTED
;
3133 PNP_DriverStoreDeleteDriverPackage(
3137 return CR_CALL_NOT_IMPLEMENTED
;
3144 PNP_RegisterServiceNotification(
3148 return CR_CALL_NOT_IMPLEMENTED
;
3155 PNP_SetActiveService(
3161 return CR_CALL_NOT_IMPLEMENTED
;
3168 PNP_DeleteServiceDevices(
3172 return CR_CALL_NOT_IMPLEMENTED
;
3177 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3179 BOOL DeviceInstalled
= FALSE
;
3182 HANDLE hInstallEvent
;
3183 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3184 LPVOID Environment
= NULL
;
3185 PROCESS_INFORMATION ProcessInfo
;
3186 STARTUPINFOW StartupInfo
;
3190 /* The following lengths are constant (see below), they cannot overflow */
3191 WCHAR CommandLine
[116];
3192 WCHAR InstallEventName
[73];
3194 WCHAR UuidString
[39];
3196 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3198 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3200 if (RegOpenKeyExW(hEnumKey
,
3204 &DeviceKey
) == ERROR_SUCCESS
)
3206 if (RegQueryValueExW(DeviceKey
,
3211 NULL
) == ERROR_SUCCESS
)
3213 DPRINT("No need to install: %S\n", DeviceInstance
);
3214 RegCloseKey(DeviceKey
);
3218 RegCloseKey(DeviceKey
);
3221 DPRINT1("Installing: %S\n", DeviceInstance
);
3223 /* Create a random UUID for the named pipe & event*/
3224 UuidCreate(&RandomUuid
);
3225 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3226 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3227 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3228 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3229 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3231 /* Create the event */
3232 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3233 wcscat(InstallEventName
, UuidString
);
3234 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3237 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3241 /* Create the named pipe */
3242 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3243 wcscat(PipeName
, UuidString
);
3244 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3245 if (hPipe
== INVALID_HANDLE_VALUE
)
3247 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3251 /* Launch rundll32 to call ClientSideInstallW */
3252 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3253 wcscat(CommandLine
, PipeName
);
3255 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3256 StartupInfo
.cb
= sizeof(StartupInfo
);
3260 /* newdev has to run under the environment of the current user */
3261 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3263 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3267 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3269 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3275 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3277 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3278 (ShowWizard is only set to FALSE for these two modes) */
3279 ASSERT(!ShowWizard
);
3281 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3283 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3288 /* Wait for the function to connect to our pipe */
3289 if (!ConnectNamedPipe(hPipe
, NULL
))
3291 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3293 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3298 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3299 Value
= sizeof(InstallEventName
);
3300 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3301 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3303 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3304 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3305 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3307 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3308 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3309 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3311 /* Wait for newdev.dll to finish processing */
3312 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3314 /* If the event got signalled, this is success */
3315 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3319 CloseHandle(hInstallEvent
);
3321 if (hPipe
!= INVALID_HANDLE_VALUE
)
3325 DestroyEnvironmentBlock(Environment
);
3327 if (ProcessInfo
.hProcess
)
3328 CloseHandle(ProcessInfo
.hProcess
);
3330 if (ProcessInfo
.hThread
)
3331 CloseHandle(ProcessInfo
.hThread
);
3333 if (!DeviceInstalled
)
3335 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3338 return DeviceInstalled
;
3354 return ERROR_INVALID_PARAMETER
;
3357 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3358 if (rc
!= ERROR_SUCCESS
)
3360 if (dwType
!= REG_SZ
)
3361 return ERROR_FILE_NOT_FOUND
;
3362 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3364 return ERROR_NOT_ENOUGH_MEMORY
;
3365 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3366 if (rc
!= ERROR_SUCCESS
)
3368 HeapFree(GetProcessHeap(), 0, Value
);
3371 /* NULL-terminate the string */
3372 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3375 return ERROR_SUCCESS
;
3383 DWORD regType
, active
, size
;
3387 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3388 if (rc
!= ERROR_SUCCESS
)
3391 size
= sizeof(DWORD
);
3392 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3393 if (rc
!= ERROR_SUCCESS
)
3395 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3398 ret
= (active
!= 0);
3404 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3413 HKEY ControlKey
= NULL
;
3414 LPWSTR SystemStartOptions
= NULL
;
3415 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3416 BOOL ConsoleBoot
= FALSE
;
3421 L
"SYSTEM\\CurrentControlSet\\Control",
3426 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3427 if (rc
!= ERROR_SUCCESS
)
3430 /* Check for CONSOLE switch in SystemStartOptions */
3431 CurrentOption
= SystemStartOptions
;
3432 while (CurrentOption
)
3434 NextOption
= wcschr(CurrentOption
, L
' ');
3436 *NextOption
= L
'\0';
3437 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3439 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3443 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3447 if (ControlKey
!= NULL
)
3448 RegCloseKey(ControlKey
);
3449 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3454 /* Loop to install all queued devices installations */
3456 DeviceInstallThread(LPVOID lpParameter
)
3458 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3459 PSLIST_ENTRY ListEntry
;
3461 PLIST_ENTRY ListEntry
;
3463 DeviceInstallParams
* Params
;
3466 UNREFERENCED_PARAMETER(lpParameter
);
3468 WaitForSingleObject(hInstallEvent
, INFINITE
);
3470 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3474 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3475 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3477 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3480 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3482 if (ListEntry
== NULL
)
3484 SetEvent(hNoPendingInstalls
);
3485 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3489 ResetEvent(hNoPendingInstalls
);
3490 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3491 InstallDevice(Params
->DeviceIds
, showWizard
);
3500 PnpEventThread(LPVOID lpParameter
)
3502 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3505 RPC_STATUS RpcStatus
;
3507 UNREFERENCED_PARAMETER(lpParameter
);
3509 PnpEventSize
= 0x1000;
3510 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3511 if (PnpEvent
== NULL
)
3512 return ERROR_OUTOFMEMORY
;
3516 DPRINT("Calling NtGetPlugPlayEvent()\n");
3518 /* Wait for the next pnp event */
3519 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3521 /* Resize the buffer for the PnP event if it's too small. */
3522 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3524 PnpEventSize
+= 0x400;
3525 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3526 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3527 if (PnpEvent
== NULL
)
3528 return ERROR_OUTOFMEMORY
;
3532 if (!NT_SUCCESS(Status
))
3534 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3538 /* Process the pnp event */
3539 DPRINT("Received PnP Event\n");
3540 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3542 DeviceInstallParams
* Params
;
3544 DWORD DeviceIdLength
;
3546 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3548 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3551 /* Queue device install (will be dequeued by DeviceInstallThread */
3552 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3553 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3556 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3557 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3558 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3560 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3562 SetEvent(hDeviceInstallListNotEmpty
);
3566 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3568 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3571 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3573 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3575 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3577 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3579 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3581 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3583 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3585 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3587 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3589 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3591 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3593 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3597 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3598 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3599 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3600 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3601 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3604 /* Dequeue the current pnp event and signal the next one */
3605 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3608 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3610 return ERROR_SUCCESS
;
3615 UpdateServiceStatus(DWORD dwState
)
3617 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3618 ServiceStatus
.dwCurrentState
= dwState
;
3619 ServiceStatus
.dwControlsAccepted
= 0;
3620 ServiceStatus
.dwWin32ExitCode
= 0;
3621 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3622 ServiceStatus
.dwCheckPoint
= 0;
3624 if (dwState
== SERVICE_START_PENDING
||
3625 dwState
== SERVICE_STOP_PENDING
||
3626 dwState
== SERVICE_PAUSE_PENDING
||
3627 dwState
== SERVICE_CONTINUE_PENDING
)
3628 ServiceStatus
.dwWaitHint
= 10000;
3630 ServiceStatus
.dwWaitHint
= 0;
3632 SetServiceStatus(ServiceStatusHandle
,
3638 ServiceControlHandler(DWORD dwControl
,
3643 DPRINT1("ServiceControlHandler() called\n");
3647 case SERVICE_CONTROL_STOP
:
3648 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3649 /* Stop listening to RPC Messages */
3650 RpcMgmtStopServerListening(NULL
);
3651 UpdateServiceStatus(SERVICE_STOPPED
);
3652 return ERROR_SUCCESS
;
3654 case SERVICE_CONTROL_PAUSE
:
3655 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3656 UpdateServiceStatus(SERVICE_PAUSED
);
3657 return ERROR_SUCCESS
;
3659 case SERVICE_CONTROL_CONTINUE
:
3660 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3661 UpdateServiceStatus(SERVICE_RUNNING
);
3662 return ERROR_SUCCESS
;
3664 case SERVICE_CONTROL_INTERROGATE
:
3665 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3666 SetServiceStatus(ServiceStatusHandle
,
3668 return ERROR_SUCCESS
;
3670 case SERVICE_CONTROL_SHUTDOWN
:
3671 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3672 /* Stop listening to RPC Messages */
3673 RpcMgmtStopServerListening(NULL
);
3674 UpdateServiceStatus(SERVICE_STOPPED
);
3675 return ERROR_SUCCESS
;
3678 DPRINT1(" Control %lu received\n", dwControl
);
3679 return ERROR_CALL_NOT_IMPLEMENTED
;
3685 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3690 UNREFERENCED_PARAMETER(argc
);
3691 UNREFERENCED_PARAMETER(argv
);
3693 DPRINT("ServiceMain() called\n");
3695 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3696 ServiceControlHandler
,
3698 if (!ServiceStatusHandle
)
3700 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3704 UpdateServiceStatus(SERVICE_START_PENDING
);
3706 hThread
= CreateThread(NULL
,
3712 if (hThread
!= NULL
)
3713 CloseHandle(hThread
);
3715 hThread
= CreateThread(NULL
,
3721 if (hThread
!= NULL
)
3722 CloseHandle(hThread
);
3724 hThread
= CreateThread(NULL
,
3726 DeviceInstallThread
,
3730 if (hThread
!= NULL
)
3731 CloseHandle(hThread
);
3733 UpdateServiceStatus(SERVICE_RUNNING
);
3735 DPRINT("ServiceMain() done\n");
3739 InitializePnPManager(VOID
)
3744 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3746 /* We need this privilege for using CreateProcessAsUserW */
3747 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3749 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3750 if (hInstallEvent
== NULL
)
3752 dwError
= GetLastError();
3753 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3757 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3758 if (hDeviceInstallListNotEmpty
== NULL
)
3760 dwError
= GetLastError();
3761 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3765 hNoPendingInstalls
= CreateEventW(NULL
,
3768 L
"Global\\PnP_No_Pending_Install_Events");
3769 if (hNoPendingInstalls
== NULL
)
3771 dwError
= GetLastError();
3772 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3776 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3777 InitializeSListHead(&DeviceInstallListHead
);
3779 InitializeListHead(&DeviceInstallListHead
);
3782 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3783 L
"System\\CurrentControlSet\\Enum",
3787 if (dwError
!= ERROR_SUCCESS
)
3789 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3793 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3794 L
"System\\CurrentControlSet\\Control\\Class",
3798 if (dwError
!= ERROR_SUCCESS
)
3800 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3804 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3810 DllMain(HINSTANCE hinstDLL
,
3816 case DLL_PROCESS_ATTACH
:
3817 DisableThreadLibraryCalls(hinstDLL
);
3818 InitializePnPManager();
3821 case DLL_PROCESS_DETACH
: