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 (eric.kohl@reactos.org)
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
46 #include <umpnpmgr/sysguid.h>
56 /* GLOBALS ******************************************************************/
58 static WCHAR ServiceName
[] = L
"PlugPlay";
60 static SERVICE_STATUS_HANDLE ServiceStatusHandle
;
61 static SERVICE_STATUS ServiceStatus
;
63 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
65 static HKEY hEnumKey
= NULL
;
66 static HKEY hClassKey
= NULL
;
68 static HANDLE hUserToken
= NULL
;
69 static HANDLE hInstallEvent
= NULL
;
70 static HANDLE hNoPendingInstalls
= NULL
;
72 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
73 static SLIST_HEADER DeviceInstallListHead
;
75 static LIST_ENTRY DeviceInstallListHead
;
77 static HANDLE hDeviceInstallListNotEmpty
;
81 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
82 SLIST_ENTRY ListEntry
;
87 } DeviceInstallParams
;
89 /* FUNCTIONS *****************************************************************/
92 RpcServerThread(LPVOID lpParameter
)
95 BOOLEAN RegisteredProtSeq
= FALSE
;
97 UNREFERENCED_PARAMETER(lpParameter
);
99 DPRINT("RpcServerThread() called\n");
102 /* 2k/XP/2k3-compatible protocol sequence/endpoint */
103 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
106 NULL
); // Security descriptor
107 if (Status
== RPC_S_OK
)
108 RegisteredProtSeq
= TRUE
;
110 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
113 /* Vista/7-compatible protocol sequence/endpoint */
114 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
117 NULL
); // Security descriptor
118 if (Status
== RPC_S_OK
)
119 RegisteredProtSeq
= TRUE
;
121 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
123 /* Make sure there's a usable endpoint */
124 if (RegisteredProtSeq
== FALSE
)
127 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
130 if (Status
!= RPC_S_OK
)
132 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
136 Status
= RpcServerListen(1,
139 if (Status
!= RPC_S_OK
)
141 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
145 /* ROS HACK (this should never happen...) */
146 DPRINT1("*** Other devices won't be installed correctly. If something\n");
147 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
149 DPRINT("RpcServerThread() done\n");
155 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
157 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
161 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
163 HeapFree(GetProcessHeap(), 0, ptr
);
167 static CONFIGRET WINAPI
168 NtStatusToCrError(NTSTATUS Status
)
172 case STATUS_NOT_IMPLEMENTED
:
173 return CR_CALL_NOT_IMPLEMENTED
;
175 case STATUS_INVALID_PARAMETER
:
176 return CR_INVALID_DATA
;
178 case STATUS_NO_SUCH_DEVICE
:
179 return CR_NO_SUCH_DEVINST
;
181 case STATUS_ACCESS_DENIED
:
182 return CR_ACCESS_DENIED
;
184 case STATUS_BUFFER_TOO_SMALL
:
185 return CR_BUFFER_SMALL
;
187 case STATUS_OBJECT_NAME_NOT_FOUND
:
188 return CR_NO_SUCH_VALUE
;
202 UNREFERENCED_PARAMETER(hBinding
);
213 UNREFERENCED_PARAMETER(hBinding
);
225 UNREFERENCED_PARAMETER(hBinding
);
240 UNREFERENCED_PARAMETER(hBinding
);
241 UNREFERENCED_PARAMETER(ulFlags
);
243 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
254 UNREFERENCED_PARAMETER(hBinding
);
256 DPRINT("PNP_InitDetection() called\n");
269 DWORD ReturnValue
= CR_FAILURE
;
272 UNREFERENCED_PARAMETER(hBinding
);
273 UNREFERENCED_PARAMETER(Admin
);
275 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
277 /* Get the users token */
278 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
282 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
288 CloseHandle(hUserToken
);
292 if (!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
294 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
298 /* Trigger the installer thread */
300 SetEvent(hInstallEvent
);
302 ReturnValue
= CR_SUCCESS
;
306 CloseHandle(hProcess
);
315 PNP_ValidateDeviceInstance(
320 CONFIGRET ret
= CR_SUCCESS
;
321 HKEY hDeviceKey
= NULL
;
323 UNREFERENCED_PARAMETER(hBinding
);
324 UNREFERENCED_PARAMETER(ulFlags
);
326 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
329 if (RegOpenKeyExW(hEnumKey
,
335 DPRINT("Could not open the Device Key!\n");
336 ret
= CR_NO_SUCH_DEVNODE
;
340 /* FIXME: add more tests */
343 if (hDeviceKey
!= NULL
)
344 RegCloseKey(hDeviceKey
);
346 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
355 PNP_GetRootDeviceInstance(
358 PNP_RPC_STRING_LEN ulLength
)
360 CONFIGRET ret
= CR_SUCCESS
;
362 UNREFERENCED_PARAMETER(hBinding
);
364 DPRINT("PNP_GetRootDeviceInstance() called\n");
368 ret
= CR_INVALID_POINTER
;
371 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
373 ret
= CR_BUFFER_SMALL
;
381 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
390 PNP_GetRelatedDeviceInstance(
392 DWORD ulRelationship
,
394 LPWSTR pRelatedDeviceId
,
395 PNP_RPC_STRING_LEN
*pulLength
,
398 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
399 CONFIGRET ret
= CR_SUCCESS
;
402 UNREFERENCED_PARAMETER(hBinding
);
403 UNREFERENCED_PARAMETER(ulFlags
);
405 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
406 DPRINT(" Relationship %ld\n", ulRelationship
);
407 DPRINT(" DeviceId %S\n", pDeviceID
);
409 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
412 PlugPlayData
.Relation
= ulRelationship
;
414 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
415 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
417 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
418 (PVOID
)&PlugPlayData
,
419 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
420 if (!NT_SUCCESS(Status
))
422 ret
= NtStatusToCrError(Status
);
425 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
426 if (ret
== CR_SUCCESS
)
428 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
438 PNP_EnumerateSubKeys(
443 PNP_RPC_STRING_LEN ulLength
,
444 PNP_RPC_STRING_LEN
*pulRequiredLen
,
447 CONFIGRET ret
= CR_SUCCESS
;
451 UNREFERENCED_PARAMETER(hBinding
);
452 UNREFERENCED_PARAMETER(ulFlags
);
454 DPRINT("PNP_EnumerateSubKeys() called\n");
458 case PNP_ENUMERATOR_SUBKEYS
:
462 case PNP_CLASS_SUBKEYS
:
470 *pulRequiredLen
= ulLength
;
471 dwError
= RegEnumKeyExW(hKey
,
479 if (dwError
!= ERROR_SUCCESS
)
481 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
488 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
501 PNP_RPC_STRING_LEN
*pulLength
,
504 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
505 CONFIGRET ret
= CR_SUCCESS
;
508 DPRINT("PNP_GetDeviceList() called\n");
510 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
511 return CR_INVALID_FLAG
;
513 if (pulLength
== NULL
|| pszFilter
== NULL
)
514 return CR_INVALID_POINTER
;
516 // if (Buffer == NULL)
517 // return CR_INVALID_POINTER;
520 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
521 CM_GETIDLIST_FILTER_POWERRELATIONS
|
522 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
523 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
525 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
527 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
529 PlugPlayData
.Relations
= 3;
531 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
533 PlugPlayData
.Relations
= 2;
535 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
537 PlugPlayData
.Relations
= 1;
539 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
541 PlugPlayData
.Relations
= 0;
544 PlugPlayData
.BufferSize
= *pulLength
* sizeof(WCHAR
);
545 PlugPlayData
.Buffer
= Buffer
;
547 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
548 (PVOID
)&PlugPlayData
,
549 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
550 if (NT_SUCCESS(Status
))
552 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
556 ret
= NtStatusToCrError(Status
);
559 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
561 ret
= CR_CALL_NOT_IMPLEMENTED
;
563 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
565 ret
= CR_CALL_NOT_IMPLEMENTED
;
567 else /* CM_GETIDLIST_FILTER_NONE */
569 ret
= CR_CALL_NOT_IMPLEMENTED
;
579 PNP_GetDeviceListSize(
582 PNP_RPC_BUFFER_SIZE
*pulLength
,
585 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
586 CONFIGRET ret
= CR_SUCCESS
;
589 DPRINT("PNP_GetDeviceListSize() called\n");
591 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
592 return CR_INVALID_FLAG
;
594 if (pulLength
== NULL
|| pszFilter
== NULL
)
595 return CR_INVALID_POINTER
;
600 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
601 CM_GETIDLIST_FILTER_POWERRELATIONS
|
602 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
603 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
605 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
607 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
609 PlugPlayData
.Relations
= 3;
611 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
613 PlugPlayData
.Relations
= 2;
615 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
617 PlugPlayData
.Relations
= 1;
619 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
621 PlugPlayData
.Relations
= 0;
624 PlugPlayData
.BufferSize
= 0;
625 PlugPlayData
.Buffer
= NULL
;
627 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
628 (PVOID
)&PlugPlayData
,
629 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
630 if (NT_SUCCESS(Status
))
632 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
636 ret
= NtStatusToCrError(Status
);
639 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
641 ret
= CR_CALL_NOT_IMPLEMENTED
;
643 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
645 ret
= CR_CALL_NOT_IMPLEMENTED
;
647 else /* CM_GETIDLIST_FILTER_NONE */
649 ret
= CR_CALL_NOT_IMPLEMENTED
;
665 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
666 CONFIGRET ret
= CR_SUCCESS
;
669 UNREFERENCED_PARAMETER(hBinding
);
670 UNREFERENCED_PARAMETER(ulFlags
);
672 DPRINT("PNP_GetDepth() called\n");
674 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
677 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
678 (PVOID
)&PlugPlayData
,
679 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
680 if (NT_SUCCESS(Status
))
682 *pulDepth
= PlugPlayData
.Depth
;
686 ret
= NtStatusToCrError(Status
);
689 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
698 PNP_GetDeviceRegProp(
702 DWORD
*pulRegDataType
,
704 PNP_PROP_SIZE
*pulTransferLen
,
705 PNP_PROP_SIZE
*pulLength
,
708 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
709 CONFIGRET ret
= CR_SUCCESS
;
710 LPWSTR lpValueName
= NULL
;
715 UNREFERENCED_PARAMETER(hBinding
);
717 DPRINT("PNP_GetDeviceRegProp() called\n");
719 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
721 ret
= CR_INVALID_POINTER
;
727 ret
= CR_INVALID_FLAG
;
731 /* FIXME: Check pDeviceID */
733 if (*pulLength
< *pulTransferLen
)
734 *pulLength
= *pulTransferLen
;
740 case CM_DRP_DEVICEDESC
:
741 lpValueName
= L
"DeviceDesc";
744 case CM_DRP_HARDWAREID
:
745 lpValueName
= L
"HardwareID";
748 case CM_DRP_COMPATIBLEIDS
:
749 lpValueName
= L
"CompatibleIDs";
753 lpValueName
= L
"Service";
757 lpValueName
= L
"Class";
760 case CM_DRP_CLASSGUID
:
761 lpValueName
= L
"ClassGUID";
765 lpValueName
= L
"Driver";
768 case CM_DRP_CONFIGFLAGS
:
769 lpValueName
= L
"ConfigFlags";
773 lpValueName
= L
"Mfg";
776 case CM_DRP_FRIENDLYNAME
:
777 lpValueName
= L
"FriendlyName";
780 case CM_DRP_LOCATION_INFORMATION
:
781 lpValueName
= L
"LocationInformation";
784 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
788 case CM_DRP_CAPABILITIES
:
789 lpValueName
= L
"Capabilities";
792 case CM_DRP_UI_NUMBER
:
796 case CM_DRP_UPPERFILTERS
:
797 lpValueName
= L
"UpperFilters";
800 case CM_DRP_LOWERFILTERS
:
801 lpValueName
= L
"LowerFilters";
804 case CM_DRP_BUSTYPEGUID
:
808 case CM_DRP_LEGACYBUSTYPE
:
812 case CM_DRP_BUSNUMBER
:
816 case CM_DRP_ENUMERATOR_NAME
:
820 case CM_DRP_SECURITY
:
821 lpValueName
= L
"Security";
825 lpValueName
= L
"DeviceType";
828 case CM_DRP_EXCLUSIVE
:
829 lpValueName
= L
"Exclusive";
832 case CM_DRP_CHARACTERISTICS
:
833 lpValueName
= L
"DeviceCharacteristics";
840 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
841 lpValueName
= L
"UINumberDescFormat";
844 case CM_DRP_DEVICE_POWER_DATA
:
848 case CM_DRP_REMOVAL_POLICY
:
852 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
856 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
857 lpValueName
= L
"RemovalPolicy";
860 case CM_DRP_INSTALL_STATE
:
864 #if (WINVER >= _WIN32_WINNT_WS03)
865 case CM_DRP_LOCATION_PATHS
:
870 #if (WINVER >= _WIN32_WINNT_WIN7)
871 case CM_DRP_BASE_CONTAINERID
:
877 ret
= CR_INVALID_PROPERTY
;
881 DPRINT("Value name: %S\n", lpValueName
);
885 /* Retrieve information from the Registry */
886 lError
= RegOpenKeyExW(hEnumKey
,
891 if (lError
!= ERROR_SUCCESS
)
895 ret
= CR_INVALID_DEVNODE
;
899 lError
= RegQueryValueExW(hKey
,
905 if (lError
!= ERROR_SUCCESS
)
907 if (lError
== ERROR_MORE_DATA
)
909 ret
= CR_BUFFER_SMALL
;
914 ret
= CR_NO_SUCH_VALUE
;
920 /* Retrieve information from the Device Node */
921 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
923 PlugPlayData
.Buffer
= Buffer
;
924 PlugPlayData
.BufferSize
= *pulLength
;
928 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
929 PlugPlayData
.Property
= 0xb; // DevicePropertyPhysicalDeviceObjectName;
932 case CM_DRP_UI_NUMBER
:
933 PlugPlayData
.Property
= 0x11; // DevicePropertyUINumber;
936 case CM_DRP_BUSTYPEGUID
:
937 PlugPlayData
.Property
= 0xc; // DevicePropertyBusTypeGuid;
940 case CM_DRP_LEGACYBUSTYPE
:
941 PlugPlayData
.Property
= 0xd; // DevicePropertyLegacyBusType;
944 case CM_DRP_BUSNUMBER
:
945 PlugPlayData
.Property
= 0xe; // DevicePropertyBusNumber;
948 case CM_DRP_ENUMERATOR_NAME
:
949 PlugPlayData
.Property
= 0xf; // DevicePropertyEnumeratorName;
953 PlugPlayData
.Property
= 0x10; // DevicePropertyAddress;
957 /* FIXME: This property is not supported by IoGetDeviceProperty */
958 case CM_DRP_DEVICE_POWER_DATA
:
961 case CM_DRP_REMOVAL_POLICY
:
962 PlugPlayData
.Property
= 0x13; // DevicePropertyRemovalPolicy
966 /* FIXME: This property is not supported by IoGetDeviceProperty */
967 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
970 case CM_DRP_INSTALL_STATE
:
971 PlugPlayData
.Property
= 0x12; // DevicePropertyInstallState;
975 /* FIXME: This property is not supported by IoGetDeviceProperty */
976 #if (WINVER >= _WIN32_WINNT_WS03)
977 case CM_DRP_LOCATION_PATHS
:
981 #if (WINVER >= _WIN32_WINNT_WIN7)
982 case CM_DRP_BASE_CONTAINERID
:
983 PlugPlayData
.Property
= 0x16; // DevicePropertyContainerID;
988 return CR_INVALID_PROPERTY
;
991 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
992 (PVOID
)&PlugPlayData
,
993 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
994 if (NT_SUCCESS(Status
))
996 *pulLength
= PlugPlayData
.BufferSize
;
1000 ret
= NtStatusToCrError(Status
);
1007 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1012 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1021 PNP_SetDeviceRegProp(
1027 PNP_PROP_SIZE ulLength
,
1030 CONFIGRET ret
= CR_SUCCESS
;
1031 LPWSTR lpValueName
= NULL
;
1034 UNREFERENCED_PARAMETER(hBinding
);
1035 UNREFERENCED_PARAMETER(ulFlags
);
1037 DPRINT("PNP_SetDeviceRegProp() called\n");
1039 DPRINT("DeviceId: %S\n", pDeviceId
);
1040 DPRINT("Property: %lu\n", ulProperty
);
1041 DPRINT("DataType: %lu\n", ulDataType
);
1042 DPRINT("Length: %lu\n", ulLength
);
1046 case CM_DRP_DEVICEDESC
:
1047 lpValueName
= L
"DeviceDesc";
1050 case CM_DRP_HARDWAREID
:
1051 lpValueName
= L
"HardwareID";
1054 case CM_DRP_COMPATIBLEIDS
:
1055 lpValueName
= L
"CompatibleIDs";
1058 case CM_DRP_SERVICE
:
1059 lpValueName
= L
"Service";
1063 lpValueName
= L
"Class";
1066 case CM_DRP_CLASSGUID
:
1067 lpValueName
= L
"ClassGUID";
1071 lpValueName
= L
"Driver";
1074 case CM_DRP_CONFIGFLAGS
:
1075 lpValueName
= L
"ConfigFlags";
1079 lpValueName
= L
"Mfg";
1082 case CM_DRP_FRIENDLYNAME
:
1083 lpValueName
= L
"FriendlyName";
1086 case CM_DRP_LOCATION_INFORMATION
:
1087 lpValueName
= L
"LocationInformation";
1090 case CM_DRP_UPPERFILTERS
:
1091 lpValueName
= L
"UpperFilters";
1094 case CM_DRP_LOWERFILTERS
:
1095 lpValueName
= L
"LowerFilters";
1098 case CM_DRP_SECURITY
:
1099 lpValueName
= L
"Security";
1102 case CM_DRP_DEVTYPE
:
1103 lpValueName
= L
"DeviceType";
1106 case CM_DRP_EXCLUSIVE
:
1107 lpValueName
= L
"Exclusive";
1110 case CM_DRP_CHARACTERISTICS
:
1111 lpValueName
= L
"DeviceCharacteristics";
1114 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1115 lpValueName
= L
"UINumberDescFormat";
1118 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1119 lpValueName
= L
"RemovalPolicy";
1123 return CR_INVALID_PROPERTY
;
1126 DPRINT("Value name: %S\n", lpValueName
);
1128 if (RegOpenKeyExW(hEnumKey
,
1133 return CR_INVALID_DEVNODE
;
1137 if (RegDeleteValueW(hKey
,
1139 ret
= CR_REGISTRY_ERROR
;
1143 if (RegSetValueExW(hKey
,
1149 ret
= CR_REGISTRY_ERROR
;
1154 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1163 PNP_GetClassInstance(
1166 LPWSTR pszClassInstance
,
1167 PNP_RPC_STRING_LEN ulLength
)
1170 return CR_CALL_NOT_IMPLEMENTED
;
1185 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1194 return CR_REGISTRY_ERROR
;
1196 /* FIXME: Set security key */
1207 PNP_DeleteRegistryKey(
1210 LPWSTR pszParentKey
,
1215 return CR_CALL_NOT_IMPLEMENTED
;
1224 DWORD
*pulClassCount
,
1230 UNREFERENCED_PARAMETER(hBinding
);
1231 UNREFERENCED_PARAMETER(ulFlags
);
1233 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1238 if (dwError
!= ERROR_SUCCESS
)
1239 return CR_INVALID_DATA
;
1241 dwError
= RegQueryInfoKeyW(hKey
,
1254 if (dwError
!= ERROR_SUCCESS
)
1255 return CR_INVALID_DATA
;
1266 LPWSTR pszClassGuid
,
1268 PNP_RPC_STRING_LEN
*pulLength
,
1271 WCHAR szKeyName
[MAX_PATH
];
1272 CONFIGRET ret
= CR_SUCCESS
;
1276 UNREFERENCED_PARAMETER(hBinding
);
1277 UNREFERENCED_PARAMETER(ulFlags
);
1279 DPRINT("PNP_GetClassName() called\n");
1281 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1282 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1283 lstrcatW(szKeyName
, pszClassGuid
);
1285 return CR_INVALID_DATA
;
1287 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1292 return CR_REGISTRY_ERROR
;
1294 dwSize
= *pulLength
* sizeof(WCHAR
);
1295 if (RegQueryValueExW(hKey
,
1303 ret
= CR_REGISTRY_ERROR
;
1307 *pulLength
= dwSize
/ sizeof(WCHAR
);
1312 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1323 LPWSTR pszClassGuid
,
1326 CONFIGRET ret
= CR_SUCCESS
;
1328 UNREFERENCED_PARAMETER(hBinding
);
1330 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1332 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1334 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1335 ret
= CR_REGISTRY_ERROR
;
1339 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1340 ret
= CR_REGISTRY_ERROR
;
1343 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1352 PNP_GetInterfaceDeviceAlias(
1354 LPWSTR pszInterfaceDevice
,
1355 GUID
*AliasInterfaceGuid
,
1356 LPWSTR pszAliasInterfaceDevice
,
1357 PNP_RPC_STRING_LEN
*pulLength
,
1358 PNP_RPC_STRING_LEN
*pulTransferLen
,
1362 return CR_CALL_NOT_IMPLEMENTED
;
1369 PNP_GetInterfaceDeviceList(
1371 GUID
*InterfaceGuid
,
1374 PNP_RPC_BUFFER_SIZE
*pulLength
,
1378 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1379 DWORD ret
= CR_SUCCESS
;
1381 UNREFERENCED_PARAMETER(hBinding
);
1383 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1386 PlugPlayData
.Flags
= ulFlags
;
1387 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1388 PlugPlayData
.Buffer
= Buffer
;
1389 PlugPlayData
.BufferSize
= *pulLength
;
1391 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1392 (PVOID
)&PlugPlayData
,
1393 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1394 if (NT_SUCCESS(Status
))
1396 *pulLength
= PlugPlayData
.BufferSize
;
1400 ret
= NtStatusToCrError(Status
);
1403 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1411 PNP_GetInterfaceDeviceListSize(
1413 PNP_RPC_BUFFER_SIZE
*pulLen
,
1414 GUID
*InterfaceGuid
,
1419 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1420 DWORD ret
= CR_SUCCESS
;
1422 UNREFERENCED_PARAMETER(hBinding
);
1424 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1426 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1429 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1430 PlugPlayData
.Buffer
= NULL
;
1431 PlugPlayData
.BufferSize
= 0;
1432 PlugPlayData
.Flags
= ulFlags
;
1434 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1435 (PVOID
)&PlugPlayData
,
1436 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1437 if (NT_SUCCESS(Status
))
1439 *pulLen
= PlugPlayData
.BufferSize
;
1443 ret
= NtStatusToCrError(Status
);
1446 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1454 PNP_RegisterDeviceClassAssociation(
1457 GUID
*InterfaceGuid
,
1458 LPWSTR pszReference
,
1460 PNP_RPC_STRING_LEN
*pulLength
,
1461 PNP_RPC_STRING_LEN
*pulTransferLen
,
1465 return CR_CALL_NOT_IMPLEMENTED
;
1472 PNP_UnregisterDeviceClassAssociation(
1474 LPWSTR pszInterfaceDevice
,
1478 return CR_CALL_NOT_IMPLEMENTED
;
1485 PNP_GetClassRegProp(
1487 LPWSTR pszClassGuid
,
1489 DWORD
*pulRegDataType
,
1491 PNP_RPC_STRING_LEN
*pulTransferLen
,
1492 PNP_RPC_STRING_LEN
*pulLength
,
1495 CONFIGRET ret
= CR_SUCCESS
;
1496 LPWSTR lpValueName
= NULL
;
1497 HKEY hInstKey
= NULL
;
1498 HKEY hPropKey
= NULL
;
1501 UNREFERENCED_PARAMETER(hBinding
);
1503 DPRINT("PNP_GetClassRegProp() called\n");
1505 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1507 ret
= CR_INVALID_POINTER
;
1513 ret
= CR_INVALID_FLAG
;
1517 if (*pulLength
< *pulTransferLen
)
1518 *pulLength
= *pulTransferLen
;
1520 *pulTransferLen
= 0;
1524 case CM_CRP_SECURITY
:
1525 lpValueName
= L
"Security";
1528 case CM_CRP_DEVTYPE
:
1529 lpValueName
= L
"DeviceType";
1532 case CM_CRP_EXCLUSIVE
:
1533 lpValueName
= L
"Exclusive";
1536 case CM_CRP_CHARACTERISTICS
:
1537 lpValueName
= L
"DeviceCharacteristics";
1541 ret
= CR_INVALID_PROPERTY
;
1545 DPRINT("Value name: %S\n", lpValueName
);
1547 lError
= RegOpenKeyExW(hClassKey
,
1552 if (lError
!= ERROR_SUCCESS
)
1555 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1559 lError
= RegOpenKeyExW(hInstKey
,
1564 if (lError
!= ERROR_SUCCESS
)
1567 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1571 lError
= RegQueryValueExW(hPropKey
,
1577 if (lError
!= ERROR_SUCCESS
)
1579 if (lError
== ERROR_MORE_DATA
)
1581 ret
= CR_BUFFER_SMALL
;
1586 ret
= CR_NO_SUCH_VALUE
;
1591 if (ret
== CR_SUCCESS
)
1592 *pulTransferLen
= *pulLength
;
1594 if (hPropKey
!= NULL
)
1595 RegCloseKey(hPropKey
);
1597 if (hInstKey
!= NULL
)
1598 RegCloseKey(hInstKey
);
1600 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1609 PNP_SetClassRegProp(
1611 LPWSTR pszClassGuid
,
1615 PNP_PROP_SIZE ulLength
,
1618 CONFIGRET ret
= CR_SUCCESS
;
1619 LPWSTR lpValueName
= NULL
;
1624 UNREFERENCED_PARAMETER(hBinding
);
1626 DPRINT("PNP_SetClassRegProp() called\n");
1629 return CR_INVALID_FLAG
;
1633 case CM_CRP_SECURITY
:
1634 lpValueName
= L
"Security";
1637 case CM_CRP_DEVTYPE
:
1638 lpValueName
= L
"DeviceType";
1641 case CM_CRP_EXCLUSIVE
:
1642 lpValueName
= L
"Exclusive";
1645 case CM_CRP_CHARACTERISTICS
:
1646 lpValueName
= L
"DeviceCharacteristics";
1650 return CR_INVALID_PROPERTY
;
1653 lError
= RegOpenKeyExW(hClassKey
,
1658 if (lError
!= ERROR_SUCCESS
)
1660 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1664 /* FIXME: Set security descriptor */
1665 lError
= RegCreateKeyExW(hInstKey
,
1669 REG_OPTION_NON_VOLATILE
,
1674 if (lError
!= ERROR_SUCCESS
)
1676 ret
= CR_REGISTRY_ERROR
;
1682 if (RegDeleteValueW(hPropKey
,
1684 ret
= CR_REGISTRY_ERROR
;
1688 if (RegSetValueExW(hPropKey
,
1694 ret
= CR_REGISTRY_ERROR
;
1698 if (hPropKey
!= NULL
)
1699 RegCloseKey(hPropKey
);
1701 if (hInstKey
!= NULL
)
1702 RegCloseKey(hInstKey
);
1709 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1710 OUT LPWSTR pszEnumerator
,
1711 OUT LPWSTR pszDevice
,
1712 OUT LPWSTR pszInstance
)
1714 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1715 LPWSTR lpEnumerator
= NULL
;
1716 LPWSTR lpDevice
= NULL
;
1717 LPWSTR lpInstance
= NULL
;
1720 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1726 lpEnumerator
= szLocalDeviceInstanceID
;
1728 ptr
= wcschr(lpEnumerator
, L
'\\');
1734 ptr
= wcschr(lpDevice
, L
'\\');
1742 if (lpEnumerator
!= NULL
)
1743 wcscpy(pszEnumerator
, lpEnumerator
);
1745 if (lpDevice
!= NULL
)
1746 wcscpy(pszDevice
, lpDevice
);
1748 if (lpInstance
!= NULL
)
1749 wcscpy(pszInstance
, lpInstance
);
1754 CreateDeviceInstance(LPWSTR pszDeviceID
)
1756 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1757 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1758 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1759 HKEY hKeyEnumerator
;
1765 /* Split the instance ID */
1766 SplitDeviceInstanceID(pszDeviceID
,
1771 /* Open or create the enumerator key */
1772 lError
= RegCreateKeyExW(hEnumKey
,
1776 REG_OPTION_NON_VOLATILE
,
1781 if (lError
!= ERROR_SUCCESS
)
1783 return CR_REGISTRY_ERROR
;
1786 /* Open or create the device key */
1787 lError
= RegCreateKeyExW(hKeyEnumerator
,
1791 REG_OPTION_NON_VOLATILE
,
1797 /* Close the enumerator key */
1798 RegCloseKey(hKeyEnumerator
);
1800 if (lError
!= ERROR_SUCCESS
)
1802 return CR_REGISTRY_ERROR
;
1805 /* Try to open the instance key and fail if it exists */
1806 lError
= RegOpenKeyExW(hKeyDevice
,
1811 if (lError
== ERROR_SUCCESS
)
1813 DPRINT1("Instance %S already exists!\n", szInstance
);
1814 RegCloseKey(hKeyInstance
);
1815 RegCloseKey(hKeyDevice
);
1816 return CR_ALREADY_SUCH_DEVINST
;
1819 /* Create a new instance key */
1820 lError
= RegCreateKeyExW(hKeyDevice
,
1824 REG_OPTION_NON_VOLATILE
,
1830 /* Close the device key */
1831 RegCloseKey(hKeyDevice
);
1833 if (lError
!= ERROR_SUCCESS
)
1835 return CR_REGISTRY_ERROR
;
1838 /* Create the 'Control' sub key */
1839 lError
= RegCreateKeyExW(hKeyInstance
,
1843 REG_OPTION_NON_VOLATILE
,
1848 if (lError
== ERROR_SUCCESS
)
1850 RegCloseKey(hKeyControl
);
1853 RegCloseKey(hKeyInstance
);
1855 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1865 LPWSTR pszParentDeviceID
,
1866 PNP_RPC_STRING_LEN ulLength
,
1869 CONFIGRET ret
= CR_SUCCESS
;
1871 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1873 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1875 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1876 DWORD dwInstanceNumber
;
1878 /* Generated ID is: Root\<Device ID>\<Instance number> */
1879 dwInstanceNumber
= 0;
1882 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1883 pszDeviceID
, dwInstanceNumber
);
1885 /* Try to create a device instance with this ID */
1886 ret
= CreateDeviceInstance(szGeneratedInstance
);
1890 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1892 if (ret
== CR_SUCCESS
)
1894 /* pszDeviceID is an out parameter too for generated IDs */
1895 if (wcslen(szGeneratedInstance
) > ulLength
)
1897 ret
= CR_BUFFER_SMALL
;
1901 wcscpy(pszDeviceID
, szGeneratedInstance
);
1907 /* Create the device instance */
1908 ret
= CreateDeviceInstance(pszDeviceID
);
1911 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1918 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1919 LPWSTR pszDeviceInstanceSource
)
1921 DPRINT("MoveDeviceInstance: not implemented\n");
1923 return CR_CALL_NOT_IMPLEMENTED
;
1928 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1931 DPRINT("SetupDeviceInstance: not implemented\n");
1933 return CR_CALL_NOT_IMPLEMENTED
;
1938 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1940 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1941 CONFIGRET ret
= CR_SUCCESS
;
1944 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
1946 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1947 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1948 if (!NT_SUCCESS(Status
))
1949 ret
= NtStatusToCrError(Status
);
1956 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1958 DPRINT("DisableDeviceInstance: not implemented\n");
1960 return CR_CALL_NOT_IMPLEMENTED
;
1965 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1967 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1969 return CR_CALL_NOT_IMPLEMENTED
;
1976 PNP_DeviceInstanceAction(
1980 LPWSTR pszDeviceInstance1
,
1981 LPWSTR pszDeviceInstance2
)
1983 CONFIGRET ret
= CR_SUCCESS
;
1985 UNREFERENCED_PARAMETER(hBinding
);
1987 DPRINT("PNP_DeviceInstanceAction() called\n");
1991 case PNP_DEVINST_MOVE
:
1992 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1993 pszDeviceInstance2
);
1996 case PNP_DEVINST_SETUP
:
1997 ret
= SetupDeviceInstance(pszDeviceInstance1
,
2001 case PNP_DEVINST_ENABLE
:
2002 ret
= EnableDeviceInstance(pszDeviceInstance1
);
2005 case PNP_DEVINST_DISABLE
:
2006 ret
= DisableDeviceInstance(pszDeviceInstance1
);
2009 case PNP_DEVINST_REENUMERATE
:
2010 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
2014 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2015 ret
= CR_CALL_NOT_IMPLEMENTED
;
2018 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2027 PNP_GetDeviceStatus(
2034 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
2035 CONFIGRET ret
= CR_SUCCESS
;
2038 UNREFERENCED_PARAMETER(hBinding
);
2039 UNREFERENCED_PARAMETER(ulFlags
);
2041 DPRINT("PNP_GetDeviceStatus() called\n");
2043 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2045 PlugPlayData
.Operation
= 0; /* Get status */
2047 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2048 (PVOID
)&PlugPlayData
,
2049 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2050 if (NT_SUCCESS(Status
))
2052 *pulStatus
= PlugPlayData
.DeviceStatus
;
2053 *pulProblem
= PlugPlayData
.DeviceProblem
;
2057 ret
= NtStatusToCrError(Status
);
2060 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2069 PNP_SetDeviceProblem(
2076 return CR_CALL_NOT_IMPLEMENTED
;
2086 PPNP_VETO_TYPE pVetoType
,
2092 return CR_CALL_NOT_IMPLEMENTED
;
2098 PNP_UninstallDevInst(
2104 return CR_CALL_NOT_IMPLEMENTED
;
2109 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2115 lpPtr
= lpDeviceIdList
;
2118 dwLength
= wcslen(lpPtr
);
2119 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2122 lpPtr
+= (dwLength
+ 1);
2130 AppendDeviceId(LPWSTR lpDeviceIdList
,
2131 LPDWORD lpDeviceIdListSize
,
2137 dwLen
= wcslen(lpDeviceId
);
2138 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2140 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2142 dwPos
+= (dwLen
+ 1);
2144 lpDeviceIdList
[dwPos
] = 0;
2146 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2159 CONFIGRET ret
= CR_SUCCESS
;
2162 DWORD dwDeviceIdListSize
;
2163 DWORD dwNewDeviceIdSize
;
2164 WCHAR
* pszDeviceIdList
= NULL
;
2166 UNREFERENCED_PARAMETER(hBinding
);
2168 DPRINT("PNP_AddID() called\n");
2169 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2170 DPRINT(" DeviceId: %S\n", pszID
);
2171 DPRINT(" Flags: %lx\n", ulFlags
);
2173 if (RegOpenKeyExW(hEnumKey
,
2176 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2177 &hDeviceKey
) != ERROR_SUCCESS
)
2179 DPRINT("Failed to open the device key!\n");
2180 return CR_INVALID_DEVNODE
;
2183 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2185 if (RegQueryValueExW(hDeviceKey
,
2190 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2192 DPRINT("Failed to query the desired ID string!\n");
2193 ret
= CR_REGISTRY_ERROR
;
2197 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2198 if (!dwNewDeviceIdSize
)
2200 ret
= CR_INVALID_POINTER
;
2204 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2206 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2207 if (!pszDeviceIdList
)
2209 DPRINT("Failed to allocate memory for the desired ID string!\n");
2210 ret
= CR_OUT_OF_MEMORY
;
2214 if (RegQueryValueExW(hDeviceKey
,
2218 (LPBYTE
)pszDeviceIdList
,
2219 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2221 DPRINT("Failed to query the desired ID string!\n");
2222 ret
= CR_REGISTRY_ERROR
;
2226 /* Check whether the device ID is already in use */
2227 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2229 DPRINT("Device ID was found in the ID string!\n");
2234 /* Append the Device ID */
2235 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2237 if (RegSetValueExW(hDeviceKey
,
2241 (LPBYTE
)pszDeviceIdList
,
2242 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2244 DPRINT("Failed to set the desired ID string!\n");
2245 ret
= CR_REGISTRY_ERROR
;
2249 RegCloseKey(hDeviceKey
);
2250 if (pszDeviceIdList
)
2251 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2253 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2268 return CR_CALL_NOT_IMPLEMENTED
;
2278 PPNP_VETO_TYPE pVetoType
,
2284 return CR_CALL_NOT_IMPLEMENTED
;
2291 PNP_RequestDeviceEject(
2294 PPNP_VETO_TYPE pVetoType
,
2300 return CR_CALL_NOT_IMPLEMENTED
;
2307 PNP_IsDockStationPresent(
2315 CONFIGRET ret
= CR_SUCCESS
;
2317 UNREFERENCED_PARAMETER(hBinding
);
2319 DPRINT1("PNP_IsDockStationPresent() called\n");
2323 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2327 &hKey
) != ERROR_SUCCESS
)
2328 return CR_REGISTRY_ERROR
;
2330 dwSize
= sizeof(DWORD
);
2331 if (RegQueryValueExW(hKey
,
2336 &dwSize
) != ERROR_SUCCESS
)
2337 ret
= CR_REGISTRY_ERROR
;
2341 if (ret
== CR_SUCCESS
)
2343 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2345 ret
= CR_REGISTRY_ERROR
;
2347 else if (dwValue
!= 0)
2353 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2366 return CR_CALL_NOT_IMPLEMENTED
;
2379 PPNP_VETO_TYPE pVetoType
,
2384 CONFIGRET ret
= CR_SUCCESS
;
2385 WCHAR szKeyName
[MAX_PATH
];
2390 UNREFERENCED_PARAMETER(hBinding
);
2392 DPRINT("PNP_HwProfFlags() called\n");
2397 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2402 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2406 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2410 &hKey
) != ERROR_SUCCESS
)
2411 return CR_REGISTRY_ERROR
;
2413 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2415 if (RegOpenKeyExW(hKey
,
2419 &hDeviceKey
) != ERROR_SUCCESS
)
2425 dwSize
= sizeof(DWORD
);
2426 if (!RegQueryValueExW(hDeviceKey
,
2431 &dwSize
) != ERROR_SUCCESS
)
2436 RegCloseKey(hDeviceKey
);
2439 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2441 /* FIXME: not implemented yet */
2442 ret
= CR_CALL_NOT_IMPLEMENTED
;
2457 HWPROFILEINFO
*pHWProfileInfo
,
2458 DWORD ulProfileInfoSize
,
2461 WCHAR szProfileName
[5];
2462 HKEY hKeyConfig
= NULL
;
2463 HKEY hKeyProfiles
= NULL
;
2464 HKEY hKeyProfile
= NULL
;
2465 DWORD dwDisposition
;
2468 CONFIGRET ret
= CR_SUCCESS
;
2470 UNREFERENCED_PARAMETER(hBinding
);
2472 DPRINT("PNP_GetHwProfInfo() called\n");
2474 if (ulProfileInfoSize
== 0)
2476 ret
= CR_INVALID_DATA
;
2482 ret
= CR_INVALID_FLAG
;
2486 /* Initialize the profile information */
2487 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2488 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2489 pHWProfileInfo
->HWPI_dwFlags
= 0;
2491 /* Open the 'IDConfigDB' key */
2492 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2493 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2496 REG_OPTION_NON_VOLATILE
,
2501 if (lError
!= ERROR_SUCCESS
)
2503 ret
= CR_REGISTRY_ERROR
;
2507 /* Open the 'Hardware Profiles' subkey */
2508 lError
= RegCreateKeyExW(hKeyConfig
,
2509 L
"Hardware Profiles",
2512 REG_OPTION_NON_VOLATILE
,
2513 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2517 if (lError
!= ERROR_SUCCESS
)
2519 ret
= CR_REGISTRY_ERROR
;
2523 if (ulIndex
== (ULONG
)-1)
2525 dwSize
= sizeof(ULONG
);
2526 lError
= RegQueryValueExW(hKeyConfig
,
2530 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2532 if (lError
!= ERROR_SUCCESS
)
2534 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2535 ret
= CR_REGISTRY_ERROR
;
2541 /* FIXME: not implemented yet */
2542 ret
= CR_CALL_NOT_IMPLEMENTED
;
2546 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2548 lError
= RegOpenKeyExW(hKeyProfiles
,
2553 if (lError
!= ERROR_SUCCESS
)
2555 ret
= CR_REGISTRY_ERROR
;
2559 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2560 lError
= RegQueryValueExW(hKeyProfile
,
2564 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2566 if (lError
!= ERROR_SUCCESS
)
2568 ret
= CR_REGISTRY_ERROR
;
2573 if (hKeyProfile
!= NULL
)
2574 RegCloseKey(hKeyProfile
);
2576 if (hKeyProfiles
!= NULL
)
2577 RegCloseKey(hKeyProfiles
);
2579 if (hKeyConfig
!= NULL
)
2580 RegCloseKey(hKeyConfig
);
2589 PNP_AddEmptyLogConf(
2593 DWORD
*pulLogConfTag
,
2597 return CR_CALL_NOT_IMPLEMENTED
;
2607 DWORD ulLogConfType
,
2612 return CR_CALL_NOT_IMPLEMENTED
;
2619 PNP_GetFirstLogConf(
2622 DWORD ulLogConfType
,
2623 DWORD
*pulLogConfTag
,
2627 return CR_CALL_NOT_IMPLEMENTED
;
2637 DWORD ulLogConfType
,
2643 return CR_CALL_NOT_IMPLEMENTED
;
2650 PNP_GetLogConfPriority(
2659 return CR_CALL_NOT_IMPLEMENTED
;
2670 DWORD ulLogConfType
,
2671 RESOURCEID ResourceID
,
2672 DWORD
*pulResourceTag
,
2674 PNP_RPC_BUFFER_SIZE ResourceLen
,
2678 return CR_CALL_NOT_IMPLEMENTED
;
2689 DWORD ulLogConfType
,
2690 RESOURCEID ResourceID
,
2691 DWORD ulResourceTag
,
2692 DWORD
*pulPreviousResType
,
2693 DWORD
*pulPreviousResTag
,
2697 return CR_CALL_NOT_IMPLEMENTED
;
2708 DWORD ulLogConfType
,
2709 RESOURCEID ResourceID
,
2710 DWORD ulResourceTag
,
2711 DWORD
*pulNextResType
,
2712 DWORD
*pulNextResTag
,
2716 return CR_CALL_NOT_IMPLEMENTED
;
2727 DWORD ulLogConfType
,
2728 RESOURCEID ResourceID
,
2729 DWORD ulResourceTag
,
2731 PNP_RPC_BUFFER_SIZE BufferLen
,
2735 return CR_CALL_NOT_IMPLEMENTED
;
2742 PNP_GetResDesDataSize(
2746 DWORD ulLogConfType
,
2747 RESOURCEID ResourceID
,
2748 DWORD ulResourceTag
,
2753 return CR_CALL_NOT_IMPLEMENTED
;
2764 DWORD ulLogConfType
,
2765 RESOURCEID CurrentResourceID
,
2766 RESOURCEID NewResourceID
,
2767 DWORD ulResourceTag
,
2769 PNP_RPC_BUFFER_SIZE ResourceLen
,
2773 return CR_CALL_NOT_IMPLEMENTED
;
2780 PNP_DetectResourceConflict(
2783 RESOURCEID ResourceID
,
2785 PNP_RPC_BUFFER_SIZE ResourceLen
,
2786 BOOL
*pbConflictDetected
,
2790 return CR_CALL_NOT_IMPLEMENTED
;
2797 PNP_QueryResConfList(
2800 RESOURCEID ResourceID
,
2802 PNP_RPC_BUFFER_SIZE ResourceLen
,
2804 PNP_RPC_BUFFER_SIZE BufferLen
,
2808 return CR_CALL_NOT_IMPLEMENTED
;
2817 DWORD ulHardwareProfile
,
2821 return CR_CALL_NOT_IMPLEMENTED
;
2828 PNP_QueryArbitratorFreeData(
2833 RESOURCEID ResourceID
,
2837 return CR_CALL_NOT_IMPLEMENTED
;
2844 PNP_QueryArbitratorFreeSize(
2848 RESOURCEID ResourceID
,
2852 return CR_CALL_NOT_IMPLEMENTED
;
2863 return CR_CALL_NOT_IMPLEMENTED
;
2870 PNP_RegisterNotification(
2876 PNOTIFY_DATA pNotifyData
;
2879 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
2880 hBinding
, ulFlags
, pulNotify
);
2883 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
2884 if (pNotifyData
== NULL
)
2885 return CR_OUT_OF_MEMORY
;
2887 *pulNotify
= (DWORD
)pNotifyData
;
2899 PNP_UnregisterNotification(
2903 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
2904 hBinding
, ulNotify
);
2908 return CR_CALL_NOT_IMPLEMENTED
;
2918 PNP_GetCustomDevProp(
2921 LPWSTR CustomPropName
,
2922 DWORD
*pulRegDataType
,
2924 PNP_RPC_STRING_LEN
*pulTransferLen
,
2925 PNP_RPC_STRING_LEN
*pulLength
,
2928 HKEY hDeviceKey
= NULL
;
2929 HKEY hParamKey
= NULL
;
2931 CONFIGRET ret
= CR_SUCCESS
;
2933 UNREFERENCED_PARAMETER(hBinding
);
2935 DPRINT("PNP_GetCustomDevProp() called\n");
2937 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2939 ret
= CR_INVALID_POINTER
;
2943 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2945 ret
= CR_INVALID_FLAG
;
2949 if (*pulLength
< *pulTransferLen
)
2950 *pulLength
= *pulTransferLen
;
2952 *pulTransferLen
= 0;
2954 lError
= RegOpenKeyExW(hEnumKey
,
2959 if (lError
!= ERROR_SUCCESS
)
2961 ret
= CR_REGISTRY_ERROR
;
2965 lError
= RegOpenKeyExW(hDeviceKey
,
2966 L
"Device Parameters",
2970 if (lError
!= ERROR_SUCCESS
)
2972 ret
= CR_REGISTRY_ERROR
;
2976 lError
= RegQueryValueExW(hParamKey
,
2982 if (lError
!= ERROR_SUCCESS
)
2984 if (lError
== ERROR_MORE_DATA
)
2986 ret
= CR_BUFFER_SMALL
;
2991 ret
= CR_NO_SUCH_VALUE
;
2996 if (ret
== CR_SUCCESS
)
2997 *pulTransferLen
= *pulLength
;
2999 if (hParamKey
!= NULL
)
3000 RegCloseKey(hParamKey
);
3002 if (hDeviceKey
!= NULL
)
3003 RegCloseKey(hDeviceKey
);
3005 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3014 PNP_GetVersionInternal(
3018 UNREFERENCED_PARAMETER(hBinding
);
3028 PNP_GetBlockedDriverInfo(
3031 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3032 PNP_RPC_BUFFER_SIZE
*pulLength
,
3036 return CR_CALL_NOT_IMPLEMENTED
;
3043 PNP_GetServerSideDeviceInstallFlags(
3045 DWORD
*pulSSDIFlags
,
3048 UNREFERENCED_PARAMETER(hBinding
);
3050 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
3051 hBinding
, pulSSDIFlags
, ulFlags
);
3053 if (pulSSDIFlags
== NULL
)
3054 return CR_INVALID_POINTER
;
3057 return CR_INVALID_FLAG
;
3069 PNP_GetObjectPropKeys(
3073 LPWSTR PropertyCultureName
,
3074 PNP_PROP_COUNT
*PropertyCount
,
3075 PNP_PROP_COUNT
*TransferLen
,
3076 DEVPROPKEY
*PropertyKeys
,
3080 return CR_CALL_NOT_IMPLEMENTED
;
3091 LPWSTR PropertyCultureName
,
3092 const DEVPROPKEY
*PropertyKey
,
3093 DEVPROPTYPE
*PropertyType
,
3094 PNP_PROP_SIZE
*PropertySize
,
3095 PNP_PROP_SIZE
*TransferLen
,
3096 BYTE
*PropertyBuffer
,
3100 return CR_CALL_NOT_IMPLEMENTED
;
3111 LPWSTR PropertyCultureName
,
3112 const DEVPROPKEY
*PropertyKey
,
3113 DEVPROPTYPE PropertyType
,
3114 PNP_PROP_SIZE PropertySize
,
3115 BYTE
*PropertyBuffer
,
3119 return CR_CALL_NOT_IMPLEMENTED
;
3130 return CR_CALL_NOT_IMPLEMENTED
;
3137 PNP_ApplyPowerSettings(
3141 return CR_CALL_NOT_IMPLEMENTED
;
3148 PNP_DriverStoreAddDriverPackage(
3152 return CR_CALL_NOT_IMPLEMENTED
;
3159 PNP_DriverStoreDeleteDriverPackage(
3163 return CR_CALL_NOT_IMPLEMENTED
;
3170 PNP_RegisterServiceNotification(
3174 return CR_CALL_NOT_IMPLEMENTED
;
3181 PNP_SetActiveService(
3187 return CR_CALL_NOT_IMPLEMENTED
;
3194 PNP_DeleteServiceDevices(
3198 return CR_CALL_NOT_IMPLEMENTED
;
3203 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3205 BOOL DeviceInstalled
= FALSE
;
3208 HANDLE hInstallEvent
;
3209 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3210 LPVOID Environment
= NULL
;
3211 PROCESS_INFORMATION ProcessInfo
;
3212 STARTUPINFOW StartupInfo
;
3216 /* The following lengths are constant (see below), they cannot overflow */
3217 WCHAR CommandLine
[116];
3218 WCHAR InstallEventName
[73];
3220 WCHAR UuidString
[39];
3222 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3224 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3226 if (RegOpenKeyExW(hEnumKey
,
3230 &DeviceKey
) == ERROR_SUCCESS
)
3232 if (RegQueryValueExW(DeviceKey
,
3237 NULL
) == ERROR_SUCCESS
)
3239 DPRINT("No need to install: %S\n", DeviceInstance
);
3240 RegCloseKey(DeviceKey
);
3244 BytesWritten
= sizeof(DWORD
);
3245 if (RegQueryValueExW(DeviceKey
,
3250 &BytesWritten
) == ERROR_SUCCESS
)
3252 if (Value
& CONFIGFLAG_FAILEDINSTALL
)
3254 DPRINT("No need to install: %S\n", DeviceInstance
);
3255 RegCloseKey(DeviceKey
);
3260 RegCloseKey(DeviceKey
);
3263 DPRINT1("Installing: %S\n", DeviceInstance
);
3265 /* Create a random UUID for the named pipe & event*/
3266 UuidCreate(&RandomUuid
);
3267 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3268 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3269 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3270 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3271 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3273 /* Create the event */
3274 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3275 wcscat(InstallEventName
, UuidString
);
3276 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3279 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3283 /* Create the named pipe */
3284 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3285 wcscat(PipeName
, UuidString
);
3286 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3287 if (hPipe
== INVALID_HANDLE_VALUE
)
3289 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3293 /* Launch rundll32 to call ClientSideInstallW */
3294 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3295 wcscat(CommandLine
, PipeName
);
3297 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3298 StartupInfo
.cb
= sizeof(StartupInfo
);
3302 /* newdev has to run under the environment of the current user */
3303 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3305 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3309 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3311 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3317 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3319 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3320 (ShowWizard is only set to FALSE for these two modes) */
3321 ASSERT(!ShowWizard
);
3323 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3325 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3330 /* Wait for the function to connect to our pipe */
3331 if (!ConnectNamedPipe(hPipe
, NULL
))
3333 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3335 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3340 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3341 Value
= sizeof(InstallEventName
);
3342 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3343 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3345 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3346 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3347 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3349 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3350 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3351 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3353 /* Wait for newdev.dll to finish processing */
3354 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3356 /* If the event got signalled, this is success */
3357 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3361 CloseHandle(hInstallEvent
);
3363 if (hPipe
!= INVALID_HANDLE_VALUE
)
3367 DestroyEnvironmentBlock(Environment
);
3369 if (ProcessInfo
.hProcess
)
3370 CloseHandle(ProcessInfo
.hProcess
);
3372 if (ProcessInfo
.hThread
)
3373 CloseHandle(ProcessInfo
.hThread
);
3375 if (!DeviceInstalled
)
3377 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3380 return DeviceInstalled
;
3396 return ERROR_INVALID_PARAMETER
;
3399 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3400 if (rc
!= ERROR_SUCCESS
)
3402 if (dwType
!= REG_SZ
)
3403 return ERROR_FILE_NOT_FOUND
;
3404 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3406 return ERROR_NOT_ENOUGH_MEMORY
;
3407 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3408 if (rc
!= ERROR_SUCCESS
)
3410 HeapFree(GetProcessHeap(), 0, Value
);
3413 /* NULL-terminate the string */
3414 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3417 return ERROR_SUCCESS
;
3425 DWORD regType
, active
, size
;
3429 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3430 if (rc
!= ERROR_SUCCESS
)
3433 size
= sizeof(DWORD
);
3434 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3435 if (rc
!= ERROR_SUCCESS
)
3437 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3440 ret
= (active
!= 0);
3446 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3455 HKEY ControlKey
= NULL
;
3456 LPWSTR SystemStartOptions
= NULL
;
3457 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3458 BOOL ConsoleBoot
= FALSE
;
3463 L
"SYSTEM\\CurrentControlSet\\Control",
3468 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3469 if (rc
!= ERROR_SUCCESS
)
3472 /* Check for CONSOLE switch in SystemStartOptions */
3473 CurrentOption
= SystemStartOptions
;
3474 while (CurrentOption
)
3476 NextOption
= wcschr(CurrentOption
, L
' ');
3478 *NextOption
= L
'\0';
3479 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3481 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3485 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3489 if (ControlKey
!= NULL
)
3490 RegCloseKey(ControlKey
);
3491 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3496 /* Loop to install all queued devices installations */
3498 DeviceInstallThread(LPVOID lpParameter
)
3500 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3501 PSLIST_ENTRY ListEntry
;
3503 PLIST_ENTRY ListEntry
;
3505 DeviceInstallParams
* Params
;
3508 UNREFERENCED_PARAMETER(lpParameter
);
3510 WaitForSingleObject(hInstallEvent
, INFINITE
);
3512 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3516 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3517 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3519 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3522 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3524 if (ListEntry
== NULL
)
3526 SetEvent(hNoPendingInstalls
);
3527 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3531 ResetEvent(hNoPendingInstalls
);
3532 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3533 InstallDevice(Params
->DeviceIds
, showWizard
);
3542 PnpEventThread(LPVOID lpParameter
)
3544 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3547 RPC_STATUS RpcStatus
;
3549 UNREFERENCED_PARAMETER(lpParameter
);
3551 PnpEventSize
= 0x1000;
3552 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3553 if (PnpEvent
== NULL
)
3554 return ERROR_OUTOFMEMORY
;
3558 DPRINT("Calling NtGetPlugPlayEvent()\n");
3560 /* Wait for the next pnp event */
3561 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3563 /* Resize the buffer for the PnP event if it's too small. */
3564 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3566 PnpEventSize
+= 0x400;
3567 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3568 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3569 if (PnpEvent
== NULL
)
3570 return ERROR_OUTOFMEMORY
;
3574 if (!NT_SUCCESS(Status
))
3576 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3580 /* Process the pnp event */
3581 DPRINT("Received PnP Event\n");
3582 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3584 DeviceInstallParams
* Params
;
3586 DWORD DeviceIdLength
;
3588 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3590 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3593 /* Queue device install (will be dequeued by DeviceInstallThread */
3594 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3595 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3598 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3599 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3600 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3602 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3604 SetEvent(hDeviceInstallListNotEmpty
);
3608 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3610 // DWORD dwRecipient;
3612 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3614 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3615 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3618 // DBT_DEVNODES_CHANGED,
3620 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3622 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3624 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3626 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3628 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3630 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3632 // DWORD dwRecipient;
3634 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3636 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3637 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3640 // DBT_DEVNODES_CHANGED,
3642 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3644 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3646 // DWORD dwRecipient;
3648 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3650 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3651 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3654 // DBT_DEVNODES_CHANGED,
3656 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3658 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3660 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3662 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3664 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3668 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3669 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3670 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3671 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3672 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3675 /* Dequeue the current pnp event and signal the next one */
3676 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3679 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3681 return ERROR_SUCCESS
;
3686 UpdateServiceStatus(DWORD dwState
)
3688 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3689 ServiceStatus
.dwCurrentState
= dwState
;
3690 ServiceStatus
.dwControlsAccepted
= 0;
3691 ServiceStatus
.dwWin32ExitCode
= 0;
3692 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3693 ServiceStatus
.dwCheckPoint
= 0;
3695 if (dwState
== SERVICE_START_PENDING
||
3696 dwState
== SERVICE_STOP_PENDING
||
3697 dwState
== SERVICE_PAUSE_PENDING
||
3698 dwState
== SERVICE_CONTINUE_PENDING
)
3699 ServiceStatus
.dwWaitHint
= 10000;
3701 ServiceStatus
.dwWaitHint
= 0;
3703 SetServiceStatus(ServiceStatusHandle
,
3709 ServiceControlHandler(DWORD dwControl
,
3714 DPRINT1("ServiceControlHandler() called\n");
3718 case SERVICE_CONTROL_STOP
:
3719 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3720 /* Stop listening to RPC Messages */
3721 RpcMgmtStopServerListening(NULL
);
3722 UpdateServiceStatus(SERVICE_STOPPED
);
3723 return ERROR_SUCCESS
;
3725 case SERVICE_CONTROL_PAUSE
:
3726 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3727 UpdateServiceStatus(SERVICE_PAUSED
);
3728 return ERROR_SUCCESS
;
3730 case SERVICE_CONTROL_CONTINUE
:
3731 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3732 UpdateServiceStatus(SERVICE_RUNNING
);
3733 return ERROR_SUCCESS
;
3735 case SERVICE_CONTROL_INTERROGATE
:
3736 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3737 SetServiceStatus(ServiceStatusHandle
,
3739 return ERROR_SUCCESS
;
3741 case SERVICE_CONTROL_SHUTDOWN
:
3742 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3743 /* Stop listening to RPC Messages */
3744 RpcMgmtStopServerListening(NULL
);
3745 UpdateServiceStatus(SERVICE_STOPPED
);
3746 return ERROR_SUCCESS
;
3749 DPRINT1(" Control %lu received\n", dwControl
);
3750 return ERROR_CALL_NOT_IMPLEMENTED
;
3756 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3761 UNREFERENCED_PARAMETER(argc
);
3762 UNREFERENCED_PARAMETER(argv
);
3764 DPRINT("ServiceMain() called\n");
3766 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3767 ServiceControlHandler
,
3769 if (!ServiceStatusHandle
)
3771 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3775 UpdateServiceStatus(SERVICE_START_PENDING
);
3777 hThread
= CreateThread(NULL
,
3783 if (hThread
!= NULL
)
3784 CloseHandle(hThread
);
3786 hThread
= CreateThread(NULL
,
3792 if (hThread
!= NULL
)
3793 CloseHandle(hThread
);
3795 hThread
= CreateThread(NULL
,
3797 DeviceInstallThread
,
3801 if (hThread
!= NULL
)
3802 CloseHandle(hThread
);
3804 UpdateServiceStatus(SERVICE_RUNNING
);
3806 DPRINT("ServiceMain() done\n");
3810 InitializePnPManager(VOID
)
3815 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3817 /* We need this privilege for using CreateProcessAsUserW */
3818 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3820 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3821 if (hInstallEvent
== NULL
)
3823 dwError
= GetLastError();
3824 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3828 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3829 if (hDeviceInstallListNotEmpty
== NULL
)
3831 dwError
= GetLastError();
3832 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3836 hNoPendingInstalls
= CreateEventW(NULL
,
3839 L
"Global\\PnP_No_Pending_Install_Events");
3840 if (hNoPendingInstalls
== NULL
)
3842 dwError
= GetLastError();
3843 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3847 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3848 InitializeSListHead(&DeviceInstallListHead
);
3850 InitializeListHead(&DeviceInstallListHead
);
3853 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3854 L
"System\\CurrentControlSet\\Enum",
3858 if (dwError
!= ERROR_SUCCESS
)
3860 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3864 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3865 L
"System\\CurrentControlSet\\Control\\Class",
3869 if (dwError
!= ERROR_SUCCESS
)
3871 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3875 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3881 DllMain(HINSTANCE hinstDLL
,
3887 case DLL_PROCESS_ATTACH
:
3888 DisableThreadLibraryCalls(hinstDLL
);
3889 InitializePnPManager();
3892 case DLL_PROCESS_DETACH
: