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_SUCCESS
;
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)
504 // return CR_INVALID_POINTER;
507 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
508 CM_GETIDLIST_FILTER_POWERRELATIONS
|
509 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
510 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
512 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
514 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
516 PlugPlayData
.Relations
= 3;
518 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
520 PlugPlayData
.Relations
= 2;
522 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
524 PlugPlayData
.Relations
= 1;
526 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
528 PlugPlayData
.Relations
= 0;
531 PlugPlayData
.BufferSize
= *pulLength
* sizeof(WCHAR
);
532 PlugPlayData
.Buffer
= Buffer
;
534 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
535 (PVOID
)&PlugPlayData
,
536 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
537 if (NT_SUCCESS(Status
))
539 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
543 ret
= NtStatusToCrError(Status
);
546 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
548 ret
= CR_CALL_NOT_IMPLEMENTED
;
550 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
552 ret
= CR_CALL_NOT_IMPLEMENTED
;
554 else /* CM_GETIDLIST_FILTER_NONE */
556 ret
= CR_CALL_NOT_IMPLEMENTED
;
566 PNP_GetDeviceListSize(
569 PNP_RPC_BUFFER_SIZE
*pulLength
,
572 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
573 CONFIGRET ret
= CR_SUCCESS
;
576 DPRINT("PNP_GetDeviceListSize() called\n");
578 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
579 return CR_INVALID_FLAG
;
581 if (pulLength
== NULL
|| pszFilter
== NULL
)
582 return CR_INVALID_POINTER
;
587 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
588 CM_GETIDLIST_FILTER_POWERRELATIONS
|
589 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
590 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
592 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
594 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
596 PlugPlayData
.Relations
= 3;
598 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
600 PlugPlayData
.Relations
= 2;
602 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
604 PlugPlayData
.Relations
= 1;
606 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
608 PlugPlayData
.Relations
= 0;
611 PlugPlayData
.BufferSize
= 0;
612 PlugPlayData
.Buffer
= NULL
;
614 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
615 (PVOID
)&PlugPlayData
,
616 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
617 if (NT_SUCCESS(Status
))
619 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
623 ret
= NtStatusToCrError(Status
);
626 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
628 ret
= CR_CALL_NOT_IMPLEMENTED
;
630 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
632 ret
= CR_CALL_NOT_IMPLEMENTED
;
634 else /* CM_GETIDLIST_FILTER_NONE */
636 ret
= CR_CALL_NOT_IMPLEMENTED
;
652 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
653 CONFIGRET ret
= CR_SUCCESS
;
656 UNREFERENCED_PARAMETER(hBinding
);
657 UNREFERENCED_PARAMETER(ulFlags
);
659 DPRINT("PNP_GetDepth() called\n");
661 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
664 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
665 (PVOID
)&PlugPlayData
,
666 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
667 if (NT_SUCCESS(Status
))
669 *pulDepth
= PlugPlayData
.Depth
;
673 ret
= NtStatusToCrError(Status
);
676 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
685 PNP_GetDeviceRegProp(
689 DWORD
*pulRegDataType
,
691 PNP_PROP_SIZE
*pulTransferLen
,
692 PNP_PROP_SIZE
*pulLength
,
695 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
696 CONFIGRET ret
= CR_SUCCESS
;
697 LPWSTR lpValueName
= NULL
;
702 UNREFERENCED_PARAMETER(hBinding
);
704 DPRINT("PNP_GetDeviceRegProp() called\n");
706 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
708 ret
= CR_INVALID_POINTER
;
714 ret
= CR_INVALID_FLAG
;
718 /* FIXME: Check pDeviceID */
720 if (*pulLength
< *pulTransferLen
)
721 *pulLength
= *pulTransferLen
;
727 case CM_DRP_DEVICEDESC
:
728 lpValueName
= L
"DeviceDesc";
731 case CM_DRP_HARDWAREID
:
732 lpValueName
= L
"HardwareID";
735 case CM_DRP_COMPATIBLEIDS
:
736 lpValueName
= L
"CompatibleIDs";
740 lpValueName
= L
"Service";
744 lpValueName
= L
"Class";
747 case CM_DRP_CLASSGUID
:
748 lpValueName
= L
"ClassGUID";
752 lpValueName
= L
"Driver";
755 case CM_DRP_CONFIGFLAGS
:
756 lpValueName
= L
"ConfigFlags";
760 lpValueName
= L
"Mfg";
763 case CM_DRP_FRIENDLYNAME
:
764 lpValueName
= L
"FriendlyName";
767 case CM_DRP_LOCATION_INFORMATION
:
768 lpValueName
= L
"LocationInformation";
771 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
775 case CM_DRP_CAPABILITIES
:
776 lpValueName
= L
"Capabilities";
779 case CM_DRP_UI_NUMBER
:
783 case CM_DRP_UPPERFILTERS
:
784 lpValueName
= L
"UpperFilters";
787 case CM_DRP_LOWERFILTERS
:
788 lpValueName
= L
"LowerFilters";
791 case CM_DRP_BUSTYPEGUID
:
795 case CM_DRP_LEGACYBUSTYPE
:
799 case CM_DRP_BUSNUMBER
:
803 case CM_DRP_ENUMERATOR_NAME
:
807 case CM_DRP_SECURITY
:
808 lpValueName
= L
"Security";
812 lpValueName
= L
"DeviceType";
815 case CM_DRP_EXCLUSIVE
:
816 lpValueName
= L
"Exclusive";
819 case CM_DRP_CHARACTERISTICS
:
820 lpValueName
= L
"DeviceCharacteristics";
827 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
828 lpValueName
= L
"UINumberDescFormat";
831 case CM_DRP_DEVICE_POWER_DATA
:
835 case CM_DRP_REMOVAL_POLICY
:
839 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
843 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
844 lpValueName
= L
"RemovalPolicy";
847 case CM_DRP_INSTALL_STATE
:
851 #if (WINVER >= _WIN32_WINNT_WS03)
852 case CM_DRP_LOCATION_PATHS
:
857 #if (WINVER >= _WIN32_WINNT_WIN7)
858 case CM_DRP_BASE_CONTAINERID
:
864 ret
= CR_INVALID_PROPERTY
;
868 DPRINT("Value name: %S\n", lpValueName
);
872 /* Retrieve information from the Registry */
873 lError
= RegOpenKeyExW(hEnumKey
,
878 if (lError
!= ERROR_SUCCESS
)
882 ret
= CR_INVALID_DEVNODE
;
886 lError
= RegQueryValueExW(hKey
,
892 if (lError
!= ERROR_SUCCESS
)
894 if (lError
== ERROR_MORE_DATA
)
896 ret
= CR_BUFFER_SMALL
;
901 ret
= CR_NO_SUCH_VALUE
;
907 /* Retrieve information from the Device Node */
908 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
910 PlugPlayData
.Buffer
= Buffer
;
911 PlugPlayData
.BufferSize
= *pulLength
;
915 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
916 PlugPlayData
.Property
= 0xb; // DevicePropertyPhysicalDeviceObjectName;
919 case CM_DRP_UI_NUMBER
:
920 PlugPlayData
.Property
= 0x11; // DevicePropertyUINumber;
923 case CM_DRP_BUSTYPEGUID
:
924 PlugPlayData
.Property
= 0xc; // DevicePropertyBusTypeGuid;
927 case CM_DRP_LEGACYBUSTYPE
:
928 PlugPlayData
.Property
= 0xd; // DevicePropertyLegacyBusType;
931 case CM_DRP_BUSNUMBER
:
932 PlugPlayData
.Property
= 0xe; // DevicePropertyBusNumber;
935 case CM_DRP_ENUMERATOR_NAME
:
936 PlugPlayData
.Property
= 0xf; // DevicePropertyEnumeratorName;
940 PlugPlayData
.Property
= 0x10; // DevicePropertyAddress;
944 /* FIXME: This property is not supported by IoGetDeviceProperty */
945 case CM_DRP_DEVICE_POWER_DATA
:
948 case CM_DRP_REMOVAL_POLICY
:
949 PlugPlayData
.Property
= 0x13; // DevicePropertyRemovalPolicy
953 /* FIXME: This property is not supported by IoGetDeviceProperty */
954 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
957 case CM_DRP_INSTALL_STATE
:
958 PlugPlayData
.Property
= 0x12; // DevicePropertyInstallState;
962 /* FIXME: This property is not supported by IoGetDeviceProperty */
963 #if (WINVER >= _WIN32_WINNT_WS03)
964 case CM_DRP_LOCATION_PATHS
:
968 #if (WINVER >= _WIN32_WINNT_WIN7)
969 case CM_DRP_BASE_CONTAINERID
:
970 PlugPlayData
.Property
= 0x16; // DevicePropertyContainerID;
975 return CR_INVALID_PROPERTY
;
978 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
979 (PVOID
)&PlugPlayData
,
980 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
981 if (NT_SUCCESS(Status
))
983 *pulLength
= PlugPlayData
.BufferSize
;
987 ret
= NtStatusToCrError(Status
);
994 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
999 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1008 PNP_SetDeviceRegProp(
1014 PNP_PROP_SIZE ulLength
,
1017 CONFIGRET ret
= CR_SUCCESS
;
1018 LPWSTR lpValueName
= NULL
;
1021 UNREFERENCED_PARAMETER(hBinding
);
1022 UNREFERENCED_PARAMETER(ulFlags
);
1024 DPRINT("PNP_SetDeviceRegProp() called\n");
1026 DPRINT("DeviceId: %S\n", pDeviceId
);
1027 DPRINT("Property: %lu\n", ulProperty
);
1028 DPRINT("DataType: %lu\n", ulDataType
);
1029 DPRINT("Length: %lu\n", ulLength
);
1033 case CM_DRP_DEVICEDESC
:
1034 lpValueName
= L
"DeviceDesc";
1037 case CM_DRP_HARDWAREID
:
1038 lpValueName
= L
"HardwareID";
1041 case CM_DRP_COMPATIBLEIDS
:
1042 lpValueName
= L
"CompatibleIDs";
1045 case CM_DRP_SERVICE
:
1046 lpValueName
= L
"Service";
1050 lpValueName
= L
"Class";
1053 case CM_DRP_CLASSGUID
:
1054 lpValueName
= L
"ClassGUID";
1058 lpValueName
= L
"Driver";
1061 case CM_DRP_CONFIGFLAGS
:
1062 lpValueName
= L
"ConfigFlags";
1066 lpValueName
= L
"Mfg";
1069 case CM_DRP_FRIENDLYNAME
:
1070 lpValueName
= L
"FriendlyName";
1073 case CM_DRP_LOCATION_INFORMATION
:
1074 lpValueName
= L
"LocationInformation";
1077 case CM_DRP_UPPERFILTERS
:
1078 lpValueName
= L
"UpperFilters";
1081 case CM_DRP_LOWERFILTERS
:
1082 lpValueName
= L
"LowerFilters";
1085 case CM_DRP_SECURITY
:
1086 lpValueName
= L
"Security";
1089 case CM_DRP_DEVTYPE
:
1090 lpValueName
= L
"DeviceType";
1093 case CM_DRP_EXCLUSIVE
:
1094 lpValueName
= L
"Exclusive";
1097 case CM_DRP_CHARACTERISTICS
:
1098 lpValueName
= L
"DeviceCharacteristics";
1101 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1102 lpValueName
= L
"UINumberDescFormat";
1105 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1106 lpValueName
= L
"RemovalPolicy";
1110 return CR_INVALID_PROPERTY
;
1113 DPRINT("Value name: %S\n", lpValueName
);
1115 if (RegOpenKeyExW(hEnumKey
,
1120 return CR_INVALID_DEVNODE
;
1124 if (RegDeleteValueW(hKey
,
1126 ret
= CR_REGISTRY_ERROR
;
1130 if (RegSetValueExW(hKey
,
1136 ret
= CR_REGISTRY_ERROR
;
1141 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1150 PNP_GetClassInstance(
1153 LPWSTR pszClassInstance
,
1154 PNP_RPC_STRING_LEN ulLength
)
1157 return CR_CALL_NOT_IMPLEMENTED
;
1172 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1181 return CR_REGISTRY_ERROR
;
1183 /* FIXME: Set security key */
1194 PNP_DeleteRegistryKey(
1197 LPWSTR pszParentKey
,
1202 return CR_CALL_NOT_IMPLEMENTED
;
1211 DWORD
*pulClassCount
,
1217 UNREFERENCED_PARAMETER(hBinding
);
1218 UNREFERENCED_PARAMETER(ulFlags
);
1220 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1225 if (dwError
!= ERROR_SUCCESS
)
1226 return CR_INVALID_DATA
;
1228 dwError
= RegQueryInfoKeyW(hKey
,
1241 if (dwError
!= ERROR_SUCCESS
)
1242 return CR_INVALID_DATA
;
1253 LPWSTR pszClassGuid
,
1255 PNP_RPC_STRING_LEN
*pulLength
,
1258 WCHAR szKeyName
[MAX_PATH
];
1259 CONFIGRET ret
= CR_SUCCESS
;
1263 UNREFERENCED_PARAMETER(hBinding
);
1264 UNREFERENCED_PARAMETER(ulFlags
);
1266 DPRINT("PNP_GetClassName() called\n");
1268 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1269 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1270 lstrcatW(szKeyName
, pszClassGuid
);
1272 return CR_INVALID_DATA
;
1274 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1279 return CR_REGISTRY_ERROR
;
1281 dwSize
= *pulLength
* sizeof(WCHAR
);
1282 if (RegQueryValueExW(hKey
,
1290 ret
= CR_REGISTRY_ERROR
;
1294 *pulLength
= dwSize
/ sizeof(WCHAR
);
1299 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1310 LPWSTR pszClassGuid
,
1313 CONFIGRET ret
= CR_SUCCESS
;
1315 UNREFERENCED_PARAMETER(hBinding
);
1317 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1319 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1321 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1322 ret
= CR_REGISTRY_ERROR
;
1326 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1327 ret
= CR_REGISTRY_ERROR
;
1330 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1339 PNP_GetInterfaceDeviceAlias(
1341 LPWSTR pszInterfaceDevice
,
1342 GUID
*AliasInterfaceGuid
,
1343 LPWSTR pszAliasInterfaceDevice
,
1344 PNP_RPC_STRING_LEN
*pulLength
,
1345 PNP_RPC_STRING_LEN
*pulTransferLen
,
1349 return CR_CALL_NOT_IMPLEMENTED
;
1356 PNP_GetInterfaceDeviceList(
1358 GUID
*InterfaceGuid
,
1361 PNP_RPC_BUFFER_SIZE
*pulLength
,
1365 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1366 DWORD ret
= CR_SUCCESS
;
1368 UNREFERENCED_PARAMETER(hBinding
);
1370 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1373 PlugPlayData
.Flags
= ulFlags
;
1374 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1375 PlugPlayData
.Buffer
= Buffer
;
1376 PlugPlayData
.BufferSize
= *pulLength
;
1378 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1379 (PVOID
)&PlugPlayData
,
1380 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1381 if (NT_SUCCESS(Status
))
1383 *pulLength
= PlugPlayData
.BufferSize
;
1387 ret
= NtStatusToCrError(Status
);
1390 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1398 PNP_GetInterfaceDeviceListSize(
1400 PNP_RPC_BUFFER_SIZE
*pulLen
,
1401 GUID
*InterfaceGuid
,
1406 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1407 DWORD ret
= CR_SUCCESS
;
1409 UNREFERENCED_PARAMETER(hBinding
);
1411 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1413 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1416 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1417 PlugPlayData
.Buffer
= NULL
;
1418 PlugPlayData
.BufferSize
= 0;
1419 PlugPlayData
.Flags
= ulFlags
;
1421 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1422 (PVOID
)&PlugPlayData
,
1423 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1424 if (NT_SUCCESS(Status
))
1426 *pulLen
= PlugPlayData
.BufferSize
;
1430 ret
= NtStatusToCrError(Status
);
1433 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1441 PNP_RegisterDeviceClassAssociation(
1444 GUID
*InterfaceGuid
,
1445 LPWSTR pszReference
,
1447 PNP_RPC_STRING_LEN
*pulLength
,
1448 PNP_RPC_STRING_LEN
*pulTransferLen
,
1452 return CR_CALL_NOT_IMPLEMENTED
;
1459 PNP_UnregisterDeviceClassAssociation(
1461 LPWSTR pszInterfaceDevice
,
1465 return CR_CALL_NOT_IMPLEMENTED
;
1472 PNP_GetClassRegProp(
1474 LPWSTR pszClassGuid
,
1476 DWORD
*pulRegDataType
,
1478 PNP_RPC_STRING_LEN
*pulTransferLen
,
1479 PNP_RPC_STRING_LEN
*pulLength
,
1482 CONFIGRET ret
= CR_SUCCESS
;
1483 LPWSTR lpValueName
= NULL
;
1484 HKEY hInstKey
= NULL
;
1485 HKEY hPropKey
= NULL
;
1488 UNREFERENCED_PARAMETER(hBinding
);
1490 DPRINT("PNP_GetClassRegProp() called\n");
1492 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1494 ret
= CR_INVALID_POINTER
;
1500 ret
= CR_INVALID_FLAG
;
1504 if (*pulLength
< *pulTransferLen
)
1505 *pulLength
= *pulTransferLen
;
1507 *pulTransferLen
= 0;
1511 case CM_CRP_SECURITY
:
1512 lpValueName
= L
"Security";
1515 case CM_CRP_DEVTYPE
:
1516 lpValueName
= L
"DeviceType";
1519 case CM_CRP_EXCLUSIVE
:
1520 lpValueName
= L
"Exclusive";
1523 case CM_CRP_CHARACTERISTICS
:
1524 lpValueName
= L
"DeviceCharacteristics";
1528 ret
= CR_INVALID_PROPERTY
;
1532 DPRINT("Value name: %S\n", lpValueName
);
1534 lError
= RegOpenKeyExW(hClassKey
,
1539 if (lError
!= ERROR_SUCCESS
)
1542 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1546 lError
= RegOpenKeyExW(hInstKey
,
1551 if (lError
!= ERROR_SUCCESS
)
1554 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1558 lError
= RegQueryValueExW(hPropKey
,
1564 if (lError
!= ERROR_SUCCESS
)
1566 if (lError
== ERROR_MORE_DATA
)
1568 ret
= CR_BUFFER_SMALL
;
1573 ret
= CR_NO_SUCH_VALUE
;
1578 if (ret
== CR_SUCCESS
)
1579 *pulTransferLen
= *pulLength
;
1581 if (hPropKey
!= NULL
)
1582 RegCloseKey(hPropKey
);
1584 if (hInstKey
!= NULL
)
1585 RegCloseKey(hInstKey
);
1587 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1596 PNP_SetClassRegProp(
1598 LPWSTR pszClassGuid
,
1602 PNP_PROP_SIZE ulLength
,
1605 CONFIGRET ret
= CR_SUCCESS
;
1606 LPWSTR lpValueName
= NULL
;
1611 UNREFERENCED_PARAMETER(hBinding
);
1613 DPRINT("PNP_SetClassRegProp() called\n");
1616 return CR_INVALID_FLAG
;
1620 case CM_CRP_SECURITY
:
1621 lpValueName
= L
"Security";
1624 case CM_CRP_DEVTYPE
:
1625 lpValueName
= L
"DeviceType";
1628 case CM_CRP_EXCLUSIVE
:
1629 lpValueName
= L
"Exclusive";
1632 case CM_CRP_CHARACTERISTICS
:
1633 lpValueName
= L
"DeviceCharacteristics";
1637 return CR_INVALID_PROPERTY
;
1640 lError
= RegOpenKeyExW(hClassKey
,
1645 if (lError
!= ERROR_SUCCESS
)
1647 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1651 /* FIXME: Set security descriptor */
1652 lError
= RegCreateKeyExW(hInstKey
,
1656 REG_OPTION_NON_VOLATILE
,
1661 if (lError
!= ERROR_SUCCESS
)
1663 ret
= CR_REGISTRY_ERROR
;
1669 if (RegDeleteValueW(hPropKey
,
1671 ret
= CR_REGISTRY_ERROR
;
1675 if (RegSetValueExW(hPropKey
,
1681 ret
= CR_REGISTRY_ERROR
;
1685 if (hPropKey
!= NULL
)
1686 RegCloseKey(hPropKey
);
1688 if (hInstKey
!= NULL
)
1689 RegCloseKey(hInstKey
);
1696 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1697 OUT LPWSTR pszEnumerator
,
1698 OUT LPWSTR pszDevice
,
1699 OUT LPWSTR pszInstance
)
1701 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1702 LPWSTR lpEnumerator
= NULL
;
1703 LPWSTR lpDevice
= NULL
;
1704 LPWSTR lpInstance
= NULL
;
1707 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1713 lpEnumerator
= szLocalDeviceInstanceID
;
1715 ptr
= wcschr(lpEnumerator
, L
'\\');
1721 ptr
= wcschr(lpDevice
, L
'\\');
1729 if (lpEnumerator
!= NULL
)
1730 wcscpy(pszEnumerator
, lpEnumerator
);
1732 if (lpDevice
!= NULL
)
1733 wcscpy(pszDevice
, lpDevice
);
1735 if (lpInstance
!= NULL
)
1736 wcscpy(pszInstance
, lpInstance
);
1741 CreateDeviceInstance(LPWSTR pszDeviceID
)
1743 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1744 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1745 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1746 HKEY hKeyEnumerator
;
1752 /* Split the instance ID */
1753 SplitDeviceInstanceID(pszDeviceID
,
1758 /* Open or create the enumerator key */
1759 lError
= RegCreateKeyExW(hEnumKey
,
1763 REG_OPTION_NON_VOLATILE
,
1768 if (lError
!= ERROR_SUCCESS
)
1770 return CR_REGISTRY_ERROR
;
1773 /* Open or create the device key */
1774 lError
= RegCreateKeyExW(hKeyEnumerator
,
1778 REG_OPTION_NON_VOLATILE
,
1784 /* Close the enumerator key */
1785 RegCloseKey(hKeyEnumerator
);
1787 if (lError
!= ERROR_SUCCESS
)
1789 return CR_REGISTRY_ERROR
;
1792 /* Try to open the instance key and fail if it exists */
1793 lError
= RegOpenKeyExW(hKeyDevice
,
1798 if (lError
== ERROR_SUCCESS
)
1800 DPRINT1("Instance %S already exists!\n", szInstance
);
1801 RegCloseKey(hKeyInstance
);
1802 RegCloseKey(hKeyDevice
);
1803 return CR_ALREADY_SUCH_DEVINST
;
1806 /* Create a new instance key */
1807 lError
= RegCreateKeyExW(hKeyDevice
,
1811 REG_OPTION_NON_VOLATILE
,
1817 /* Close the device key */
1818 RegCloseKey(hKeyDevice
);
1820 if (lError
!= ERROR_SUCCESS
)
1822 return CR_REGISTRY_ERROR
;
1825 /* Create the 'Control' sub key */
1826 lError
= RegCreateKeyExW(hKeyInstance
,
1830 REG_OPTION_NON_VOLATILE
,
1835 if (lError
== ERROR_SUCCESS
)
1837 RegCloseKey(hKeyControl
);
1840 RegCloseKey(hKeyInstance
);
1842 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1852 LPWSTR pszParentDeviceID
,
1853 PNP_RPC_STRING_LEN ulLength
,
1856 CONFIGRET ret
= CR_SUCCESS
;
1858 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1860 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1862 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1863 DWORD dwInstanceNumber
;
1865 /* Generated ID is: Root\<Device ID>\<Instance number> */
1866 dwInstanceNumber
= 0;
1869 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1870 pszDeviceID
, dwInstanceNumber
);
1872 /* Try to create a device instance with this ID */
1873 ret
= CreateDeviceInstance(szGeneratedInstance
);
1877 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1879 if (ret
== CR_SUCCESS
)
1881 /* pszDeviceID is an out parameter too for generated IDs */
1882 if (wcslen(szGeneratedInstance
) > ulLength
)
1884 ret
= CR_BUFFER_SMALL
;
1888 wcscpy(pszDeviceID
, szGeneratedInstance
);
1894 /* Create the device instance */
1895 ret
= CreateDeviceInstance(pszDeviceID
);
1898 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1905 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1906 LPWSTR pszDeviceInstanceSource
)
1908 DPRINT("MoveDeviceInstance: not implemented\n");
1910 return CR_CALL_NOT_IMPLEMENTED
;
1915 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1918 DPRINT("SetupDeviceInstance: not implemented\n");
1920 return CR_CALL_NOT_IMPLEMENTED
;
1925 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1927 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1928 CONFIGRET ret
= CR_SUCCESS
;
1931 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
1933 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1934 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1935 if (!NT_SUCCESS(Status
))
1936 ret
= NtStatusToCrError(Status
);
1943 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1945 DPRINT("DisableDeviceInstance: not implemented\n");
1947 return CR_CALL_NOT_IMPLEMENTED
;
1952 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1954 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1956 return CR_CALL_NOT_IMPLEMENTED
;
1963 PNP_DeviceInstanceAction(
1967 LPWSTR pszDeviceInstance1
,
1968 LPWSTR pszDeviceInstance2
)
1970 CONFIGRET ret
= CR_SUCCESS
;
1972 UNREFERENCED_PARAMETER(hBinding
);
1974 DPRINT("PNP_DeviceInstanceAction() called\n");
1978 case PNP_DEVINST_MOVE
:
1979 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1980 pszDeviceInstance2
);
1983 case PNP_DEVINST_SETUP
:
1984 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1988 case PNP_DEVINST_ENABLE
:
1989 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1992 case PNP_DEVINST_DISABLE
:
1993 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1996 case PNP_DEVINST_REENUMERATE
:
1997 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
2001 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2002 ret
= CR_CALL_NOT_IMPLEMENTED
;
2005 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2014 PNP_GetDeviceStatus(
2021 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
2022 CONFIGRET ret
= CR_SUCCESS
;
2025 UNREFERENCED_PARAMETER(hBinding
);
2026 UNREFERENCED_PARAMETER(ulFlags
);
2028 DPRINT("PNP_GetDeviceStatus() called\n");
2030 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2032 PlugPlayData
.Operation
= 0; /* Get status */
2034 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2035 (PVOID
)&PlugPlayData
,
2036 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2037 if (NT_SUCCESS(Status
))
2039 *pulStatus
= PlugPlayData
.DeviceStatus
;
2040 *pulProblem
= PlugPlayData
.DeviceProblem
;
2044 ret
= NtStatusToCrError(Status
);
2047 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2056 PNP_SetDeviceProblem(
2063 return CR_CALL_NOT_IMPLEMENTED
;
2073 PPNP_VETO_TYPE pVetoType
,
2079 return CR_CALL_NOT_IMPLEMENTED
;
2085 PNP_UninstallDevInst(
2091 return CR_CALL_NOT_IMPLEMENTED
;
2096 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2102 lpPtr
= lpDeviceIdList
;
2105 dwLength
= wcslen(lpPtr
);
2106 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2109 lpPtr
+= (dwLength
+ 1);
2117 AppendDeviceId(LPWSTR lpDeviceIdList
,
2118 LPDWORD lpDeviceIdListSize
,
2124 dwLen
= wcslen(lpDeviceId
);
2125 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2127 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2129 dwPos
+= (dwLen
+ 1);
2131 lpDeviceIdList
[dwPos
] = 0;
2133 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2146 CONFIGRET ret
= CR_SUCCESS
;
2149 DWORD dwDeviceIdListSize
;
2150 DWORD dwNewDeviceIdSize
;
2151 WCHAR
* pszDeviceIdList
= NULL
;
2153 UNREFERENCED_PARAMETER(hBinding
);
2155 DPRINT("PNP_AddID() called\n");
2156 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2157 DPRINT(" DeviceId: %S\n", pszID
);
2158 DPRINT(" Flags: %lx\n", ulFlags
);
2160 if (RegOpenKeyExW(hEnumKey
,
2163 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2164 &hDeviceKey
) != ERROR_SUCCESS
)
2166 DPRINT("Failed to open the device key!\n");
2167 return CR_INVALID_DEVNODE
;
2170 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2172 if (RegQueryValueExW(hDeviceKey
,
2177 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2179 DPRINT("Failed to query the desired ID string!\n");
2180 ret
= CR_REGISTRY_ERROR
;
2184 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2185 if (!dwNewDeviceIdSize
)
2187 ret
= CR_INVALID_POINTER
;
2191 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2193 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2194 if (!pszDeviceIdList
)
2196 DPRINT("Failed to allocate memory for the desired ID string!\n");
2197 ret
= CR_OUT_OF_MEMORY
;
2201 if (RegQueryValueExW(hDeviceKey
,
2205 (LPBYTE
)pszDeviceIdList
,
2206 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2208 DPRINT("Failed to query the desired ID string!\n");
2209 ret
= CR_REGISTRY_ERROR
;
2213 /* Check whether the device ID is already in use */
2214 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2216 DPRINT("Device ID was found in the ID string!\n");
2221 /* Append the Device ID */
2222 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2224 if (RegSetValueExW(hDeviceKey
,
2228 (LPBYTE
)pszDeviceIdList
,
2229 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2231 DPRINT("Failed to set the desired ID string!\n");
2232 ret
= CR_REGISTRY_ERROR
;
2236 RegCloseKey(hDeviceKey
);
2237 if (pszDeviceIdList
)
2238 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2240 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2255 return CR_CALL_NOT_IMPLEMENTED
;
2265 PPNP_VETO_TYPE pVetoType
,
2271 return CR_CALL_NOT_IMPLEMENTED
;
2278 PNP_RequestDeviceEject(
2281 PPNP_VETO_TYPE pVetoType
,
2287 return CR_CALL_NOT_IMPLEMENTED
;
2294 PNP_IsDockStationPresent(
2302 CONFIGRET ret
= CR_SUCCESS
;
2304 UNREFERENCED_PARAMETER(hBinding
);
2306 DPRINT1("PNP_IsDockStationPresent() called\n");
2310 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2314 &hKey
) != ERROR_SUCCESS
)
2315 return CR_REGISTRY_ERROR
;
2317 dwSize
= sizeof(DWORD
);
2318 if (RegQueryValueExW(hKey
,
2323 &dwSize
) != ERROR_SUCCESS
)
2324 ret
= CR_REGISTRY_ERROR
;
2328 if (ret
== CR_SUCCESS
)
2330 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2332 ret
= CR_REGISTRY_ERROR
;
2334 else if (dwValue
!= 0)
2340 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2353 return CR_CALL_NOT_IMPLEMENTED
;
2366 PPNP_VETO_TYPE pVetoType
,
2371 CONFIGRET ret
= CR_SUCCESS
;
2372 WCHAR szKeyName
[MAX_PATH
];
2377 UNREFERENCED_PARAMETER(hBinding
);
2379 DPRINT("PNP_HwProfFlags() called\n");
2384 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2389 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2393 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2397 &hKey
) != ERROR_SUCCESS
)
2398 return CR_REGISTRY_ERROR
;
2400 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2402 if (RegOpenKeyExW(hKey
,
2406 &hDeviceKey
) != ERROR_SUCCESS
)
2412 dwSize
= sizeof(DWORD
);
2413 if (!RegQueryValueExW(hDeviceKey
,
2418 &dwSize
) != ERROR_SUCCESS
)
2423 RegCloseKey(hDeviceKey
);
2426 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2428 /* FIXME: not implemented yet */
2429 ret
= CR_CALL_NOT_IMPLEMENTED
;
2444 HWPROFILEINFO
*pHWProfileInfo
,
2445 DWORD ulProfileInfoSize
,
2448 WCHAR szProfileName
[5];
2449 HKEY hKeyConfig
= NULL
;
2450 HKEY hKeyProfiles
= NULL
;
2451 HKEY hKeyProfile
= NULL
;
2452 DWORD dwDisposition
;
2455 CONFIGRET ret
= CR_SUCCESS
;
2457 UNREFERENCED_PARAMETER(hBinding
);
2459 DPRINT("PNP_GetHwProfInfo() called\n");
2461 if (ulProfileInfoSize
== 0)
2463 ret
= CR_INVALID_DATA
;
2469 ret
= CR_INVALID_FLAG
;
2473 /* Initialize the profile information */
2474 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2475 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2476 pHWProfileInfo
->HWPI_dwFlags
= 0;
2478 /* Open the 'IDConfigDB' key */
2479 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2480 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2483 REG_OPTION_NON_VOLATILE
,
2488 if (lError
!= ERROR_SUCCESS
)
2490 ret
= CR_REGISTRY_ERROR
;
2494 /* Open the 'Hardware Profiles' subkey */
2495 lError
= RegCreateKeyExW(hKeyConfig
,
2496 L
"Hardware Profiles",
2499 REG_OPTION_NON_VOLATILE
,
2500 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2504 if (lError
!= ERROR_SUCCESS
)
2506 ret
= CR_REGISTRY_ERROR
;
2510 if (ulIndex
== (ULONG
)-1)
2512 dwSize
= sizeof(ULONG
);
2513 lError
= RegQueryValueExW(hKeyConfig
,
2517 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2519 if (lError
!= ERROR_SUCCESS
)
2521 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2522 ret
= CR_REGISTRY_ERROR
;
2528 /* FIXME: not implemented yet */
2529 ret
= CR_CALL_NOT_IMPLEMENTED
;
2533 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2535 lError
= RegOpenKeyExW(hKeyProfiles
,
2540 if (lError
!= ERROR_SUCCESS
)
2542 ret
= CR_REGISTRY_ERROR
;
2546 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2547 lError
= RegQueryValueExW(hKeyProfile
,
2551 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2553 if (lError
!= ERROR_SUCCESS
)
2555 ret
= CR_REGISTRY_ERROR
;
2560 if (hKeyProfile
!= NULL
)
2561 RegCloseKey(hKeyProfile
);
2563 if (hKeyProfiles
!= NULL
)
2564 RegCloseKey(hKeyProfiles
);
2566 if (hKeyConfig
!= NULL
)
2567 RegCloseKey(hKeyConfig
);
2576 PNP_AddEmptyLogConf(
2580 DWORD
*pulLogConfTag
,
2584 return CR_CALL_NOT_IMPLEMENTED
;
2594 DWORD ulLogConfType
,
2599 return CR_CALL_NOT_IMPLEMENTED
;
2606 PNP_GetFirstLogConf(
2609 DWORD ulLogConfType
,
2610 DWORD
*pulLogConfTag
,
2614 return CR_CALL_NOT_IMPLEMENTED
;
2624 DWORD ulLogConfType
,
2630 return CR_CALL_NOT_IMPLEMENTED
;
2637 PNP_GetLogConfPriority(
2646 return CR_CALL_NOT_IMPLEMENTED
;
2657 DWORD ulLogConfType
,
2658 RESOURCEID ResourceID
,
2659 DWORD
*pulResourceTag
,
2661 PNP_RPC_BUFFER_SIZE ResourceLen
,
2665 return CR_CALL_NOT_IMPLEMENTED
;
2676 DWORD ulLogConfType
,
2677 RESOURCEID ResourceID
,
2678 DWORD ulResourceTag
,
2679 DWORD
*pulPreviousResType
,
2680 DWORD
*pulPreviousResTag
,
2684 return CR_CALL_NOT_IMPLEMENTED
;
2695 DWORD ulLogConfType
,
2696 RESOURCEID ResourceID
,
2697 DWORD ulResourceTag
,
2698 DWORD
*pulNextResType
,
2699 DWORD
*pulNextResTag
,
2703 return CR_CALL_NOT_IMPLEMENTED
;
2714 DWORD ulLogConfType
,
2715 RESOURCEID ResourceID
,
2716 DWORD ulResourceTag
,
2718 PNP_RPC_BUFFER_SIZE BufferLen
,
2722 return CR_CALL_NOT_IMPLEMENTED
;
2729 PNP_GetResDesDataSize(
2733 DWORD ulLogConfType
,
2734 RESOURCEID ResourceID
,
2735 DWORD ulResourceTag
,
2740 return CR_CALL_NOT_IMPLEMENTED
;
2751 DWORD ulLogConfType
,
2752 RESOURCEID CurrentResourceID
,
2753 RESOURCEID NewResourceID
,
2754 DWORD ulResourceTag
,
2756 PNP_RPC_BUFFER_SIZE ResourceLen
,
2760 return CR_CALL_NOT_IMPLEMENTED
;
2767 PNP_DetectResourceConflict(
2770 RESOURCEID ResourceID
,
2772 PNP_RPC_BUFFER_SIZE ResourceLen
,
2773 BOOL
*pbConflictDetected
,
2777 return CR_CALL_NOT_IMPLEMENTED
;
2784 PNP_QueryResConfList(
2787 RESOURCEID ResourceID
,
2789 PNP_RPC_BUFFER_SIZE ResourceLen
,
2791 PNP_RPC_BUFFER_SIZE BufferLen
,
2795 return CR_CALL_NOT_IMPLEMENTED
;
2804 DWORD ulHardwareProfile
,
2808 return CR_CALL_NOT_IMPLEMENTED
;
2815 PNP_QueryArbitratorFreeData(
2820 RESOURCEID ResourceID
,
2824 return CR_CALL_NOT_IMPLEMENTED
;
2831 PNP_QueryArbitratorFreeSize(
2835 RESOURCEID ResourceID
,
2839 return CR_CALL_NOT_IMPLEMENTED
;
2850 return CR_CALL_NOT_IMPLEMENTED
;
2857 PNP_RegisterNotification(
2863 PNOTIFY_DATA pNotifyData
;
2866 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
2867 hBinding
, ulFlags
, pulNotify
);
2870 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
2871 if (pNotifyData
== NULL
)
2872 return CR_OUT_OF_MEMORY
;
2874 *pulNotify
= (DWORD
)pNotifyData
;
2886 PNP_UnregisterNotification(
2890 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
2891 hBinding
, ulNotify
);
2895 return CR_CALL_NOT_IMPLEMENTED
;
2905 PNP_GetCustomDevProp(
2908 LPWSTR CustomPropName
,
2909 DWORD
*pulRegDataType
,
2911 PNP_RPC_STRING_LEN
*pulTransferLen
,
2912 PNP_RPC_STRING_LEN
*pulLength
,
2915 HKEY hDeviceKey
= NULL
;
2916 HKEY hParamKey
= NULL
;
2918 CONFIGRET ret
= CR_SUCCESS
;
2920 UNREFERENCED_PARAMETER(hBinding
);
2922 DPRINT("PNP_GetCustomDevProp() called\n");
2924 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2926 ret
= CR_INVALID_POINTER
;
2930 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2932 ret
= CR_INVALID_FLAG
;
2936 if (*pulLength
< *pulTransferLen
)
2937 *pulLength
= *pulTransferLen
;
2939 *pulTransferLen
= 0;
2941 lError
= RegOpenKeyExW(hEnumKey
,
2946 if (lError
!= ERROR_SUCCESS
)
2948 ret
= CR_REGISTRY_ERROR
;
2952 lError
= RegOpenKeyExW(hDeviceKey
,
2953 L
"Device Parameters",
2957 if (lError
!= ERROR_SUCCESS
)
2959 ret
= CR_REGISTRY_ERROR
;
2963 lError
= RegQueryValueExW(hParamKey
,
2969 if (lError
!= ERROR_SUCCESS
)
2971 if (lError
== ERROR_MORE_DATA
)
2973 ret
= CR_BUFFER_SMALL
;
2978 ret
= CR_NO_SUCH_VALUE
;
2983 if (ret
== CR_SUCCESS
)
2984 *pulTransferLen
= *pulLength
;
2986 if (hParamKey
!= NULL
)
2987 RegCloseKey(hParamKey
);
2989 if (hDeviceKey
!= NULL
)
2990 RegCloseKey(hDeviceKey
);
2992 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3001 PNP_GetVersionInternal(
3013 PNP_GetBlockedDriverInfo(
3016 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3017 PNP_RPC_BUFFER_SIZE
*pulLength
,
3021 return CR_CALL_NOT_IMPLEMENTED
;
3028 PNP_GetServerSideDeviceInstallFlags(
3030 DWORD
*pulSSDIFlags
,
3034 return CR_CALL_NOT_IMPLEMENTED
;
3041 PNP_GetObjectPropKeys(
3045 LPWSTR PropertyCultureName
,
3046 PNP_PROP_COUNT
*PropertyCount
,
3047 PNP_PROP_COUNT
*TransferLen
,
3048 DEVPROPKEY
*PropertyKeys
,
3052 return CR_CALL_NOT_IMPLEMENTED
;
3063 LPWSTR PropertyCultureName
,
3064 const DEVPROPKEY
*PropertyKey
,
3065 DEVPROPTYPE
*PropertyType
,
3066 PNP_PROP_SIZE
*PropertySize
,
3067 PNP_PROP_SIZE
*TransferLen
,
3068 BYTE
*PropertyBuffer
,
3072 return CR_CALL_NOT_IMPLEMENTED
;
3083 LPWSTR PropertyCultureName
,
3084 const DEVPROPKEY
*PropertyKey
,
3085 DEVPROPTYPE PropertyType
,
3086 PNP_PROP_SIZE PropertySize
,
3087 BYTE
*PropertyBuffer
,
3091 return CR_CALL_NOT_IMPLEMENTED
;
3102 return CR_CALL_NOT_IMPLEMENTED
;
3109 PNP_ApplyPowerSettings(
3113 return CR_CALL_NOT_IMPLEMENTED
;
3120 PNP_DriverStoreAddDriverPackage(
3124 return CR_CALL_NOT_IMPLEMENTED
;
3131 PNP_DriverStoreDeleteDriverPackage(
3135 return CR_CALL_NOT_IMPLEMENTED
;
3142 PNP_RegisterServiceNotification(
3146 return CR_CALL_NOT_IMPLEMENTED
;
3153 PNP_SetActiveService(
3159 return CR_CALL_NOT_IMPLEMENTED
;
3166 PNP_DeleteServiceDevices(
3170 return CR_CALL_NOT_IMPLEMENTED
;
3175 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3177 BOOL DeviceInstalled
= FALSE
;
3180 HANDLE hInstallEvent
;
3181 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3182 LPVOID Environment
= NULL
;
3183 PROCESS_INFORMATION ProcessInfo
;
3184 STARTUPINFOW StartupInfo
;
3188 /* The following lengths are constant (see below), they cannot overflow */
3189 WCHAR CommandLine
[116];
3190 WCHAR InstallEventName
[73];
3192 WCHAR UuidString
[39];
3194 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3196 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3198 if (RegOpenKeyExW(hEnumKey
,
3202 &DeviceKey
) == ERROR_SUCCESS
)
3204 if (RegQueryValueExW(DeviceKey
,
3209 NULL
) == ERROR_SUCCESS
)
3211 DPRINT("No need to install: %S\n", DeviceInstance
);
3212 RegCloseKey(DeviceKey
);
3216 RegCloseKey(DeviceKey
);
3219 DPRINT1("Installing: %S\n", DeviceInstance
);
3221 /* Create a random UUID for the named pipe & event*/
3222 UuidCreate(&RandomUuid
);
3223 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3224 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3225 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3226 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3227 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3229 /* Create the event */
3230 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3231 wcscat(InstallEventName
, UuidString
);
3232 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3235 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3239 /* Create the named pipe */
3240 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3241 wcscat(PipeName
, UuidString
);
3242 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3243 if (hPipe
== INVALID_HANDLE_VALUE
)
3245 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3249 /* Launch rundll32 to call ClientSideInstallW */
3250 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3251 wcscat(CommandLine
, PipeName
);
3253 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3254 StartupInfo
.cb
= sizeof(StartupInfo
);
3258 /* newdev has to run under the environment of the current user */
3259 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3261 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3265 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3267 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3273 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3275 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3276 (ShowWizard is only set to FALSE for these two modes) */
3277 ASSERT(!ShowWizard
);
3279 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3281 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3286 /* Wait for the function to connect to our pipe */
3287 if (!ConnectNamedPipe(hPipe
, NULL
))
3289 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3291 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3296 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3297 Value
= sizeof(InstallEventName
);
3298 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3299 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3301 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3302 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3303 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3305 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3306 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3307 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3309 /* Wait for newdev.dll to finish processing */
3310 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3312 /* If the event got signalled, this is success */
3313 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3317 CloseHandle(hInstallEvent
);
3319 if (hPipe
!= INVALID_HANDLE_VALUE
)
3323 DestroyEnvironmentBlock(Environment
);
3325 if (ProcessInfo
.hProcess
)
3326 CloseHandle(ProcessInfo
.hProcess
);
3328 if (ProcessInfo
.hThread
)
3329 CloseHandle(ProcessInfo
.hThread
);
3331 if (!DeviceInstalled
)
3333 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3336 return DeviceInstalled
;
3352 return ERROR_INVALID_PARAMETER
;
3355 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3356 if (rc
!= ERROR_SUCCESS
)
3358 if (dwType
!= REG_SZ
)
3359 return ERROR_FILE_NOT_FOUND
;
3360 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3362 return ERROR_NOT_ENOUGH_MEMORY
;
3363 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3364 if (rc
!= ERROR_SUCCESS
)
3366 HeapFree(GetProcessHeap(), 0, Value
);
3369 /* NULL-terminate the string */
3370 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3373 return ERROR_SUCCESS
;
3381 DWORD regType
, active
, size
;
3385 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3386 if (rc
!= ERROR_SUCCESS
)
3389 size
= sizeof(DWORD
);
3390 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3391 if (rc
!= ERROR_SUCCESS
)
3393 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3396 ret
= (active
!= 0);
3402 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3411 HKEY ControlKey
= NULL
;
3412 LPWSTR SystemStartOptions
= NULL
;
3413 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3414 BOOL ConsoleBoot
= FALSE
;
3419 L
"SYSTEM\\CurrentControlSet\\Control",
3424 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3425 if (rc
!= ERROR_SUCCESS
)
3428 /* Check for CONSOLE switch in SystemStartOptions */
3429 CurrentOption
= SystemStartOptions
;
3430 while (CurrentOption
)
3432 NextOption
= wcschr(CurrentOption
, L
' ');
3434 *NextOption
= L
'\0';
3435 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3437 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3441 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3445 if (ControlKey
!= NULL
)
3446 RegCloseKey(ControlKey
);
3447 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3452 /* Loop to install all queued devices installations */
3454 DeviceInstallThread(LPVOID lpParameter
)
3456 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3457 PSLIST_ENTRY ListEntry
;
3459 PLIST_ENTRY ListEntry
;
3461 DeviceInstallParams
* Params
;
3464 UNREFERENCED_PARAMETER(lpParameter
);
3466 WaitForSingleObject(hInstallEvent
, INFINITE
);
3468 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3472 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3473 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3475 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3478 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3480 if (ListEntry
== NULL
)
3482 SetEvent(hNoPendingInstalls
);
3483 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3487 ResetEvent(hNoPendingInstalls
);
3488 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3489 InstallDevice(Params
->DeviceIds
, showWizard
);
3498 PnpEventThread(LPVOID lpParameter
)
3500 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3503 RPC_STATUS RpcStatus
;
3505 UNREFERENCED_PARAMETER(lpParameter
);
3507 PnpEventSize
= 0x1000;
3508 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3509 if (PnpEvent
== NULL
)
3510 return ERROR_OUTOFMEMORY
;
3514 DPRINT("Calling NtGetPlugPlayEvent()\n");
3516 /* Wait for the next pnp event */
3517 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3519 /* Resize the buffer for the PnP event if it's too small. */
3520 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3522 PnpEventSize
+= 0x400;
3523 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3524 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3525 if (PnpEvent
== NULL
)
3526 return ERROR_OUTOFMEMORY
;
3530 if (!NT_SUCCESS(Status
))
3532 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3536 /* Process the pnp event */
3537 DPRINT("Received PnP Event\n");
3538 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3540 DeviceInstallParams
* Params
;
3542 DWORD DeviceIdLength
;
3544 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3546 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3549 /* Queue device install (will be dequeued by DeviceInstallThread */
3550 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3551 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3554 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3555 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3556 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3558 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3560 SetEvent(hDeviceInstallListNotEmpty
);
3564 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3566 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3569 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3571 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3573 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3575 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3577 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3579 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3581 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3583 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3585 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3587 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3589 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3591 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3595 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3596 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3597 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3598 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3599 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3602 /* Dequeue the current pnp event and signal the next one */
3603 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3606 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3608 return ERROR_SUCCESS
;
3613 UpdateServiceStatus(DWORD dwState
)
3615 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3616 ServiceStatus
.dwCurrentState
= dwState
;
3617 ServiceStatus
.dwControlsAccepted
= 0;
3618 ServiceStatus
.dwWin32ExitCode
= 0;
3619 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3620 ServiceStatus
.dwCheckPoint
= 0;
3622 if (dwState
== SERVICE_START_PENDING
||
3623 dwState
== SERVICE_STOP_PENDING
||
3624 dwState
== SERVICE_PAUSE_PENDING
||
3625 dwState
== SERVICE_CONTINUE_PENDING
)
3626 ServiceStatus
.dwWaitHint
= 10000;
3628 ServiceStatus
.dwWaitHint
= 0;
3630 SetServiceStatus(ServiceStatusHandle
,
3636 ServiceControlHandler(DWORD dwControl
,
3641 DPRINT1("ServiceControlHandler() called\n");
3645 case SERVICE_CONTROL_STOP
:
3646 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3647 /* Stop listening to RPC Messages */
3648 RpcMgmtStopServerListening(NULL
);
3649 UpdateServiceStatus(SERVICE_STOPPED
);
3650 return ERROR_SUCCESS
;
3652 case SERVICE_CONTROL_PAUSE
:
3653 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3654 UpdateServiceStatus(SERVICE_PAUSED
);
3655 return ERROR_SUCCESS
;
3657 case SERVICE_CONTROL_CONTINUE
:
3658 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3659 UpdateServiceStatus(SERVICE_RUNNING
);
3660 return ERROR_SUCCESS
;
3662 case SERVICE_CONTROL_INTERROGATE
:
3663 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3664 SetServiceStatus(ServiceStatusHandle
,
3666 return ERROR_SUCCESS
;
3668 case SERVICE_CONTROL_SHUTDOWN
:
3669 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3670 /* Stop listening to RPC Messages */
3671 RpcMgmtStopServerListening(NULL
);
3672 UpdateServiceStatus(SERVICE_STOPPED
);
3673 return ERROR_SUCCESS
;
3676 DPRINT1(" Control %lu received\n", dwControl
);
3677 return ERROR_CALL_NOT_IMPLEMENTED
;
3683 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3688 UNREFERENCED_PARAMETER(argc
);
3689 UNREFERENCED_PARAMETER(argv
);
3691 DPRINT("ServiceMain() called\n");
3693 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3694 ServiceControlHandler
,
3696 if (!ServiceStatusHandle
)
3698 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3702 UpdateServiceStatus(SERVICE_START_PENDING
);
3704 hThread
= CreateThread(NULL
,
3710 if (hThread
!= NULL
)
3711 CloseHandle(hThread
);
3713 hThread
= CreateThread(NULL
,
3719 if (hThread
!= NULL
)
3720 CloseHandle(hThread
);
3722 hThread
= CreateThread(NULL
,
3724 DeviceInstallThread
,
3728 if (hThread
!= NULL
)
3729 CloseHandle(hThread
);
3731 UpdateServiceStatus(SERVICE_RUNNING
);
3733 DPRINT("ServiceMain() done\n");
3737 InitializePnPManager(VOID
)
3742 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3744 /* We need this privilege for using CreateProcessAsUserW */
3745 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3747 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3748 if (hInstallEvent
== NULL
)
3750 dwError
= GetLastError();
3751 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3755 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3756 if (hDeviceInstallListNotEmpty
== NULL
)
3758 dwError
= GetLastError();
3759 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3763 hNoPendingInstalls
= CreateEventW(NULL
,
3766 L
"Global\\PnP_No_Pending_Install_Events");
3767 if (hNoPendingInstalls
== NULL
)
3769 dwError
= GetLastError();
3770 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3774 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3775 InitializeSListHead(&DeviceInstallListHead
);
3777 InitializeListHead(&DeviceInstallListHead
);
3780 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3781 L
"System\\CurrentControlSet\\Enum",
3785 if (dwError
!= ERROR_SUCCESS
)
3787 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3791 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3792 L
"System\\CurrentControlSet\\Control\\Class",
3796 if (dwError
!= ERROR_SUCCESS
)
3798 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3802 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3808 DllMain(HINSTANCE hinstDLL
,
3814 case DLL_PROCESS_ATTACH
:
3815 DisableThreadLibraryCalls(hinstDLL
);
3816 InitializePnPManager();
3819 case DLL_PROCESS_DETACH
: