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
:
785 PlugPlayData
.Property
= PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME
;
788 case CM_DRP_CAPABILITIES
:
789 lpValueName
= L
"Capabilities";
792 case CM_DRP_UI_NUMBER
:
793 PlugPlayData
.Property
= PNP_PROPERTY_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
:
805 PlugPlayData
.Property
= PNP_PROPERTY_BUSTYPEGUID
;
808 case CM_DRP_LEGACYBUSTYPE
:
809 PlugPlayData
.Property
= PNP_PROPERTY_LEGACYBUSTYPE
;
812 case CM_DRP_BUSNUMBER
:
813 PlugPlayData
.Property
= PNP_PROPERTY_BUSNUMBER
;
816 case CM_DRP_ENUMERATOR_NAME
:
817 PlugPlayData
.Property
= PNP_PROPERTY_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";
837 PlugPlayData
.Property
= PNP_PROPERTY_ADDRESS
;
840 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
841 lpValueName
= L
"UINumberDescFormat";
844 case CM_DRP_DEVICE_POWER_DATA
:
845 PlugPlayData
.Property
= PNP_PROPERTY_POWER_DATA
;
848 case CM_DRP_REMOVAL_POLICY
:
849 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY
;
852 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
853 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
;
856 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
857 lpValueName
= L
"RemovalPolicy";
860 case CM_DRP_INSTALL_STATE
:
861 PlugPlayData
.Property
= PNP_PROPERTY_INSTALL_STATE
;
864 #if (WINVER >= _WIN32_WINNT_WS03)
865 case CM_DRP_LOCATION_PATHS
:
866 PlugPlayData
.Property
= PNP_PROPERTY_LOCATION_PATHS
;
870 #if (WINVER >= _WIN32_WINNT_WIN7)
871 case CM_DRP_BASE_CONTAINERID
:
872 PlugPlayData
.Property
= PNP_PROPERTY_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
;
926 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
927 (PVOID
)&PlugPlayData
,
928 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
929 if (NT_SUCCESS(Status
))
931 *pulLength
= PlugPlayData
.BufferSize
;
935 ret
= NtStatusToCrError(Status
);
941 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
946 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
955 PNP_SetDeviceRegProp(
961 PNP_PROP_SIZE ulLength
,
964 CONFIGRET ret
= CR_SUCCESS
;
965 LPWSTR lpValueName
= NULL
;
968 UNREFERENCED_PARAMETER(hBinding
);
969 UNREFERENCED_PARAMETER(ulFlags
);
971 DPRINT("PNP_SetDeviceRegProp() called\n");
973 DPRINT("DeviceId: %S\n", pDeviceId
);
974 DPRINT("Property: %lu\n", ulProperty
);
975 DPRINT("DataType: %lu\n", ulDataType
);
976 DPRINT("Length: %lu\n", ulLength
);
980 case CM_DRP_DEVICEDESC
:
981 lpValueName
= L
"DeviceDesc";
984 case CM_DRP_HARDWAREID
:
985 lpValueName
= L
"HardwareID";
988 case CM_DRP_COMPATIBLEIDS
:
989 lpValueName
= L
"CompatibleIDs";
993 lpValueName
= L
"Service";
997 lpValueName
= L
"Class";
1000 case CM_DRP_CLASSGUID
:
1001 lpValueName
= L
"ClassGUID";
1005 lpValueName
= L
"Driver";
1008 case CM_DRP_CONFIGFLAGS
:
1009 lpValueName
= L
"ConfigFlags";
1013 lpValueName
= L
"Mfg";
1016 case CM_DRP_FRIENDLYNAME
:
1017 lpValueName
= L
"FriendlyName";
1020 case CM_DRP_LOCATION_INFORMATION
:
1021 lpValueName
= L
"LocationInformation";
1024 case CM_DRP_UPPERFILTERS
:
1025 lpValueName
= L
"UpperFilters";
1028 case CM_DRP_LOWERFILTERS
:
1029 lpValueName
= L
"LowerFilters";
1032 case CM_DRP_SECURITY
:
1033 lpValueName
= L
"Security";
1036 case CM_DRP_DEVTYPE
:
1037 lpValueName
= L
"DeviceType";
1040 case CM_DRP_EXCLUSIVE
:
1041 lpValueName
= L
"Exclusive";
1044 case CM_DRP_CHARACTERISTICS
:
1045 lpValueName
= L
"DeviceCharacteristics";
1048 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1049 lpValueName
= L
"UINumberDescFormat";
1052 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1053 lpValueName
= L
"RemovalPolicy";
1057 return CR_INVALID_PROPERTY
;
1060 DPRINT("Value name: %S\n", lpValueName
);
1062 if (RegOpenKeyExW(hEnumKey
,
1067 return CR_INVALID_DEVNODE
;
1071 if (RegDeleteValueW(hKey
,
1073 ret
= CR_REGISTRY_ERROR
;
1077 if (RegSetValueExW(hKey
,
1083 ret
= CR_REGISTRY_ERROR
;
1088 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1097 PNP_GetClassInstance(
1100 LPWSTR pszClassInstance
,
1101 PNP_RPC_STRING_LEN ulLength
)
1104 return CR_CALL_NOT_IMPLEMENTED
;
1119 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1128 return CR_REGISTRY_ERROR
;
1130 /* FIXME: Set security key */
1141 PNP_DeleteRegistryKey(
1144 LPWSTR pszParentKey
,
1149 return CR_CALL_NOT_IMPLEMENTED
;
1158 DWORD
*pulClassCount
,
1164 UNREFERENCED_PARAMETER(hBinding
);
1165 UNREFERENCED_PARAMETER(ulFlags
);
1167 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1172 if (dwError
!= ERROR_SUCCESS
)
1173 return CR_INVALID_DATA
;
1175 dwError
= RegQueryInfoKeyW(hKey
,
1188 if (dwError
!= ERROR_SUCCESS
)
1189 return CR_INVALID_DATA
;
1200 LPWSTR pszClassGuid
,
1202 PNP_RPC_STRING_LEN
*pulLength
,
1205 WCHAR szKeyName
[MAX_PATH
];
1206 CONFIGRET ret
= CR_SUCCESS
;
1210 UNREFERENCED_PARAMETER(hBinding
);
1211 UNREFERENCED_PARAMETER(ulFlags
);
1213 DPRINT("PNP_GetClassName() called\n");
1215 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1216 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1217 lstrcatW(szKeyName
, pszClassGuid
);
1219 return CR_INVALID_DATA
;
1221 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1226 return CR_REGISTRY_ERROR
;
1228 dwSize
= *pulLength
* sizeof(WCHAR
);
1229 if (RegQueryValueExW(hKey
,
1237 ret
= CR_REGISTRY_ERROR
;
1241 *pulLength
= dwSize
/ sizeof(WCHAR
);
1246 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1257 LPWSTR pszClassGuid
,
1260 CONFIGRET ret
= CR_SUCCESS
;
1262 UNREFERENCED_PARAMETER(hBinding
);
1264 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1266 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1268 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1269 ret
= CR_REGISTRY_ERROR
;
1273 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1274 ret
= CR_REGISTRY_ERROR
;
1277 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1286 PNP_GetInterfaceDeviceAlias(
1288 LPWSTR pszInterfaceDevice
,
1289 GUID
*AliasInterfaceGuid
,
1290 LPWSTR pszAliasInterfaceDevice
,
1291 PNP_RPC_STRING_LEN
*pulLength
,
1292 PNP_RPC_STRING_LEN
*pulTransferLen
,
1296 return CR_CALL_NOT_IMPLEMENTED
;
1303 PNP_GetInterfaceDeviceList(
1305 GUID
*InterfaceGuid
,
1308 PNP_RPC_BUFFER_SIZE
*pulLength
,
1312 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1313 DWORD ret
= CR_SUCCESS
;
1315 UNREFERENCED_PARAMETER(hBinding
);
1317 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1320 PlugPlayData
.Flags
= ulFlags
;
1321 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1322 PlugPlayData
.Buffer
= Buffer
;
1323 PlugPlayData
.BufferSize
= *pulLength
;
1325 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1326 (PVOID
)&PlugPlayData
,
1327 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1328 if (NT_SUCCESS(Status
))
1330 *pulLength
= PlugPlayData
.BufferSize
;
1334 ret
= NtStatusToCrError(Status
);
1337 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1345 PNP_GetInterfaceDeviceListSize(
1347 PNP_RPC_BUFFER_SIZE
*pulLen
,
1348 GUID
*InterfaceGuid
,
1353 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1354 DWORD ret
= CR_SUCCESS
;
1356 UNREFERENCED_PARAMETER(hBinding
);
1358 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1360 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1363 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1364 PlugPlayData
.Buffer
= NULL
;
1365 PlugPlayData
.BufferSize
= 0;
1366 PlugPlayData
.Flags
= ulFlags
;
1368 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1369 (PVOID
)&PlugPlayData
,
1370 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1371 if (NT_SUCCESS(Status
))
1373 *pulLen
= PlugPlayData
.BufferSize
;
1377 ret
= NtStatusToCrError(Status
);
1380 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1388 PNP_RegisterDeviceClassAssociation(
1391 GUID
*InterfaceGuid
,
1392 LPWSTR pszReference
,
1394 PNP_RPC_STRING_LEN
*pulLength
,
1395 PNP_RPC_STRING_LEN
*pulTransferLen
,
1399 return CR_CALL_NOT_IMPLEMENTED
;
1406 PNP_UnregisterDeviceClassAssociation(
1408 LPWSTR pszInterfaceDevice
,
1412 return CR_CALL_NOT_IMPLEMENTED
;
1419 PNP_GetClassRegProp(
1421 LPWSTR pszClassGuid
,
1423 DWORD
*pulRegDataType
,
1425 PNP_RPC_STRING_LEN
*pulTransferLen
,
1426 PNP_RPC_STRING_LEN
*pulLength
,
1429 CONFIGRET ret
= CR_SUCCESS
;
1430 LPWSTR lpValueName
= NULL
;
1431 HKEY hInstKey
= NULL
;
1432 HKEY hPropKey
= NULL
;
1435 UNREFERENCED_PARAMETER(hBinding
);
1437 DPRINT("PNP_GetClassRegProp() called\n");
1439 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1441 ret
= CR_INVALID_POINTER
;
1447 ret
= CR_INVALID_FLAG
;
1451 if (*pulLength
< *pulTransferLen
)
1452 *pulLength
= *pulTransferLen
;
1454 *pulTransferLen
= 0;
1458 case CM_CRP_SECURITY
:
1459 lpValueName
= L
"Security";
1462 case CM_CRP_DEVTYPE
:
1463 lpValueName
= L
"DeviceType";
1466 case CM_CRP_EXCLUSIVE
:
1467 lpValueName
= L
"Exclusive";
1470 case CM_CRP_CHARACTERISTICS
:
1471 lpValueName
= L
"DeviceCharacteristics";
1475 ret
= CR_INVALID_PROPERTY
;
1479 DPRINT("Value name: %S\n", lpValueName
);
1481 lError
= RegOpenKeyExW(hClassKey
,
1486 if (lError
!= ERROR_SUCCESS
)
1489 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1493 lError
= RegOpenKeyExW(hInstKey
,
1498 if (lError
!= ERROR_SUCCESS
)
1501 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1505 lError
= RegQueryValueExW(hPropKey
,
1511 if (lError
!= ERROR_SUCCESS
)
1513 if (lError
== ERROR_MORE_DATA
)
1515 ret
= CR_BUFFER_SMALL
;
1520 ret
= CR_NO_SUCH_VALUE
;
1525 if (ret
== CR_SUCCESS
)
1526 *pulTransferLen
= *pulLength
;
1528 if (hPropKey
!= NULL
)
1529 RegCloseKey(hPropKey
);
1531 if (hInstKey
!= NULL
)
1532 RegCloseKey(hInstKey
);
1534 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1543 PNP_SetClassRegProp(
1545 LPWSTR pszClassGuid
,
1549 PNP_PROP_SIZE ulLength
,
1552 CONFIGRET ret
= CR_SUCCESS
;
1553 LPWSTR lpValueName
= NULL
;
1558 UNREFERENCED_PARAMETER(hBinding
);
1560 DPRINT("PNP_SetClassRegProp() called\n");
1563 return CR_INVALID_FLAG
;
1567 case CM_CRP_SECURITY
:
1568 lpValueName
= L
"Security";
1571 case CM_CRP_DEVTYPE
:
1572 lpValueName
= L
"DeviceType";
1575 case CM_CRP_EXCLUSIVE
:
1576 lpValueName
= L
"Exclusive";
1579 case CM_CRP_CHARACTERISTICS
:
1580 lpValueName
= L
"DeviceCharacteristics";
1584 return CR_INVALID_PROPERTY
;
1587 lError
= RegOpenKeyExW(hClassKey
,
1592 if (lError
!= ERROR_SUCCESS
)
1594 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1598 /* FIXME: Set security descriptor */
1599 lError
= RegCreateKeyExW(hInstKey
,
1603 REG_OPTION_NON_VOLATILE
,
1608 if (lError
!= ERROR_SUCCESS
)
1610 ret
= CR_REGISTRY_ERROR
;
1616 if (RegDeleteValueW(hPropKey
,
1618 ret
= CR_REGISTRY_ERROR
;
1622 if (RegSetValueExW(hPropKey
,
1628 ret
= CR_REGISTRY_ERROR
;
1632 if (hPropKey
!= NULL
)
1633 RegCloseKey(hPropKey
);
1635 if (hInstKey
!= NULL
)
1636 RegCloseKey(hInstKey
);
1643 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1644 OUT LPWSTR pszEnumerator
,
1645 OUT LPWSTR pszDevice
,
1646 OUT LPWSTR pszInstance
)
1648 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1649 LPWSTR lpEnumerator
= NULL
;
1650 LPWSTR lpDevice
= NULL
;
1651 LPWSTR lpInstance
= NULL
;
1654 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1660 lpEnumerator
= szLocalDeviceInstanceID
;
1662 ptr
= wcschr(lpEnumerator
, L
'\\');
1668 ptr
= wcschr(lpDevice
, L
'\\');
1676 if (lpEnumerator
!= NULL
)
1677 wcscpy(pszEnumerator
, lpEnumerator
);
1679 if (lpDevice
!= NULL
)
1680 wcscpy(pszDevice
, lpDevice
);
1682 if (lpInstance
!= NULL
)
1683 wcscpy(pszInstance
, lpInstance
);
1688 CreateDeviceInstance(LPWSTR pszDeviceID
)
1690 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1691 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1692 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1693 HKEY hKeyEnumerator
;
1699 /* Split the instance ID */
1700 SplitDeviceInstanceID(pszDeviceID
,
1705 /* Open or create the enumerator key */
1706 lError
= RegCreateKeyExW(hEnumKey
,
1710 REG_OPTION_NON_VOLATILE
,
1715 if (lError
!= ERROR_SUCCESS
)
1717 return CR_REGISTRY_ERROR
;
1720 /* Open or create the device key */
1721 lError
= RegCreateKeyExW(hKeyEnumerator
,
1725 REG_OPTION_NON_VOLATILE
,
1731 /* Close the enumerator key */
1732 RegCloseKey(hKeyEnumerator
);
1734 if (lError
!= ERROR_SUCCESS
)
1736 return CR_REGISTRY_ERROR
;
1739 /* Try to open the instance key and fail if it exists */
1740 lError
= RegOpenKeyExW(hKeyDevice
,
1745 if (lError
== ERROR_SUCCESS
)
1747 DPRINT1("Instance %S already exists!\n", szInstance
);
1748 RegCloseKey(hKeyInstance
);
1749 RegCloseKey(hKeyDevice
);
1750 return CR_ALREADY_SUCH_DEVINST
;
1753 /* Create a new instance key */
1754 lError
= RegCreateKeyExW(hKeyDevice
,
1758 REG_OPTION_NON_VOLATILE
,
1764 /* Close the device key */
1765 RegCloseKey(hKeyDevice
);
1767 if (lError
!= ERROR_SUCCESS
)
1769 return CR_REGISTRY_ERROR
;
1772 /* Create the 'Control' sub key */
1773 lError
= RegCreateKeyExW(hKeyInstance
,
1777 REG_OPTION_NON_VOLATILE
,
1782 if (lError
== ERROR_SUCCESS
)
1784 RegCloseKey(hKeyControl
);
1787 RegCloseKey(hKeyInstance
);
1789 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1799 LPWSTR pszParentDeviceID
,
1800 PNP_RPC_STRING_LEN ulLength
,
1803 CONFIGRET ret
= CR_SUCCESS
;
1805 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1807 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1809 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1810 DWORD dwInstanceNumber
;
1812 /* Generated ID is: Root\<Device ID>\<Instance number> */
1813 dwInstanceNumber
= 0;
1816 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1817 pszDeviceID
, dwInstanceNumber
);
1819 /* Try to create a device instance with this ID */
1820 ret
= CreateDeviceInstance(szGeneratedInstance
);
1824 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1826 if (ret
== CR_SUCCESS
)
1828 /* pszDeviceID is an out parameter too for generated IDs */
1829 if (wcslen(szGeneratedInstance
) > ulLength
)
1831 ret
= CR_BUFFER_SMALL
;
1835 wcscpy(pszDeviceID
, szGeneratedInstance
);
1841 /* Create the device instance */
1842 ret
= CreateDeviceInstance(pszDeviceID
);
1845 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1852 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1853 LPWSTR pszDeviceInstanceSource
)
1855 DPRINT("MoveDeviceInstance: not implemented\n");
1857 return CR_CALL_NOT_IMPLEMENTED
;
1862 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1865 DPRINT("SetupDeviceInstance: not implemented\n");
1867 return CR_CALL_NOT_IMPLEMENTED
;
1872 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1874 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1875 CONFIGRET ret
= CR_SUCCESS
;
1878 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
1880 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1881 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1882 if (!NT_SUCCESS(Status
))
1883 ret
= NtStatusToCrError(Status
);
1890 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1892 DPRINT("DisableDeviceInstance: not implemented\n");
1894 return CR_CALL_NOT_IMPLEMENTED
;
1899 ReenumerateDeviceInstance(
1900 _In_ LPWSTR pszDeviceInstance
,
1903 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData
;
1904 CONFIGRET ret
= CR_SUCCESS
;
1907 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
1908 pszDeviceInstance
, ulFlags
);
1910 if (ulFlags
& ~CM_REENUMERATE_BITS
)
1911 return CR_INVALID_FLAG
;
1913 if (ulFlags
& CM_REENUMERATE_RETRY_INSTALLATION
)
1915 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
1918 RtlInitUnicodeString(&EnumerateDeviceData
.DeviceInstance
,
1920 EnumerateDeviceData
.Flags
= 0;
1922 Status
= NtPlugPlayControl(PlugPlayControlEnumerateDevice
,
1923 &EnumerateDeviceData
,
1924 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA
));
1925 if (!NT_SUCCESS(Status
))
1926 ret
= NtStatusToCrError(Status
);
1935 PNP_DeviceInstanceAction(
1939 LPWSTR pszDeviceInstance1
,
1940 LPWSTR pszDeviceInstance2
)
1942 CONFIGRET ret
= CR_SUCCESS
;
1944 UNREFERENCED_PARAMETER(hBinding
);
1946 DPRINT("PNP_DeviceInstanceAction() called\n");
1950 case PNP_DEVINST_MOVE
:
1951 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1952 pszDeviceInstance2
);
1955 case PNP_DEVINST_SETUP
:
1956 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1960 case PNP_DEVINST_ENABLE
:
1961 ret
= EnableDeviceInstance(pszDeviceInstance1
);
1964 case PNP_DEVINST_DISABLE
:
1965 ret
= DisableDeviceInstance(pszDeviceInstance1
);
1968 case PNP_DEVINST_REENUMERATE
:
1969 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
,
1974 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
1975 ret
= CR_CALL_NOT_IMPLEMENTED
;
1978 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
1987 PNP_GetDeviceStatus(
1994 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
1995 CONFIGRET ret
= CR_SUCCESS
;
1998 UNREFERENCED_PARAMETER(hBinding
);
1999 UNREFERENCED_PARAMETER(ulFlags
);
2001 DPRINT("PNP_GetDeviceStatus() called\n");
2003 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2005 PlugPlayData
.Operation
= 0; /* Get status */
2007 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2008 (PVOID
)&PlugPlayData
,
2009 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2010 if (NT_SUCCESS(Status
))
2012 *pulStatus
= PlugPlayData
.DeviceStatus
;
2013 *pulProblem
= PlugPlayData
.DeviceProblem
;
2017 ret
= NtStatusToCrError(Status
);
2020 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2029 PNP_SetDeviceProblem(
2036 return CR_CALL_NOT_IMPLEMENTED
;
2046 PPNP_VETO_TYPE pVetoType
,
2052 return CR_CALL_NOT_IMPLEMENTED
;
2058 PNP_UninstallDevInst(
2064 return CR_CALL_NOT_IMPLEMENTED
;
2069 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2075 lpPtr
= lpDeviceIdList
;
2078 dwLength
= wcslen(lpPtr
);
2079 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2082 lpPtr
+= (dwLength
+ 1);
2090 AppendDeviceId(LPWSTR lpDeviceIdList
,
2091 LPDWORD lpDeviceIdListSize
,
2097 dwLen
= wcslen(lpDeviceId
);
2098 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2100 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2102 dwPos
+= (dwLen
+ 1);
2104 lpDeviceIdList
[dwPos
] = 0;
2106 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2119 CONFIGRET ret
= CR_SUCCESS
;
2122 DWORD dwDeviceIdListSize
;
2123 DWORD dwNewDeviceIdSize
;
2124 WCHAR
* pszDeviceIdList
= NULL
;
2126 UNREFERENCED_PARAMETER(hBinding
);
2128 DPRINT("PNP_AddID() called\n");
2129 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2130 DPRINT(" DeviceId: %S\n", pszID
);
2131 DPRINT(" Flags: %lx\n", ulFlags
);
2133 if (RegOpenKeyExW(hEnumKey
,
2136 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2137 &hDeviceKey
) != ERROR_SUCCESS
)
2139 DPRINT("Failed to open the device key!\n");
2140 return CR_INVALID_DEVNODE
;
2143 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2145 if (RegQueryValueExW(hDeviceKey
,
2150 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2152 DPRINT("Failed to query the desired ID string!\n");
2153 ret
= CR_REGISTRY_ERROR
;
2157 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2158 if (!dwNewDeviceIdSize
)
2160 ret
= CR_INVALID_POINTER
;
2164 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2166 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2167 if (!pszDeviceIdList
)
2169 DPRINT("Failed to allocate memory for the desired ID string!\n");
2170 ret
= CR_OUT_OF_MEMORY
;
2174 if (RegQueryValueExW(hDeviceKey
,
2178 (LPBYTE
)pszDeviceIdList
,
2179 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2181 DPRINT("Failed to query the desired ID string!\n");
2182 ret
= CR_REGISTRY_ERROR
;
2186 /* Check whether the device ID is already in use */
2187 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2189 DPRINT("Device ID was found in the ID string!\n");
2194 /* Append the Device ID */
2195 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2197 if (RegSetValueExW(hDeviceKey
,
2201 (LPBYTE
)pszDeviceIdList
,
2202 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2204 DPRINT("Failed to set the desired ID string!\n");
2205 ret
= CR_REGISTRY_ERROR
;
2209 RegCloseKey(hDeviceKey
);
2210 if (pszDeviceIdList
)
2211 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2213 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2228 return CR_CALL_NOT_IMPLEMENTED
;
2238 PPNP_VETO_TYPE pVetoType
,
2244 return CR_CALL_NOT_IMPLEMENTED
;
2251 PNP_RequestDeviceEject(
2254 PPNP_VETO_TYPE pVetoType
,
2260 return CR_CALL_NOT_IMPLEMENTED
;
2267 PNP_IsDockStationPresent(
2275 CONFIGRET ret
= CR_SUCCESS
;
2277 UNREFERENCED_PARAMETER(hBinding
);
2279 DPRINT1("PNP_IsDockStationPresent() called\n");
2283 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2287 &hKey
) != ERROR_SUCCESS
)
2288 return CR_REGISTRY_ERROR
;
2290 dwSize
= sizeof(DWORD
);
2291 if (RegQueryValueExW(hKey
,
2296 &dwSize
) != ERROR_SUCCESS
)
2297 ret
= CR_REGISTRY_ERROR
;
2301 if (ret
== CR_SUCCESS
)
2303 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2305 ret
= CR_REGISTRY_ERROR
;
2307 else if (dwValue
!= 0)
2313 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2326 return CR_CALL_NOT_IMPLEMENTED
;
2339 PPNP_VETO_TYPE pVetoType
,
2344 CONFIGRET ret
= CR_SUCCESS
;
2345 WCHAR szKeyName
[MAX_PATH
];
2350 UNREFERENCED_PARAMETER(hBinding
);
2352 DPRINT("PNP_HwProfFlags() called\n");
2357 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2362 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2366 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2370 &hKey
) != ERROR_SUCCESS
)
2371 return CR_REGISTRY_ERROR
;
2373 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2375 if (RegOpenKeyExW(hKey
,
2379 &hDeviceKey
) != ERROR_SUCCESS
)
2385 dwSize
= sizeof(DWORD
);
2386 if (RegQueryValueExW(hDeviceKey
,
2391 &dwSize
) != ERROR_SUCCESS
)
2396 RegCloseKey(hDeviceKey
);
2399 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2401 /* FIXME: not implemented yet */
2402 ret
= CR_CALL_NOT_IMPLEMENTED
;
2417 HWPROFILEINFO
*pHWProfileInfo
,
2418 DWORD ulProfileInfoSize
,
2421 WCHAR szProfileName
[5];
2422 HKEY hKeyConfig
= NULL
;
2423 HKEY hKeyProfiles
= NULL
;
2424 HKEY hKeyProfile
= NULL
;
2425 DWORD dwDisposition
;
2428 CONFIGRET ret
= CR_SUCCESS
;
2430 UNREFERENCED_PARAMETER(hBinding
);
2432 DPRINT("PNP_GetHwProfInfo() called\n");
2434 if (ulProfileInfoSize
== 0)
2436 ret
= CR_INVALID_DATA
;
2442 ret
= CR_INVALID_FLAG
;
2446 /* Initialize the profile information */
2447 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2448 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2449 pHWProfileInfo
->HWPI_dwFlags
= 0;
2451 /* Open the 'IDConfigDB' key */
2452 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2453 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2456 REG_OPTION_NON_VOLATILE
,
2461 if (lError
!= ERROR_SUCCESS
)
2463 ret
= CR_REGISTRY_ERROR
;
2467 /* Open the 'Hardware Profiles' subkey */
2468 lError
= RegCreateKeyExW(hKeyConfig
,
2469 L
"Hardware Profiles",
2472 REG_OPTION_NON_VOLATILE
,
2473 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2477 if (lError
!= ERROR_SUCCESS
)
2479 ret
= CR_REGISTRY_ERROR
;
2483 if (ulIndex
== (ULONG
)-1)
2485 dwSize
= sizeof(ULONG
);
2486 lError
= RegQueryValueExW(hKeyConfig
,
2490 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2492 if (lError
!= ERROR_SUCCESS
)
2494 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2495 ret
= CR_REGISTRY_ERROR
;
2501 /* FIXME: not implemented yet */
2502 ret
= CR_CALL_NOT_IMPLEMENTED
;
2506 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2508 lError
= RegOpenKeyExW(hKeyProfiles
,
2513 if (lError
!= ERROR_SUCCESS
)
2515 ret
= CR_REGISTRY_ERROR
;
2519 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2520 lError
= RegQueryValueExW(hKeyProfile
,
2524 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2526 if (lError
!= ERROR_SUCCESS
)
2528 ret
= CR_REGISTRY_ERROR
;
2533 if (hKeyProfile
!= NULL
)
2534 RegCloseKey(hKeyProfile
);
2536 if (hKeyProfiles
!= NULL
)
2537 RegCloseKey(hKeyProfiles
);
2539 if (hKeyConfig
!= NULL
)
2540 RegCloseKey(hKeyConfig
);
2549 PNP_AddEmptyLogConf(
2553 DWORD
*pulLogConfTag
,
2557 return CR_CALL_NOT_IMPLEMENTED
;
2567 DWORD ulLogConfType
,
2572 return CR_CALL_NOT_IMPLEMENTED
;
2579 PNP_GetFirstLogConf(
2582 DWORD ulLogConfType
,
2583 DWORD
*pulLogConfTag
,
2587 return CR_CALL_NOT_IMPLEMENTED
;
2597 DWORD ulLogConfType
,
2603 return CR_CALL_NOT_IMPLEMENTED
;
2610 PNP_GetLogConfPriority(
2619 return CR_CALL_NOT_IMPLEMENTED
;
2630 DWORD ulLogConfType
,
2631 RESOURCEID ResourceID
,
2632 DWORD
*pulResourceTag
,
2634 PNP_RPC_BUFFER_SIZE ResourceLen
,
2638 return CR_CALL_NOT_IMPLEMENTED
;
2649 DWORD ulLogConfType
,
2650 RESOURCEID ResourceID
,
2651 DWORD ulResourceTag
,
2652 DWORD
*pulPreviousResType
,
2653 DWORD
*pulPreviousResTag
,
2657 return CR_CALL_NOT_IMPLEMENTED
;
2668 DWORD ulLogConfType
,
2669 RESOURCEID ResourceID
,
2670 DWORD ulResourceTag
,
2671 DWORD
*pulNextResType
,
2672 DWORD
*pulNextResTag
,
2676 return CR_CALL_NOT_IMPLEMENTED
;
2687 DWORD ulLogConfType
,
2688 RESOURCEID ResourceID
,
2689 DWORD ulResourceTag
,
2691 PNP_RPC_BUFFER_SIZE BufferLen
,
2695 return CR_CALL_NOT_IMPLEMENTED
;
2702 PNP_GetResDesDataSize(
2706 DWORD ulLogConfType
,
2707 RESOURCEID ResourceID
,
2708 DWORD ulResourceTag
,
2713 return CR_CALL_NOT_IMPLEMENTED
;
2724 DWORD ulLogConfType
,
2725 RESOURCEID CurrentResourceID
,
2726 RESOURCEID NewResourceID
,
2727 DWORD ulResourceTag
,
2729 PNP_RPC_BUFFER_SIZE ResourceLen
,
2733 return CR_CALL_NOT_IMPLEMENTED
;
2740 PNP_DetectResourceConflict(
2743 RESOURCEID ResourceID
,
2745 PNP_RPC_BUFFER_SIZE ResourceLen
,
2746 BOOL
*pbConflictDetected
,
2750 return CR_CALL_NOT_IMPLEMENTED
;
2757 PNP_QueryResConfList(
2760 RESOURCEID ResourceID
,
2762 PNP_RPC_BUFFER_SIZE ResourceLen
,
2764 PNP_RPC_BUFFER_SIZE BufferLen
,
2768 return CR_CALL_NOT_IMPLEMENTED
;
2777 DWORD ulHardwareProfile
,
2781 return CR_CALL_NOT_IMPLEMENTED
;
2788 PNP_QueryArbitratorFreeData(
2793 RESOURCEID ResourceID
,
2797 return CR_CALL_NOT_IMPLEMENTED
;
2804 PNP_QueryArbitratorFreeSize(
2808 RESOURCEID ResourceID
,
2812 return CR_CALL_NOT_IMPLEMENTED
;
2823 return CR_CALL_NOT_IMPLEMENTED
;
2830 PNP_RegisterNotification(
2836 PNOTIFY_DATA pNotifyData
;
2839 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
2840 hBinding
, ulFlags
, pulNotify
);
2843 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
2844 if (pNotifyData
== NULL
)
2845 return CR_OUT_OF_MEMORY
;
2847 *pulNotify
= (DWORD
)pNotifyData
;
2859 PNP_UnregisterNotification(
2863 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
2864 hBinding
, ulNotify
);
2868 return CR_CALL_NOT_IMPLEMENTED
;
2878 PNP_GetCustomDevProp(
2881 LPWSTR CustomPropName
,
2882 DWORD
*pulRegDataType
,
2884 PNP_RPC_STRING_LEN
*pulTransferLen
,
2885 PNP_RPC_STRING_LEN
*pulLength
,
2888 HKEY hDeviceKey
= NULL
;
2889 HKEY hParamKey
= NULL
;
2891 CONFIGRET ret
= CR_SUCCESS
;
2893 UNREFERENCED_PARAMETER(hBinding
);
2895 DPRINT("PNP_GetCustomDevProp() called\n");
2897 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2899 ret
= CR_INVALID_POINTER
;
2903 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2905 ret
= CR_INVALID_FLAG
;
2909 if (*pulLength
< *pulTransferLen
)
2910 *pulLength
= *pulTransferLen
;
2912 *pulTransferLen
= 0;
2914 lError
= RegOpenKeyExW(hEnumKey
,
2919 if (lError
!= ERROR_SUCCESS
)
2921 ret
= CR_REGISTRY_ERROR
;
2925 lError
= RegOpenKeyExW(hDeviceKey
,
2926 L
"Device Parameters",
2930 if (lError
!= ERROR_SUCCESS
)
2932 ret
= CR_REGISTRY_ERROR
;
2936 lError
= RegQueryValueExW(hParamKey
,
2942 if (lError
!= ERROR_SUCCESS
)
2944 if (lError
== ERROR_MORE_DATA
)
2946 ret
= CR_BUFFER_SMALL
;
2951 ret
= CR_NO_SUCH_VALUE
;
2956 if (ret
== CR_SUCCESS
)
2957 *pulTransferLen
= *pulLength
;
2959 if (hParamKey
!= NULL
)
2960 RegCloseKey(hParamKey
);
2962 if (hDeviceKey
!= NULL
)
2963 RegCloseKey(hDeviceKey
);
2965 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
2974 PNP_GetVersionInternal(
2978 UNREFERENCED_PARAMETER(hBinding
);
2988 PNP_GetBlockedDriverInfo(
2991 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
2992 PNP_RPC_BUFFER_SIZE
*pulLength
,
2996 return CR_CALL_NOT_IMPLEMENTED
;
3003 PNP_GetServerSideDeviceInstallFlags(
3005 DWORD
*pulSSDIFlags
,
3008 UNREFERENCED_PARAMETER(hBinding
);
3010 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
3011 hBinding
, pulSSDIFlags
, ulFlags
);
3013 if (pulSSDIFlags
== NULL
)
3014 return CR_INVALID_POINTER
;
3017 return CR_INVALID_FLAG
;
3029 PNP_GetObjectPropKeys(
3033 LPWSTR PropertyCultureName
,
3034 PNP_PROP_COUNT
*PropertyCount
,
3035 PNP_PROP_COUNT
*TransferLen
,
3036 DEVPROPKEY
*PropertyKeys
,
3040 return CR_CALL_NOT_IMPLEMENTED
;
3051 LPWSTR PropertyCultureName
,
3052 const DEVPROPKEY
*PropertyKey
,
3053 DEVPROPTYPE
*PropertyType
,
3054 PNP_PROP_SIZE
*PropertySize
,
3055 PNP_PROP_SIZE
*TransferLen
,
3056 BYTE
*PropertyBuffer
,
3060 return CR_CALL_NOT_IMPLEMENTED
;
3071 LPWSTR PropertyCultureName
,
3072 const DEVPROPKEY
*PropertyKey
,
3073 DEVPROPTYPE PropertyType
,
3074 PNP_PROP_SIZE PropertySize
,
3075 BYTE
*PropertyBuffer
,
3079 return CR_CALL_NOT_IMPLEMENTED
;
3090 return CR_CALL_NOT_IMPLEMENTED
;
3097 PNP_ApplyPowerSettings(
3101 return CR_CALL_NOT_IMPLEMENTED
;
3108 PNP_DriverStoreAddDriverPackage(
3112 return CR_CALL_NOT_IMPLEMENTED
;
3119 PNP_DriverStoreDeleteDriverPackage(
3123 return CR_CALL_NOT_IMPLEMENTED
;
3130 PNP_RegisterServiceNotification(
3134 return CR_CALL_NOT_IMPLEMENTED
;
3141 PNP_SetActiveService(
3147 return CR_CALL_NOT_IMPLEMENTED
;
3154 PNP_DeleteServiceDevices(
3158 return CR_CALL_NOT_IMPLEMENTED
;
3163 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3165 BOOL DeviceInstalled
= FALSE
;
3168 HANDLE hInstallEvent
;
3169 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3170 LPVOID Environment
= NULL
;
3171 PROCESS_INFORMATION ProcessInfo
;
3172 STARTUPINFOW StartupInfo
;
3176 /* The following lengths are constant (see below), they cannot overflow */
3177 WCHAR CommandLine
[116];
3178 WCHAR InstallEventName
[73];
3180 WCHAR UuidString
[39];
3182 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3184 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3186 if (RegOpenKeyExW(hEnumKey
,
3190 &DeviceKey
) == ERROR_SUCCESS
)
3192 if (RegQueryValueExW(DeviceKey
,
3197 NULL
) == ERROR_SUCCESS
)
3199 DPRINT("No need to install: %S\n", DeviceInstance
);
3200 RegCloseKey(DeviceKey
);
3204 BytesWritten
= sizeof(DWORD
);
3205 if (RegQueryValueExW(DeviceKey
,
3210 &BytesWritten
) == ERROR_SUCCESS
)
3212 if (Value
& CONFIGFLAG_FAILEDINSTALL
)
3214 DPRINT("No need to install: %S\n", DeviceInstance
);
3215 RegCloseKey(DeviceKey
);
3220 RegCloseKey(DeviceKey
);
3223 DPRINT1("Installing: %S\n", DeviceInstance
);
3225 /* Create a random UUID for the named pipe & event*/
3226 UuidCreate(&RandomUuid
);
3227 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3228 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3229 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3230 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3231 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3233 /* Create the event */
3234 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3235 wcscat(InstallEventName
, UuidString
);
3236 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3239 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3243 /* Create the named pipe */
3244 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3245 wcscat(PipeName
, UuidString
);
3246 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3247 if (hPipe
== INVALID_HANDLE_VALUE
)
3249 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3253 /* Launch rundll32 to call ClientSideInstallW */
3254 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3255 wcscat(CommandLine
, PipeName
);
3257 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3258 StartupInfo
.cb
= sizeof(StartupInfo
);
3262 /* newdev has to run under the environment of the current user */
3263 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3265 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3269 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3271 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3277 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3279 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3280 (ShowWizard is only set to FALSE for these two modes) */
3281 ASSERT(!ShowWizard
);
3283 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3285 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3290 /* Wait for the function to connect to our pipe */
3291 if (!ConnectNamedPipe(hPipe
, NULL
))
3293 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3295 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3300 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3301 Value
= sizeof(InstallEventName
);
3302 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3303 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3305 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3306 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3307 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3309 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3310 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3311 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3313 /* Wait for newdev.dll to finish processing */
3314 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3316 /* If the event got signalled, this is success */
3317 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3321 CloseHandle(hInstallEvent
);
3323 if (hPipe
!= INVALID_HANDLE_VALUE
)
3327 DestroyEnvironmentBlock(Environment
);
3329 if (ProcessInfo
.hProcess
)
3330 CloseHandle(ProcessInfo
.hProcess
);
3332 if (ProcessInfo
.hThread
)
3333 CloseHandle(ProcessInfo
.hThread
);
3335 if (!DeviceInstalled
)
3337 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3340 return DeviceInstalled
;
3356 return ERROR_INVALID_PARAMETER
;
3359 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3360 if (rc
!= ERROR_SUCCESS
)
3362 if (dwType
!= REG_SZ
)
3363 return ERROR_FILE_NOT_FOUND
;
3364 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3366 return ERROR_NOT_ENOUGH_MEMORY
;
3367 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3368 if (rc
!= ERROR_SUCCESS
)
3370 HeapFree(GetProcessHeap(), 0, Value
);
3373 /* NULL-terminate the string */
3374 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3377 return ERROR_SUCCESS
;
3385 DWORD regType
, active
, size
;
3389 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3390 if (rc
!= ERROR_SUCCESS
)
3393 size
= sizeof(DWORD
);
3394 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3395 if (rc
!= ERROR_SUCCESS
)
3397 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3400 ret
= (active
!= 0);
3406 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3415 HKEY ControlKey
= NULL
;
3416 LPWSTR SystemStartOptions
= NULL
;
3417 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3418 BOOL ConsoleBoot
= FALSE
;
3423 L
"SYSTEM\\CurrentControlSet\\Control",
3428 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3429 if (rc
!= ERROR_SUCCESS
)
3432 /* Check for CONSOLE switch in SystemStartOptions */
3433 CurrentOption
= SystemStartOptions
;
3434 while (CurrentOption
)
3436 NextOption
= wcschr(CurrentOption
, L
' ');
3438 *NextOption
= L
'\0';
3439 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3441 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3445 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3449 if (ControlKey
!= NULL
)
3450 RegCloseKey(ControlKey
);
3451 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3456 /* Loop to install all queued devices installations */
3458 DeviceInstallThread(LPVOID lpParameter
)
3460 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3461 PSLIST_ENTRY ListEntry
;
3463 PLIST_ENTRY ListEntry
;
3465 DeviceInstallParams
* Params
;
3468 UNREFERENCED_PARAMETER(lpParameter
);
3470 WaitForSingleObject(hInstallEvent
, INFINITE
);
3472 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3476 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3477 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3479 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3482 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3484 if (ListEntry
== NULL
)
3486 SetEvent(hNoPendingInstalls
);
3487 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3491 ResetEvent(hNoPendingInstalls
);
3492 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3493 InstallDevice(Params
->DeviceIds
, showWizard
);
3502 PnpEventThread(LPVOID lpParameter
)
3504 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3507 RPC_STATUS RpcStatus
;
3509 UNREFERENCED_PARAMETER(lpParameter
);
3511 PnpEventSize
= 0x1000;
3512 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3513 if (PnpEvent
== NULL
)
3514 return ERROR_OUTOFMEMORY
;
3518 DPRINT("Calling NtGetPlugPlayEvent()\n");
3520 /* Wait for the next pnp event */
3521 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3523 /* Resize the buffer for the PnP event if it's too small. */
3524 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3526 PnpEventSize
+= 0x400;
3527 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3528 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3529 if (PnpEvent
== NULL
)
3530 return ERROR_OUTOFMEMORY
;
3534 if (!NT_SUCCESS(Status
))
3536 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3540 /* Process the pnp event */
3541 DPRINT("Received PnP Event\n");
3542 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3544 DeviceInstallParams
* Params
;
3546 DWORD DeviceIdLength
;
3548 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3550 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3553 /* Queue device install (will be dequeued by DeviceInstallThread */
3554 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3555 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3558 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3559 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3560 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3562 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3564 SetEvent(hDeviceInstallListNotEmpty
);
3568 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3570 // DWORD dwRecipient;
3572 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3574 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3575 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3578 // DBT_DEVNODES_CHANGED,
3580 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3582 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3584 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3586 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3588 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3590 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3592 // DWORD dwRecipient;
3594 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3596 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3597 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3600 // DBT_DEVNODES_CHANGED,
3602 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3604 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3606 // DWORD dwRecipient;
3608 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3610 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3611 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3614 // DBT_DEVNODES_CHANGED,
3616 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3618 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3620 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3622 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3624 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3628 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3629 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3630 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3631 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3632 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3635 /* Dequeue the current pnp event and signal the next one */
3636 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3639 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3641 return ERROR_SUCCESS
;
3646 UpdateServiceStatus(DWORD dwState
)
3648 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3649 ServiceStatus
.dwCurrentState
= dwState
;
3650 ServiceStatus
.dwControlsAccepted
= 0;
3651 ServiceStatus
.dwWin32ExitCode
= 0;
3652 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3653 ServiceStatus
.dwCheckPoint
= 0;
3655 if (dwState
== SERVICE_START_PENDING
||
3656 dwState
== SERVICE_STOP_PENDING
||
3657 dwState
== SERVICE_PAUSE_PENDING
||
3658 dwState
== SERVICE_CONTINUE_PENDING
)
3659 ServiceStatus
.dwWaitHint
= 10000;
3661 ServiceStatus
.dwWaitHint
= 0;
3663 SetServiceStatus(ServiceStatusHandle
,
3669 ServiceControlHandler(DWORD dwControl
,
3674 DPRINT1("ServiceControlHandler() called\n");
3678 case SERVICE_CONTROL_STOP
:
3679 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3680 /* Stop listening to RPC Messages */
3681 RpcMgmtStopServerListening(NULL
);
3682 UpdateServiceStatus(SERVICE_STOPPED
);
3683 return ERROR_SUCCESS
;
3685 case SERVICE_CONTROL_PAUSE
:
3686 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3687 UpdateServiceStatus(SERVICE_PAUSED
);
3688 return ERROR_SUCCESS
;
3690 case SERVICE_CONTROL_CONTINUE
:
3691 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3692 UpdateServiceStatus(SERVICE_RUNNING
);
3693 return ERROR_SUCCESS
;
3695 case SERVICE_CONTROL_INTERROGATE
:
3696 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3697 SetServiceStatus(ServiceStatusHandle
,
3699 return ERROR_SUCCESS
;
3701 case SERVICE_CONTROL_SHUTDOWN
:
3702 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3703 /* Stop listening to RPC Messages */
3704 RpcMgmtStopServerListening(NULL
);
3705 UpdateServiceStatus(SERVICE_STOPPED
);
3706 return ERROR_SUCCESS
;
3709 DPRINT1(" Control %lu received\n", dwControl
);
3710 return ERROR_CALL_NOT_IMPLEMENTED
;
3716 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3721 UNREFERENCED_PARAMETER(argc
);
3722 UNREFERENCED_PARAMETER(argv
);
3724 DPRINT("ServiceMain() called\n");
3726 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3727 ServiceControlHandler
,
3729 if (!ServiceStatusHandle
)
3731 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3735 UpdateServiceStatus(SERVICE_START_PENDING
);
3737 hThread
= CreateThread(NULL
,
3743 if (hThread
!= NULL
)
3744 CloseHandle(hThread
);
3746 hThread
= CreateThread(NULL
,
3752 if (hThread
!= NULL
)
3753 CloseHandle(hThread
);
3755 hThread
= CreateThread(NULL
,
3757 DeviceInstallThread
,
3761 if (hThread
!= NULL
)
3762 CloseHandle(hThread
);
3764 UpdateServiceStatus(SERVICE_RUNNING
);
3766 DPRINT("ServiceMain() done\n");
3770 InitializePnPManager(VOID
)
3775 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3777 /* We need this privilege for using CreateProcessAsUserW */
3778 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3780 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3781 if (hInstallEvent
== NULL
)
3783 dwError
= GetLastError();
3784 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3788 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3789 if (hDeviceInstallListNotEmpty
== NULL
)
3791 dwError
= GetLastError();
3792 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3796 hNoPendingInstalls
= CreateEventW(NULL
,
3799 L
"Global\\PnP_No_Pending_Install_Events");
3800 if (hNoPendingInstalls
== NULL
)
3802 dwError
= GetLastError();
3803 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3807 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3808 InitializeSListHead(&DeviceInstallListHead
);
3810 InitializeListHead(&DeviceInstallListHead
);
3813 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3814 L
"System\\CurrentControlSet\\Enum",
3818 if (dwError
!= ERROR_SUCCESS
)
3820 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3824 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3825 L
"System\\CurrentControlSet\\Control\\Class",
3829 if (dwError
!= ERROR_SUCCESS
)
3831 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3835 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3841 DllMain(HINSTANCE hinstDLL
,
3847 case DLL_PROCESS_ATTACH
:
3848 DisableThreadLibraryCalls(hinstDLL
);
3849 InitializePnPManager();
3852 case DLL_PROCESS_DETACH
: