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
= PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME
;
932 case CM_DRP_UI_NUMBER
:
933 PlugPlayData
.Property
= PNP_PROPERTY_UI_NUMBER
;
936 case CM_DRP_BUSTYPEGUID
:
937 PlugPlayData
.Property
= PNP_PROPERTY_BUSTYPEGUID
;
940 case CM_DRP_LEGACYBUSTYPE
:
941 PlugPlayData
.Property
= PNP_PROPERTY_LEGACYBUSTYPE
;
944 case CM_DRP_BUSNUMBER
:
945 PlugPlayData
.Property
= PNP_PROPERTY_BUSNUMBER
;
948 case CM_DRP_ENUMERATOR_NAME
:
949 PlugPlayData
.Property
= PNP_PROPERTY_ENUMERATOR_NAME
;
953 PlugPlayData
.Property
= PNP_PROPERTY_ADDRESS
;
956 case CM_DRP_DEVICE_POWER_DATA
:
957 PlugPlayData
.Property
= PNP_PROPERTY_POWER_DATA
;
960 case CM_DRP_REMOVAL_POLICY
:
961 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY
;
964 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
965 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
;
968 case CM_DRP_INSTALL_STATE
:
969 PlugPlayData
.Property
= PNP_PROPERTY_INSTALL_STATE
;
972 #if (WINVER >= _WIN32_WINNT_WS03)
973 case CM_DRP_LOCATION_PATHS
:
974 PlugPlayData
.Property
= PNP_PROPERTY_LOCATION_PATHS
;
978 #if (WINVER >= _WIN32_WINNT_WIN7)
979 case CM_DRP_BASE_CONTAINERID
:
980 PlugPlayData
.Property
= PNP_PROPERTY_CONTAINERID
;
985 return CR_INVALID_PROPERTY
;
988 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
989 (PVOID
)&PlugPlayData
,
990 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
991 if (NT_SUCCESS(Status
))
993 *pulLength
= PlugPlayData
.BufferSize
;
997 ret
= NtStatusToCrError(Status
);
1004 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1009 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1018 PNP_SetDeviceRegProp(
1024 PNP_PROP_SIZE ulLength
,
1027 CONFIGRET ret
= CR_SUCCESS
;
1028 LPWSTR lpValueName
= NULL
;
1031 UNREFERENCED_PARAMETER(hBinding
);
1032 UNREFERENCED_PARAMETER(ulFlags
);
1034 DPRINT("PNP_SetDeviceRegProp() called\n");
1036 DPRINT("DeviceId: %S\n", pDeviceId
);
1037 DPRINT("Property: %lu\n", ulProperty
);
1038 DPRINT("DataType: %lu\n", ulDataType
);
1039 DPRINT("Length: %lu\n", ulLength
);
1043 case CM_DRP_DEVICEDESC
:
1044 lpValueName
= L
"DeviceDesc";
1047 case CM_DRP_HARDWAREID
:
1048 lpValueName
= L
"HardwareID";
1051 case CM_DRP_COMPATIBLEIDS
:
1052 lpValueName
= L
"CompatibleIDs";
1055 case CM_DRP_SERVICE
:
1056 lpValueName
= L
"Service";
1060 lpValueName
= L
"Class";
1063 case CM_DRP_CLASSGUID
:
1064 lpValueName
= L
"ClassGUID";
1068 lpValueName
= L
"Driver";
1071 case CM_DRP_CONFIGFLAGS
:
1072 lpValueName
= L
"ConfigFlags";
1076 lpValueName
= L
"Mfg";
1079 case CM_DRP_FRIENDLYNAME
:
1080 lpValueName
= L
"FriendlyName";
1083 case CM_DRP_LOCATION_INFORMATION
:
1084 lpValueName
= L
"LocationInformation";
1087 case CM_DRP_UPPERFILTERS
:
1088 lpValueName
= L
"UpperFilters";
1091 case CM_DRP_LOWERFILTERS
:
1092 lpValueName
= L
"LowerFilters";
1095 case CM_DRP_SECURITY
:
1096 lpValueName
= L
"Security";
1099 case CM_DRP_DEVTYPE
:
1100 lpValueName
= L
"DeviceType";
1103 case CM_DRP_EXCLUSIVE
:
1104 lpValueName
= L
"Exclusive";
1107 case CM_DRP_CHARACTERISTICS
:
1108 lpValueName
= L
"DeviceCharacteristics";
1111 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1112 lpValueName
= L
"UINumberDescFormat";
1115 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1116 lpValueName
= L
"RemovalPolicy";
1120 return CR_INVALID_PROPERTY
;
1123 DPRINT("Value name: %S\n", lpValueName
);
1125 if (RegOpenKeyExW(hEnumKey
,
1130 return CR_INVALID_DEVNODE
;
1134 if (RegDeleteValueW(hKey
,
1136 ret
= CR_REGISTRY_ERROR
;
1140 if (RegSetValueExW(hKey
,
1146 ret
= CR_REGISTRY_ERROR
;
1151 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1160 PNP_GetClassInstance(
1163 LPWSTR pszClassInstance
,
1164 PNP_RPC_STRING_LEN ulLength
)
1167 return CR_CALL_NOT_IMPLEMENTED
;
1182 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1191 return CR_REGISTRY_ERROR
;
1193 /* FIXME: Set security key */
1204 PNP_DeleteRegistryKey(
1207 LPWSTR pszParentKey
,
1212 return CR_CALL_NOT_IMPLEMENTED
;
1221 DWORD
*pulClassCount
,
1227 UNREFERENCED_PARAMETER(hBinding
);
1228 UNREFERENCED_PARAMETER(ulFlags
);
1230 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1235 if (dwError
!= ERROR_SUCCESS
)
1236 return CR_INVALID_DATA
;
1238 dwError
= RegQueryInfoKeyW(hKey
,
1251 if (dwError
!= ERROR_SUCCESS
)
1252 return CR_INVALID_DATA
;
1263 LPWSTR pszClassGuid
,
1265 PNP_RPC_STRING_LEN
*pulLength
,
1268 WCHAR szKeyName
[MAX_PATH
];
1269 CONFIGRET ret
= CR_SUCCESS
;
1273 UNREFERENCED_PARAMETER(hBinding
);
1274 UNREFERENCED_PARAMETER(ulFlags
);
1276 DPRINT("PNP_GetClassName() called\n");
1278 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1279 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1280 lstrcatW(szKeyName
, pszClassGuid
);
1282 return CR_INVALID_DATA
;
1284 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1289 return CR_REGISTRY_ERROR
;
1291 dwSize
= *pulLength
* sizeof(WCHAR
);
1292 if (RegQueryValueExW(hKey
,
1300 ret
= CR_REGISTRY_ERROR
;
1304 *pulLength
= dwSize
/ sizeof(WCHAR
);
1309 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1320 LPWSTR pszClassGuid
,
1323 CONFIGRET ret
= CR_SUCCESS
;
1325 UNREFERENCED_PARAMETER(hBinding
);
1327 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1329 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1331 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1332 ret
= CR_REGISTRY_ERROR
;
1336 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1337 ret
= CR_REGISTRY_ERROR
;
1340 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1349 PNP_GetInterfaceDeviceAlias(
1351 LPWSTR pszInterfaceDevice
,
1352 GUID
*AliasInterfaceGuid
,
1353 LPWSTR pszAliasInterfaceDevice
,
1354 PNP_RPC_STRING_LEN
*pulLength
,
1355 PNP_RPC_STRING_LEN
*pulTransferLen
,
1359 return CR_CALL_NOT_IMPLEMENTED
;
1366 PNP_GetInterfaceDeviceList(
1368 GUID
*InterfaceGuid
,
1371 PNP_RPC_BUFFER_SIZE
*pulLength
,
1375 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1376 DWORD ret
= CR_SUCCESS
;
1378 UNREFERENCED_PARAMETER(hBinding
);
1380 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1383 PlugPlayData
.Flags
= ulFlags
;
1384 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1385 PlugPlayData
.Buffer
= Buffer
;
1386 PlugPlayData
.BufferSize
= *pulLength
;
1388 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1389 (PVOID
)&PlugPlayData
,
1390 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1391 if (NT_SUCCESS(Status
))
1393 *pulLength
= PlugPlayData
.BufferSize
;
1397 ret
= NtStatusToCrError(Status
);
1400 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1408 PNP_GetInterfaceDeviceListSize(
1410 PNP_RPC_BUFFER_SIZE
*pulLen
,
1411 GUID
*InterfaceGuid
,
1416 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1417 DWORD ret
= CR_SUCCESS
;
1419 UNREFERENCED_PARAMETER(hBinding
);
1421 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1423 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1426 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1427 PlugPlayData
.Buffer
= NULL
;
1428 PlugPlayData
.BufferSize
= 0;
1429 PlugPlayData
.Flags
= ulFlags
;
1431 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1432 (PVOID
)&PlugPlayData
,
1433 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1434 if (NT_SUCCESS(Status
))
1436 *pulLen
= PlugPlayData
.BufferSize
;
1440 ret
= NtStatusToCrError(Status
);
1443 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1451 PNP_RegisterDeviceClassAssociation(
1454 GUID
*InterfaceGuid
,
1455 LPWSTR pszReference
,
1457 PNP_RPC_STRING_LEN
*pulLength
,
1458 PNP_RPC_STRING_LEN
*pulTransferLen
,
1462 return CR_CALL_NOT_IMPLEMENTED
;
1469 PNP_UnregisterDeviceClassAssociation(
1471 LPWSTR pszInterfaceDevice
,
1475 return CR_CALL_NOT_IMPLEMENTED
;
1482 PNP_GetClassRegProp(
1484 LPWSTR pszClassGuid
,
1486 DWORD
*pulRegDataType
,
1488 PNP_RPC_STRING_LEN
*pulTransferLen
,
1489 PNP_RPC_STRING_LEN
*pulLength
,
1492 CONFIGRET ret
= CR_SUCCESS
;
1493 LPWSTR lpValueName
= NULL
;
1494 HKEY hInstKey
= NULL
;
1495 HKEY hPropKey
= NULL
;
1498 UNREFERENCED_PARAMETER(hBinding
);
1500 DPRINT("PNP_GetClassRegProp() called\n");
1502 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1504 ret
= CR_INVALID_POINTER
;
1510 ret
= CR_INVALID_FLAG
;
1514 if (*pulLength
< *pulTransferLen
)
1515 *pulLength
= *pulTransferLen
;
1517 *pulTransferLen
= 0;
1521 case CM_CRP_SECURITY
:
1522 lpValueName
= L
"Security";
1525 case CM_CRP_DEVTYPE
:
1526 lpValueName
= L
"DeviceType";
1529 case CM_CRP_EXCLUSIVE
:
1530 lpValueName
= L
"Exclusive";
1533 case CM_CRP_CHARACTERISTICS
:
1534 lpValueName
= L
"DeviceCharacteristics";
1538 ret
= CR_INVALID_PROPERTY
;
1542 DPRINT("Value name: %S\n", lpValueName
);
1544 lError
= RegOpenKeyExW(hClassKey
,
1549 if (lError
!= ERROR_SUCCESS
)
1552 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1556 lError
= RegOpenKeyExW(hInstKey
,
1561 if (lError
!= ERROR_SUCCESS
)
1564 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1568 lError
= RegQueryValueExW(hPropKey
,
1574 if (lError
!= ERROR_SUCCESS
)
1576 if (lError
== ERROR_MORE_DATA
)
1578 ret
= CR_BUFFER_SMALL
;
1583 ret
= CR_NO_SUCH_VALUE
;
1588 if (ret
== CR_SUCCESS
)
1589 *pulTransferLen
= *pulLength
;
1591 if (hPropKey
!= NULL
)
1592 RegCloseKey(hPropKey
);
1594 if (hInstKey
!= NULL
)
1595 RegCloseKey(hInstKey
);
1597 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1606 PNP_SetClassRegProp(
1608 LPWSTR pszClassGuid
,
1612 PNP_PROP_SIZE ulLength
,
1615 CONFIGRET ret
= CR_SUCCESS
;
1616 LPWSTR lpValueName
= NULL
;
1621 UNREFERENCED_PARAMETER(hBinding
);
1623 DPRINT("PNP_SetClassRegProp() called\n");
1626 return CR_INVALID_FLAG
;
1630 case CM_CRP_SECURITY
:
1631 lpValueName
= L
"Security";
1634 case CM_CRP_DEVTYPE
:
1635 lpValueName
= L
"DeviceType";
1638 case CM_CRP_EXCLUSIVE
:
1639 lpValueName
= L
"Exclusive";
1642 case CM_CRP_CHARACTERISTICS
:
1643 lpValueName
= L
"DeviceCharacteristics";
1647 return CR_INVALID_PROPERTY
;
1650 lError
= RegOpenKeyExW(hClassKey
,
1655 if (lError
!= ERROR_SUCCESS
)
1657 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1661 /* FIXME: Set security descriptor */
1662 lError
= RegCreateKeyExW(hInstKey
,
1666 REG_OPTION_NON_VOLATILE
,
1671 if (lError
!= ERROR_SUCCESS
)
1673 ret
= CR_REGISTRY_ERROR
;
1679 if (RegDeleteValueW(hPropKey
,
1681 ret
= CR_REGISTRY_ERROR
;
1685 if (RegSetValueExW(hPropKey
,
1691 ret
= CR_REGISTRY_ERROR
;
1695 if (hPropKey
!= NULL
)
1696 RegCloseKey(hPropKey
);
1698 if (hInstKey
!= NULL
)
1699 RegCloseKey(hInstKey
);
1706 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
1707 OUT LPWSTR pszEnumerator
,
1708 OUT LPWSTR pszDevice
,
1709 OUT LPWSTR pszInstance
)
1711 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
1712 LPWSTR lpEnumerator
= NULL
;
1713 LPWSTR lpDevice
= NULL
;
1714 LPWSTR lpInstance
= NULL
;
1717 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
1723 lpEnumerator
= szLocalDeviceInstanceID
;
1725 ptr
= wcschr(lpEnumerator
, L
'\\');
1731 ptr
= wcschr(lpDevice
, L
'\\');
1739 if (lpEnumerator
!= NULL
)
1740 wcscpy(pszEnumerator
, lpEnumerator
);
1742 if (lpDevice
!= NULL
)
1743 wcscpy(pszDevice
, lpDevice
);
1745 if (lpInstance
!= NULL
)
1746 wcscpy(pszInstance
, lpInstance
);
1751 CreateDeviceInstance(LPWSTR pszDeviceID
)
1753 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1754 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1755 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1756 HKEY hKeyEnumerator
;
1762 /* Split the instance ID */
1763 SplitDeviceInstanceID(pszDeviceID
,
1768 /* Open or create the enumerator key */
1769 lError
= RegCreateKeyExW(hEnumKey
,
1773 REG_OPTION_NON_VOLATILE
,
1778 if (lError
!= ERROR_SUCCESS
)
1780 return CR_REGISTRY_ERROR
;
1783 /* Open or create the device key */
1784 lError
= RegCreateKeyExW(hKeyEnumerator
,
1788 REG_OPTION_NON_VOLATILE
,
1794 /* Close the enumerator key */
1795 RegCloseKey(hKeyEnumerator
);
1797 if (lError
!= ERROR_SUCCESS
)
1799 return CR_REGISTRY_ERROR
;
1802 /* Try to open the instance key and fail if it exists */
1803 lError
= RegOpenKeyExW(hKeyDevice
,
1808 if (lError
== ERROR_SUCCESS
)
1810 DPRINT1("Instance %S already exists!\n", szInstance
);
1811 RegCloseKey(hKeyInstance
);
1812 RegCloseKey(hKeyDevice
);
1813 return CR_ALREADY_SUCH_DEVINST
;
1816 /* Create a new instance key */
1817 lError
= RegCreateKeyExW(hKeyDevice
,
1821 REG_OPTION_NON_VOLATILE
,
1827 /* Close the device key */
1828 RegCloseKey(hKeyDevice
);
1830 if (lError
!= ERROR_SUCCESS
)
1832 return CR_REGISTRY_ERROR
;
1835 /* Create the 'Control' sub key */
1836 lError
= RegCreateKeyExW(hKeyInstance
,
1840 REG_OPTION_NON_VOLATILE
,
1845 if (lError
== ERROR_SUCCESS
)
1847 RegCloseKey(hKeyControl
);
1850 RegCloseKey(hKeyInstance
);
1852 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1862 LPWSTR pszParentDeviceID
,
1863 PNP_RPC_STRING_LEN ulLength
,
1866 CONFIGRET ret
= CR_SUCCESS
;
1868 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1870 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1872 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1873 DWORD dwInstanceNumber
;
1875 /* Generated ID is: Root\<Device ID>\<Instance number> */
1876 dwInstanceNumber
= 0;
1879 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1880 pszDeviceID
, dwInstanceNumber
);
1882 /* Try to create a device instance with this ID */
1883 ret
= CreateDeviceInstance(szGeneratedInstance
);
1887 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1889 if (ret
== CR_SUCCESS
)
1891 /* pszDeviceID is an out parameter too for generated IDs */
1892 if (wcslen(szGeneratedInstance
) > ulLength
)
1894 ret
= CR_BUFFER_SMALL
;
1898 wcscpy(pszDeviceID
, szGeneratedInstance
);
1904 /* Create the device instance */
1905 ret
= CreateDeviceInstance(pszDeviceID
);
1908 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
1915 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
1916 LPWSTR pszDeviceInstanceSource
)
1918 DPRINT("MoveDeviceInstance: not implemented\n");
1920 return CR_CALL_NOT_IMPLEMENTED
;
1925 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
1928 DPRINT("SetupDeviceInstance: not implemented\n");
1930 return CR_CALL_NOT_IMPLEMENTED
;
1935 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
1937 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
1938 CONFIGRET ret
= CR_SUCCESS
;
1941 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
1943 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
1944 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
1945 if (!NT_SUCCESS(Status
))
1946 ret
= NtStatusToCrError(Status
);
1953 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
1955 DPRINT("DisableDeviceInstance: not implemented\n");
1957 return CR_CALL_NOT_IMPLEMENTED
;
1962 ReenumerateDeviceInstance(LPWSTR pszDeviceInstance
)
1964 DPRINT("ReenumerateDeviceInstance: not implemented\n");
1966 return CR_CALL_NOT_IMPLEMENTED
;
1973 PNP_DeviceInstanceAction(
1977 LPWSTR pszDeviceInstance1
,
1978 LPWSTR pszDeviceInstance2
)
1980 CONFIGRET ret
= CR_SUCCESS
;
1982 UNREFERENCED_PARAMETER(hBinding
);
1984 DPRINT("PNP_DeviceInstanceAction() called\n");
1988 case PNP_DEVINST_MOVE
:
1989 ret
= MoveDeviceInstance(pszDeviceInstance1
,
1990 pszDeviceInstance2
);
1993 case PNP_DEVINST_SETUP
:
1994 ret
= SetupDeviceInstance(pszDeviceInstance1
,
1998 case PNP_DEVINST_ENABLE
:
1999 ret
= EnableDeviceInstance(pszDeviceInstance1
);
2002 case PNP_DEVINST_DISABLE
:
2003 ret
= DisableDeviceInstance(pszDeviceInstance1
);
2006 case PNP_DEVINST_REENUMERATE
:
2007 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
);
2011 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2012 ret
= CR_CALL_NOT_IMPLEMENTED
;
2015 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2024 PNP_GetDeviceStatus(
2031 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
2032 CONFIGRET ret
= CR_SUCCESS
;
2035 UNREFERENCED_PARAMETER(hBinding
);
2036 UNREFERENCED_PARAMETER(ulFlags
);
2038 DPRINT("PNP_GetDeviceStatus() called\n");
2040 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2042 PlugPlayData
.Operation
= 0; /* Get status */
2044 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2045 (PVOID
)&PlugPlayData
,
2046 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2047 if (NT_SUCCESS(Status
))
2049 *pulStatus
= PlugPlayData
.DeviceStatus
;
2050 *pulProblem
= PlugPlayData
.DeviceProblem
;
2054 ret
= NtStatusToCrError(Status
);
2057 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2066 PNP_SetDeviceProblem(
2073 return CR_CALL_NOT_IMPLEMENTED
;
2083 PPNP_VETO_TYPE pVetoType
,
2089 return CR_CALL_NOT_IMPLEMENTED
;
2095 PNP_UninstallDevInst(
2101 return CR_CALL_NOT_IMPLEMENTED
;
2106 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2112 lpPtr
= lpDeviceIdList
;
2115 dwLength
= wcslen(lpPtr
);
2116 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2119 lpPtr
+= (dwLength
+ 1);
2127 AppendDeviceId(LPWSTR lpDeviceIdList
,
2128 LPDWORD lpDeviceIdListSize
,
2134 dwLen
= wcslen(lpDeviceId
);
2135 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2137 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2139 dwPos
+= (dwLen
+ 1);
2141 lpDeviceIdList
[dwPos
] = 0;
2143 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2156 CONFIGRET ret
= CR_SUCCESS
;
2159 DWORD dwDeviceIdListSize
;
2160 DWORD dwNewDeviceIdSize
;
2161 WCHAR
* pszDeviceIdList
= NULL
;
2163 UNREFERENCED_PARAMETER(hBinding
);
2165 DPRINT("PNP_AddID() called\n");
2166 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2167 DPRINT(" DeviceId: %S\n", pszID
);
2168 DPRINT(" Flags: %lx\n", ulFlags
);
2170 if (RegOpenKeyExW(hEnumKey
,
2173 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2174 &hDeviceKey
) != ERROR_SUCCESS
)
2176 DPRINT("Failed to open the device key!\n");
2177 return CR_INVALID_DEVNODE
;
2180 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2182 if (RegQueryValueExW(hDeviceKey
,
2187 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2189 DPRINT("Failed to query the desired ID string!\n");
2190 ret
= CR_REGISTRY_ERROR
;
2194 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2195 if (!dwNewDeviceIdSize
)
2197 ret
= CR_INVALID_POINTER
;
2201 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2203 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2204 if (!pszDeviceIdList
)
2206 DPRINT("Failed to allocate memory for the desired ID string!\n");
2207 ret
= CR_OUT_OF_MEMORY
;
2211 if (RegQueryValueExW(hDeviceKey
,
2215 (LPBYTE
)pszDeviceIdList
,
2216 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2218 DPRINT("Failed to query the desired ID string!\n");
2219 ret
= CR_REGISTRY_ERROR
;
2223 /* Check whether the device ID is already in use */
2224 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2226 DPRINT("Device ID was found in the ID string!\n");
2231 /* Append the Device ID */
2232 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2234 if (RegSetValueExW(hDeviceKey
,
2238 (LPBYTE
)pszDeviceIdList
,
2239 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2241 DPRINT("Failed to set the desired ID string!\n");
2242 ret
= CR_REGISTRY_ERROR
;
2246 RegCloseKey(hDeviceKey
);
2247 if (pszDeviceIdList
)
2248 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2250 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2265 return CR_CALL_NOT_IMPLEMENTED
;
2275 PPNP_VETO_TYPE pVetoType
,
2281 return CR_CALL_NOT_IMPLEMENTED
;
2288 PNP_RequestDeviceEject(
2291 PPNP_VETO_TYPE pVetoType
,
2297 return CR_CALL_NOT_IMPLEMENTED
;
2304 PNP_IsDockStationPresent(
2312 CONFIGRET ret
= CR_SUCCESS
;
2314 UNREFERENCED_PARAMETER(hBinding
);
2316 DPRINT1("PNP_IsDockStationPresent() called\n");
2320 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2324 &hKey
) != ERROR_SUCCESS
)
2325 return CR_REGISTRY_ERROR
;
2327 dwSize
= sizeof(DWORD
);
2328 if (RegQueryValueExW(hKey
,
2333 &dwSize
) != ERROR_SUCCESS
)
2334 ret
= CR_REGISTRY_ERROR
;
2338 if (ret
== CR_SUCCESS
)
2340 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2342 ret
= CR_REGISTRY_ERROR
;
2344 else if (dwValue
!= 0)
2350 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2363 return CR_CALL_NOT_IMPLEMENTED
;
2376 PPNP_VETO_TYPE pVetoType
,
2381 CONFIGRET ret
= CR_SUCCESS
;
2382 WCHAR szKeyName
[MAX_PATH
];
2387 UNREFERENCED_PARAMETER(hBinding
);
2389 DPRINT("PNP_HwProfFlags() called\n");
2394 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2399 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2403 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2407 &hKey
) != ERROR_SUCCESS
)
2408 return CR_REGISTRY_ERROR
;
2410 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2412 if (RegOpenKeyExW(hKey
,
2416 &hDeviceKey
) != ERROR_SUCCESS
)
2422 dwSize
= sizeof(DWORD
);
2423 if (RegQueryValueExW(hDeviceKey
,
2428 &dwSize
) != ERROR_SUCCESS
)
2433 RegCloseKey(hDeviceKey
);
2436 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2438 /* FIXME: not implemented yet */
2439 ret
= CR_CALL_NOT_IMPLEMENTED
;
2454 HWPROFILEINFO
*pHWProfileInfo
,
2455 DWORD ulProfileInfoSize
,
2458 WCHAR szProfileName
[5];
2459 HKEY hKeyConfig
= NULL
;
2460 HKEY hKeyProfiles
= NULL
;
2461 HKEY hKeyProfile
= NULL
;
2462 DWORD dwDisposition
;
2465 CONFIGRET ret
= CR_SUCCESS
;
2467 UNREFERENCED_PARAMETER(hBinding
);
2469 DPRINT("PNP_GetHwProfInfo() called\n");
2471 if (ulProfileInfoSize
== 0)
2473 ret
= CR_INVALID_DATA
;
2479 ret
= CR_INVALID_FLAG
;
2483 /* Initialize the profile information */
2484 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2485 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2486 pHWProfileInfo
->HWPI_dwFlags
= 0;
2488 /* Open the 'IDConfigDB' key */
2489 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2490 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2493 REG_OPTION_NON_VOLATILE
,
2498 if (lError
!= ERROR_SUCCESS
)
2500 ret
= CR_REGISTRY_ERROR
;
2504 /* Open the 'Hardware Profiles' subkey */
2505 lError
= RegCreateKeyExW(hKeyConfig
,
2506 L
"Hardware Profiles",
2509 REG_OPTION_NON_VOLATILE
,
2510 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2514 if (lError
!= ERROR_SUCCESS
)
2516 ret
= CR_REGISTRY_ERROR
;
2520 if (ulIndex
== (ULONG
)-1)
2522 dwSize
= sizeof(ULONG
);
2523 lError
= RegQueryValueExW(hKeyConfig
,
2527 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2529 if (lError
!= ERROR_SUCCESS
)
2531 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2532 ret
= CR_REGISTRY_ERROR
;
2538 /* FIXME: not implemented yet */
2539 ret
= CR_CALL_NOT_IMPLEMENTED
;
2543 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2545 lError
= RegOpenKeyExW(hKeyProfiles
,
2550 if (lError
!= ERROR_SUCCESS
)
2552 ret
= CR_REGISTRY_ERROR
;
2556 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2557 lError
= RegQueryValueExW(hKeyProfile
,
2561 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2563 if (lError
!= ERROR_SUCCESS
)
2565 ret
= CR_REGISTRY_ERROR
;
2570 if (hKeyProfile
!= NULL
)
2571 RegCloseKey(hKeyProfile
);
2573 if (hKeyProfiles
!= NULL
)
2574 RegCloseKey(hKeyProfiles
);
2576 if (hKeyConfig
!= NULL
)
2577 RegCloseKey(hKeyConfig
);
2586 PNP_AddEmptyLogConf(
2590 DWORD
*pulLogConfTag
,
2594 return CR_CALL_NOT_IMPLEMENTED
;
2604 DWORD ulLogConfType
,
2609 return CR_CALL_NOT_IMPLEMENTED
;
2616 PNP_GetFirstLogConf(
2619 DWORD ulLogConfType
,
2620 DWORD
*pulLogConfTag
,
2624 return CR_CALL_NOT_IMPLEMENTED
;
2634 DWORD ulLogConfType
,
2640 return CR_CALL_NOT_IMPLEMENTED
;
2647 PNP_GetLogConfPriority(
2656 return CR_CALL_NOT_IMPLEMENTED
;
2667 DWORD ulLogConfType
,
2668 RESOURCEID ResourceID
,
2669 DWORD
*pulResourceTag
,
2671 PNP_RPC_BUFFER_SIZE ResourceLen
,
2675 return CR_CALL_NOT_IMPLEMENTED
;
2686 DWORD ulLogConfType
,
2687 RESOURCEID ResourceID
,
2688 DWORD ulResourceTag
,
2689 DWORD
*pulPreviousResType
,
2690 DWORD
*pulPreviousResTag
,
2694 return CR_CALL_NOT_IMPLEMENTED
;
2705 DWORD ulLogConfType
,
2706 RESOURCEID ResourceID
,
2707 DWORD ulResourceTag
,
2708 DWORD
*pulNextResType
,
2709 DWORD
*pulNextResTag
,
2713 return CR_CALL_NOT_IMPLEMENTED
;
2724 DWORD ulLogConfType
,
2725 RESOURCEID ResourceID
,
2726 DWORD ulResourceTag
,
2728 PNP_RPC_BUFFER_SIZE BufferLen
,
2732 return CR_CALL_NOT_IMPLEMENTED
;
2739 PNP_GetResDesDataSize(
2743 DWORD ulLogConfType
,
2744 RESOURCEID ResourceID
,
2745 DWORD ulResourceTag
,
2750 return CR_CALL_NOT_IMPLEMENTED
;
2761 DWORD ulLogConfType
,
2762 RESOURCEID CurrentResourceID
,
2763 RESOURCEID NewResourceID
,
2764 DWORD ulResourceTag
,
2766 PNP_RPC_BUFFER_SIZE ResourceLen
,
2770 return CR_CALL_NOT_IMPLEMENTED
;
2777 PNP_DetectResourceConflict(
2780 RESOURCEID ResourceID
,
2782 PNP_RPC_BUFFER_SIZE ResourceLen
,
2783 BOOL
*pbConflictDetected
,
2787 return CR_CALL_NOT_IMPLEMENTED
;
2794 PNP_QueryResConfList(
2797 RESOURCEID ResourceID
,
2799 PNP_RPC_BUFFER_SIZE ResourceLen
,
2801 PNP_RPC_BUFFER_SIZE BufferLen
,
2805 return CR_CALL_NOT_IMPLEMENTED
;
2814 DWORD ulHardwareProfile
,
2818 return CR_CALL_NOT_IMPLEMENTED
;
2825 PNP_QueryArbitratorFreeData(
2830 RESOURCEID ResourceID
,
2834 return CR_CALL_NOT_IMPLEMENTED
;
2841 PNP_QueryArbitratorFreeSize(
2845 RESOURCEID ResourceID
,
2849 return CR_CALL_NOT_IMPLEMENTED
;
2860 return CR_CALL_NOT_IMPLEMENTED
;
2867 PNP_RegisterNotification(
2873 PNOTIFY_DATA pNotifyData
;
2876 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
2877 hBinding
, ulFlags
, pulNotify
);
2880 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
2881 if (pNotifyData
== NULL
)
2882 return CR_OUT_OF_MEMORY
;
2884 *pulNotify
= (DWORD
)pNotifyData
;
2896 PNP_UnregisterNotification(
2900 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
2901 hBinding
, ulNotify
);
2905 return CR_CALL_NOT_IMPLEMENTED
;
2915 PNP_GetCustomDevProp(
2918 LPWSTR CustomPropName
,
2919 DWORD
*pulRegDataType
,
2921 PNP_RPC_STRING_LEN
*pulTransferLen
,
2922 PNP_RPC_STRING_LEN
*pulLength
,
2925 HKEY hDeviceKey
= NULL
;
2926 HKEY hParamKey
= NULL
;
2928 CONFIGRET ret
= CR_SUCCESS
;
2930 UNREFERENCED_PARAMETER(hBinding
);
2932 DPRINT("PNP_GetCustomDevProp() called\n");
2934 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
2936 ret
= CR_INVALID_POINTER
;
2940 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
2942 ret
= CR_INVALID_FLAG
;
2946 if (*pulLength
< *pulTransferLen
)
2947 *pulLength
= *pulTransferLen
;
2949 *pulTransferLen
= 0;
2951 lError
= RegOpenKeyExW(hEnumKey
,
2956 if (lError
!= ERROR_SUCCESS
)
2958 ret
= CR_REGISTRY_ERROR
;
2962 lError
= RegOpenKeyExW(hDeviceKey
,
2963 L
"Device Parameters",
2967 if (lError
!= ERROR_SUCCESS
)
2969 ret
= CR_REGISTRY_ERROR
;
2973 lError
= RegQueryValueExW(hParamKey
,
2979 if (lError
!= ERROR_SUCCESS
)
2981 if (lError
== ERROR_MORE_DATA
)
2983 ret
= CR_BUFFER_SMALL
;
2988 ret
= CR_NO_SUCH_VALUE
;
2993 if (ret
== CR_SUCCESS
)
2994 *pulTransferLen
= *pulLength
;
2996 if (hParamKey
!= NULL
)
2997 RegCloseKey(hParamKey
);
2999 if (hDeviceKey
!= NULL
)
3000 RegCloseKey(hDeviceKey
);
3002 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3011 PNP_GetVersionInternal(
3015 UNREFERENCED_PARAMETER(hBinding
);
3025 PNP_GetBlockedDriverInfo(
3028 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3029 PNP_RPC_BUFFER_SIZE
*pulLength
,
3033 return CR_CALL_NOT_IMPLEMENTED
;
3040 PNP_GetServerSideDeviceInstallFlags(
3042 DWORD
*pulSSDIFlags
,
3045 UNREFERENCED_PARAMETER(hBinding
);
3047 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
3048 hBinding
, pulSSDIFlags
, ulFlags
);
3050 if (pulSSDIFlags
== NULL
)
3051 return CR_INVALID_POINTER
;
3054 return CR_INVALID_FLAG
;
3066 PNP_GetObjectPropKeys(
3070 LPWSTR PropertyCultureName
,
3071 PNP_PROP_COUNT
*PropertyCount
,
3072 PNP_PROP_COUNT
*TransferLen
,
3073 DEVPROPKEY
*PropertyKeys
,
3077 return CR_CALL_NOT_IMPLEMENTED
;
3088 LPWSTR PropertyCultureName
,
3089 const DEVPROPKEY
*PropertyKey
,
3090 DEVPROPTYPE
*PropertyType
,
3091 PNP_PROP_SIZE
*PropertySize
,
3092 PNP_PROP_SIZE
*TransferLen
,
3093 BYTE
*PropertyBuffer
,
3097 return CR_CALL_NOT_IMPLEMENTED
;
3108 LPWSTR PropertyCultureName
,
3109 const DEVPROPKEY
*PropertyKey
,
3110 DEVPROPTYPE PropertyType
,
3111 PNP_PROP_SIZE PropertySize
,
3112 BYTE
*PropertyBuffer
,
3116 return CR_CALL_NOT_IMPLEMENTED
;
3127 return CR_CALL_NOT_IMPLEMENTED
;
3134 PNP_ApplyPowerSettings(
3138 return CR_CALL_NOT_IMPLEMENTED
;
3145 PNP_DriverStoreAddDriverPackage(
3149 return CR_CALL_NOT_IMPLEMENTED
;
3156 PNP_DriverStoreDeleteDriverPackage(
3160 return CR_CALL_NOT_IMPLEMENTED
;
3167 PNP_RegisterServiceNotification(
3171 return CR_CALL_NOT_IMPLEMENTED
;
3178 PNP_SetActiveService(
3184 return CR_CALL_NOT_IMPLEMENTED
;
3191 PNP_DeleteServiceDevices(
3195 return CR_CALL_NOT_IMPLEMENTED
;
3200 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3202 BOOL DeviceInstalled
= FALSE
;
3205 HANDLE hInstallEvent
;
3206 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3207 LPVOID Environment
= NULL
;
3208 PROCESS_INFORMATION ProcessInfo
;
3209 STARTUPINFOW StartupInfo
;
3213 /* The following lengths are constant (see below), they cannot overflow */
3214 WCHAR CommandLine
[116];
3215 WCHAR InstallEventName
[73];
3217 WCHAR UuidString
[39];
3219 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3221 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3223 if (RegOpenKeyExW(hEnumKey
,
3227 &DeviceKey
) == ERROR_SUCCESS
)
3229 if (RegQueryValueExW(DeviceKey
,
3234 NULL
) == ERROR_SUCCESS
)
3236 DPRINT("No need to install: %S\n", DeviceInstance
);
3237 RegCloseKey(DeviceKey
);
3241 BytesWritten
= sizeof(DWORD
);
3242 if (RegQueryValueExW(DeviceKey
,
3247 &BytesWritten
) == ERROR_SUCCESS
)
3249 if (Value
& CONFIGFLAG_FAILEDINSTALL
)
3251 DPRINT("No need to install: %S\n", DeviceInstance
);
3252 RegCloseKey(DeviceKey
);
3257 RegCloseKey(DeviceKey
);
3260 DPRINT1("Installing: %S\n", DeviceInstance
);
3262 /* Create a random UUID for the named pipe & event*/
3263 UuidCreate(&RandomUuid
);
3264 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3265 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3266 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3267 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3268 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3270 /* Create the event */
3271 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3272 wcscat(InstallEventName
, UuidString
);
3273 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3276 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3280 /* Create the named pipe */
3281 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3282 wcscat(PipeName
, UuidString
);
3283 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3284 if (hPipe
== INVALID_HANDLE_VALUE
)
3286 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3290 /* Launch rundll32 to call ClientSideInstallW */
3291 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3292 wcscat(CommandLine
, PipeName
);
3294 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3295 StartupInfo
.cb
= sizeof(StartupInfo
);
3299 /* newdev has to run under the environment of the current user */
3300 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3302 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3306 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3308 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3314 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3316 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3317 (ShowWizard is only set to FALSE for these two modes) */
3318 ASSERT(!ShowWizard
);
3320 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3322 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3327 /* Wait for the function to connect to our pipe */
3328 if (!ConnectNamedPipe(hPipe
, NULL
))
3330 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3332 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3337 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3338 Value
= sizeof(InstallEventName
);
3339 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3340 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3342 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3343 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3344 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3346 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3347 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3348 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3350 /* Wait for newdev.dll to finish processing */
3351 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3353 /* If the event got signalled, this is success */
3354 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3358 CloseHandle(hInstallEvent
);
3360 if (hPipe
!= INVALID_HANDLE_VALUE
)
3364 DestroyEnvironmentBlock(Environment
);
3366 if (ProcessInfo
.hProcess
)
3367 CloseHandle(ProcessInfo
.hProcess
);
3369 if (ProcessInfo
.hThread
)
3370 CloseHandle(ProcessInfo
.hThread
);
3372 if (!DeviceInstalled
)
3374 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3377 return DeviceInstalled
;
3393 return ERROR_INVALID_PARAMETER
;
3396 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3397 if (rc
!= ERROR_SUCCESS
)
3399 if (dwType
!= REG_SZ
)
3400 return ERROR_FILE_NOT_FOUND
;
3401 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3403 return ERROR_NOT_ENOUGH_MEMORY
;
3404 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3405 if (rc
!= ERROR_SUCCESS
)
3407 HeapFree(GetProcessHeap(), 0, Value
);
3410 /* NULL-terminate the string */
3411 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3414 return ERROR_SUCCESS
;
3422 DWORD regType
, active
, size
;
3426 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3427 if (rc
!= ERROR_SUCCESS
)
3430 size
= sizeof(DWORD
);
3431 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3432 if (rc
!= ERROR_SUCCESS
)
3434 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3437 ret
= (active
!= 0);
3443 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3452 HKEY ControlKey
= NULL
;
3453 LPWSTR SystemStartOptions
= NULL
;
3454 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3455 BOOL ConsoleBoot
= FALSE
;
3460 L
"SYSTEM\\CurrentControlSet\\Control",
3465 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3466 if (rc
!= ERROR_SUCCESS
)
3469 /* Check for CONSOLE switch in SystemStartOptions */
3470 CurrentOption
= SystemStartOptions
;
3471 while (CurrentOption
)
3473 NextOption
= wcschr(CurrentOption
, L
' ');
3475 *NextOption
= L
'\0';
3476 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3478 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3482 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3486 if (ControlKey
!= NULL
)
3487 RegCloseKey(ControlKey
);
3488 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3493 /* Loop to install all queued devices installations */
3495 DeviceInstallThread(LPVOID lpParameter
)
3497 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3498 PSLIST_ENTRY ListEntry
;
3500 PLIST_ENTRY ListEntry
;
3502 DeviceInstallParams
* Params
;
3505 UNREFERENCED_PARAMETER(lpParameter
);
3507 WaitForSingleObject(hInstallEvent
, INFINITE
);
3509 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3513 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3514 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3516 if ((BOOL
)IsListEmpty(&DeviceInstallListHead
))
3519 ListEntry
= RemoveHeadList(&DeviceInstallListHead
);
3521 if (ListEntry
== NULL
)
3523 SetEvent(hNoPendingInstalls
);
3524 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3528 ResetEvent(hNoPendingInstalls
);
3529 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3530 InstallDevice(Params
->DeviceIds
, showWizard
);
3539 PnpEventThread(LPVOID lpParameter
)
3541 PPLUGPLAY_EVENT_BLOCK PnpEvent
;
3544 RPC_STATUS RpcStatus
;
3546 UNREFERENCED_PARAMETER(lpParameter
);
3548 PnpEventSize
= 0x1000;
3549 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3550 if (PnpEvent
== NULL
)
3551 return ERROR_OUTOFMEMORY
;
3555 DPRINT("Calling NtGetPlugPlayEvent()\n");
3557 /* Wait for the next pnp event */
3558 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3560 /* Resize the buffer for the PnP event if it's too small. */
3561 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3563 PnpEventSize
+= 0x400;
3564 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3565 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3566 if (PnpEvent
== NULL
)
3567 return ERROR_OUTOFMEMORY
;
3571 if (!NT_SUCCESS(Status
))
3573 DPRINT("NtGetPlugPlayEvent() failed (Status %lx)\n", Status
);
3577 /* Process the pnp event */
3578 DPRINT("Received PnP Event\n");
3579 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3581 DeviceInstallParams
* Params
;
3583 DWORD DeviceIdLength
;
3585 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3587 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3590 /* Queue device install (will be dequeued by DeviceInstallThread */
3591 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3592 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3595 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3596 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3597 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3599 InsertTailList(&DeviceInstallListHead
, &Params
->ListEntry
);
3601 SetEvent(hDeviceInstallListNotEmpty
);
3605 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3607 // DWORD dwRecipient;
3609 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3611 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3612 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3615 // DBT_DEVNODES_CHANGED,
3617 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3619 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3621 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3623 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3625 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3627 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3629 // DWORD dwRecipient;
3631 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3633 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3634 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3637 // DBT_DEVNODES_CHANGED,
3639 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3641 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3643 // DWORD dwRecipient;
3645 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3647 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3648 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3651 // DBT_DEVNODES_CHANGED,
3653 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3655 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3657 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3659 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3661 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3665 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3666 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3667 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3668 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3669 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3672 /* Dequeue the current pnp event and signal the next one */
3673 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3676 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3678 return ERROR_SUCCESS
;
3683 UpdateServiceStatus(DWORD dwState
)
3685 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3686 ServiceStatus
.dwCurrentState
= dwState
;
3687 ServiceStatus
.dwControlsAccepted
= 0;
3688 ServiceStatus
.dwWin32ExitCode
= 0;
3689 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3690 ServiceStatus
.dwCheckPoint
= 0;
3692 if (dwState
== SERVICE_START_PENDING
||
3693 dwState
== SERVICE_STOP_PENDING
||
3694 dwState
== SERVICE_PAUSE_PENDING
||
3695 dwState
== SERVICE_CONTINUE_PENDING
)
3696 ServiceStatus
.dwWaitHint
= 10000;
3698 ServiceStatus
.dwWaitHint
= 0;
3700 SetServiceStatus(ServiceStatusHandle
,
3706 ServiceControlHandler(DWORD dwControl
,
3711 DPRINT1("ServiceControlHandler() called\n");
3715 case SERVICE_CONTROL_STOP
:
3716 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3717 /* Stop listening to RPC Messages */
3718 RpcMgmtStopServerListening(NULL
);
3719 UpdateServiceStatus(SERVICE_STOPPED
);
3720 return ERROR_SUCCESS
;
3722 case SERVICE_CONTROL_PAUSE
:
3723 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3724 UpdateServiceStatus(SERVICE_PAUSED
);
3725 return ERROR_SUCCESS
;
3727 case SERVICE_CONTROL_CONTINUE
:
3728 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3729 UpdateServiceStatus(SERVICE_RUNNING
);
3730 return ERROR_SUCCESS
;
3732 case SERVICE_CONTROL_INTERROGATE
:
3733 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3734 SetServiceStatus(ServiceStatusHandle
,
3736 return ERROR_SUCCESS
;
3738 case SERVICE_CONTROL_SHUTDOWN
:
3739 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3740 /* Stop listening to RPC Messages */
3741 RpcMgmtStopServerListening(NULL
);
3742 UpdateServiceStatus(SERVICE_STOPPED
);
3743 return ERROR_SUCCESS
;
3746 DPRINT1(" Control %lu received\n", dwControl
);
3747 return ERROR_CALL_NOT_IMPLEMENTED
;
3753 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3758 UNREFERENCED_PARAMETER(argc
);
3759 UNREFERENCED_PARAMETER(argv
);
3761 DPRINT("ServiceMain() called\n");
3763 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3764 ServiceControlHandler
,
3766 if (!ServiceStatusHandle
)
3768 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3772 UpdateServiceStatus(SERVICE_START_PENDING
);
3774 hThread
= CreateThread(NULL
,
3780 if (hThread
!= NULL
)
3781 CloseHandle(hThread
);
3783 hThread
= CreateThread(NULL
,
3789 if (hThread
!= NULL
)
3790 CloseHandle(hThread
);
3792 hThread
= CreateThread(NULL
,
3794 DeviceInstallThread
,
3798 if (hThread
!= NULL
)
3799 CloseHandle(hThread
);
3801 UpdateServiceStatus(SERVICE_RUNNING
);
3803 DPRINT("ServiceMain() done\n");
3807 InitializePnPManager(VOID
)
3812 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3814 /* We need this privilege for using CreateProcessAsUserW */
3815 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3817 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3818 if (hInstallEvent
== NULL
)
3820 dwError
= GetLastError();
3821 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3825 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3826 if (hDeviceInstallListNotEmpty
== NULL
)
3828 dwError
= GetLastError();
3829 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3833 hNoPendingInstalls
= CreateEventW(NULL
,
3836 L
"Global\\PnP_No_Pending_Install_Events");
3837 if (hNoPendingInstalls
== NULL
)
3839 dwError
= GetLastError();
3840 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3844 #ifdef HAVE_SLIST_ENTRY_IMPLEMENTED
3845 InitializeSListHead(&DeviceInstallListHead
);
3847 InitializeListHead(&DeviceInstallListHead
);
3850 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3851 L
"System\\CurrentControlSet\\Enum",
3855 if (dwError
!= ERROR_SUCCESS
)
3857 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3861 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3862 L
"System\\CurrentControlSet\\Control\\Class",
3866 if (dwError
!= ERROR_SUCCESS
)
3868 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3872 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3878 DllMain(HINSTANCE hinstDLL
,
3884 case DLL_PROCESS_ATTACH
:
3885 DisableThreadLibraryCalls(hinstDLL
);
3886 InitializePnPManager();
3889 case DLL_PROCESS_DETACH
: