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 WIN32_NO_STATUS
33 #define COM_NO_WINDOWS_H
45 #include <umpnpmgr/sysguid.h>
55 /* GLOBALS ******************************************************************/
57 static WCHAR ServiceName
[] = L
"PlugPlay";
59 static SERVICE_STATUS_HANDLE ServiceStatusHandle
;
60 static SERVICE_STATUS ServiceStatus
;
62 static WCHAR szRootDeviceId
[] = L
"HTREE\\ROOT\\0";
64 static HKEY hEnumKey
= NULL
;
65 static HKEY hClassKey
= NULL
;
67 static HANDLE hUserToken
= NULL
;
68 static HANDLE hInstallEvent
= NULL
;
69 static HANDLE hNoPendingInstalls
= NULL
;
71 static SLIST_HEADER DeviceInstallListHead
;
72 static HANDLE hDeviceInstallListNotEmpty
;
76 SLIST_ENTRY ListEntry
;
78 } DeviceInstallParams
;
80 /* FUNCTIONS *****************************************************************/
83 RpcServerThread(LPVOID lpParameter
)
86 BOOLEAN RegisteredProtSeq
= FALSE
;
88 UNREFERENCED_PARAMETER(lpParameter
);
90 DPRINT("RpcServerThread() called\n");
93 /* 2k/XP/2k3-compatible protocol sequence/endpoint */
94 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
97 NULL
); // Security descriptor
98 if (Status
== RPC_S_OK
)
99 RegisteredProtSeq
= TRUE
;
101 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
104 /* Vista/7-compatible protocol sequence/endpoint */
105 Status
= RpcServerUseProtseqEpW(L
"ncacn_np",
108 NULL
); // Security descriptor
109 if (Status
== RPC_S_OK
)
110 RegisteredProtSeq
= TRUE
;
112 DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status
);
114 /* Make sure there's a usable endpoint */
115 if (RegisteredProtSeq
== FALSE
)
118 Status
= RpcServerRegisterIf(pnp_v1_0_s_ifspec
,
121 if (Status
!= RPC_S_OK
)
123 DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status
);
127 Status
= RpcServerListen(1,
130 if (Status
!= RPC_S_OK
)
132 DPRINT1("RpcServerListen() failed (Status %lx)\n", Status
);
136 /* ROS HACK (this should never happen...) */
137 DPRINT1("*** Other devices won't be installed correctly. If something\n");
138 DPRINT1("*** doesn't work, try to reboot to get a new chance.\n");
140 DPRINT("RpcServerThread() done\n");
146 void __RPC_FAR
* __RPC_USER
midl_user_allocate(SIZE_T len
)
148 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, len
);
152 void __RPC_USER
midl_user_free(void __RPC_FAR
* ptr
)
154 HeapFree(GetProcessHeap(), 0, ptr
);
158 static CONFIGRET WINAPI
159 NtStatusToCrError(NTSTATUS Status
)
163 case STATUS_NOT_IMPLEMENTED
:
164 return CR_CALL_NOT_IMPLEMENTED
;
166 case STATUS_INVALID_PARAMETER
:
167 return CR_INVALID_DATA
;
169 case STATUS_NO_SUCH_DEVICE
:
170 return CR_NO_SUCH_DEVINST
;
172 case STATUS_ACCESS_DENIED
:
173 return CR_ACCESS_DENIED
;
175 case STATUS_BUFFER_TOO_SMALL
:
176 return CR_BUFFER_SMALL
;
178 case STATUS_OBJECT_NAME_NOT_FOUND
:
179 return CR_NO_SUCH_VALUE
;
188 SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID
,
189 OUT LPWSTR pszEnumerator
,
190 OUT LPWSTR pszDevice
,
191 OUT LPWSTR pszInstance
)
193 WCHAR szLocalDeviceInstanceID
[MAX_DEVICE_ID_LEN
];
194 LPWSTR lpEnumerator
= NULL
;
195 LPWSTR lpDevice
= NULL
;
196 LPWSTR lpInstance
= NULL
;
199 wcscpy(szLocalDeviceInstanceID
, pszDeviceInstanceID
);
205 lpEnumerator
= szLocalDeviceInstanceID
;
207 ptr
= wcschr(lpEnumerator
, L
'\\');
213 ptr
= wcschr(lpDevice
, L
'\\');
221 if (lpEnumerator
!= NULL
)
222 wcscpy(pszEnumerator
, lpEnumerator
);
224 if (lpDevice
!= NULL
)
225 wcscpy(pszDevice
, lpDevice
);
227 if (lpInstance
!= NULL
)
228 wcscpy(pszInstance
, lpInstance
);
232 /* PUBLIC FUNCTIONS **********************************************************/
240 UNREFERENCED_PARAMETER(hBinding
);
251 UNREFERENCED_PARAMETER(hBinding
);
263 UNREFERENCED_PARAMETER(hBinding
);
278 UNREFERENCED_PARAMETER(hBinding
);
279 UNREFERENCED_PARAMETER(ulFlags
);
281 *pulState
= CM_GLOBAL_STATE_CAN_DO_UI
| CM_GLOBAL_STATE_SERVICES_AVAILABLE
;
292 UNREFERENCED_PARAMETER(hBinding
);
294 DPRINT("PNP_InitDetection() called\n");
307 DWORD ReturnValue
= CR_FAILURE
;
310 UNREFERENCED_PARAMETER(hBinding
);
311 UNREFERENCED_PARAMETER(Admin
);
313 DPRINT("PNP_ReportLogOn(%u, %u) called\n", Admin
, ProcessId
);
315 /* Get the users token */
316 hProcess
= OpenProcess(PROCESS_ALL_ACCESS
, TRUE
, ProcessId
);
320 DPRINT1("OpenProcess failed with error %u\n", GetLastError());
326 CloseHandle(hUserToken
);
330 if (!OpenProcessToken(hProcess
, TOKEN_ASSIGN_PRIMARY
| TOKEN_DUPLICATE
| TOKEN_QUERY
, &hUserToken
))
332 DPRINT1("OpenProcessToken failed with error %u\n", GetLastError());
336 /* Trigger the installer thread */
338 SetEvent(hInstallEvent
);
340 ReturnValue
= CR_SUCCESS
;
344 CloseHandle(hProcess
);
353 PNP_ValidateDeviceInstance(
358 CONFIGRET ret
= CR_SUCCESS
;
359 HKEY hDeviceKey
= NULL
;
361 UNREFERENCED_PARAMETER(hBinding
);
362 UNREFERENCED_PARAMETER(ulFlags
);
364 DPRINT("PNP_ValidateDeviceInstance(%S %lx) called\n",
367 if (RegOpenKeyExW(hEnumKey
,
373 DPRINT("Could not open the Device Key!\n");
374 ret
= CR_NO_SUCH_DEVNODE
;
378 /* FIXME: add more tests */
381 if (hDeviceKey
!= NULL
)
382 RegCloseKey(hDeviceKey
);
384 DPRINT("PNP_ValidateDeviceInstance() done (returns %lx)\n", ret
);
393 PNP_GetRootDeviceInstance(
396 PNP_RPC_STRING_LEN ulLength
)
398 CONFIGRET ret
= CR_SUCCESS
;
400 UNREFERENCED_PARAMETER(hBinding
);
402 DPRINT("PNP_GetRootDeviceInstance() called\n");
406 ret
= CR_INVALID_POINTER
;
409 if (ulLength
< lstrlenW(szRootDeviceId
) + 1)
411 ret
= CR_BUFFER_SMALL
;
419 DPRINT("PNP_GetRootDeviceInstance() done (returns %lx)\n", ret
);
428 PNP_GetRelatedDeviceInstance(
430 DWORD ulRelationship
,
432 LPWSTR pRelatedDeviceId
,
433 PNP_RPC_STRING_LEN
*pulLength
,
436 PLUGPLAY_CONTROL_RELATED_DEVICE_DATA PlugPlayData
;
437 CONFIGRET ret
= CR_SUCCESS
;
440 UNREFERENCED_PARAMETER(hBinding
);
441 UNREFERENCED_PARAMETER(ulFlags
);
443 DPRINT("PNP_GetRelatedDeviceInstance() called\n");
444 DPRINT(" Relationship %ld\n", ulRelationship
);
445 DPRINT(" DeviceId %S\n", pDeviceID
);
447 RtlInitUnicodeString(&PlugPlayData
.TargetDeviceInstance
,
450 PlugPlayData
.Relation
= ulRelationship
;
452 PlugPlayData
.RelatedDeviceInstanceLength
= *pulLength
;
453 PlugPlayData
.RelatedDeviceInstance
= pRelatedDeviceId
;
455 Status
= NtPlugPlayControl(PlugPlayControlGetRelatedDevice
,
456 (PVOID
)&PlugPlayData
,
457 sizeof(PLUGPLAY_CONTROL_RELATED_DEVICE_DATA
));
458 if (!NT_SUCCESS(Status
))
460 ret
= NtStatusToCrError(Status
);
463 DPRINT("PNP_GetRelatedDeviceInstance() done (returns %lx)\n", ret
);
464 if (ret
== CR_SUCCESS
)
466 DPRINT("RelatedDevice: %wZ\n", &PlugPlayData
.RelatedDeviceInstance
);
476 PNP_EnumerateSubKeys(
481 PNP_RPC_STRING_LEN ulLength
,
482 PNP_RPC_STRING_LEN
*pulRequiredLen
,
485 CONFIGRET ret
= CR_SUCCESS
;
489 UNREFERENCED_PARAMETER(hBinding
);
490 UNREFERENCED_PARAMETER(ulFlags
);
492 DPRINT("PNP_EnumerateSubKeys() called\n");
496 case PNP_ENUMERATOR_SUBKEYS
:
500 case PNP_CLASS_SUBKEYS
:
508 *pulRequiredLen
= ulLength
;
509 dwError
= RegEnumKeyExW(hKey
,
517 if (dwError
!= ERROR_SUCCESS
)
519 ret
= (dwError
== ERROR_NO_MORE_ITEMS
) ? CR_NO_SUCH_VALUE
: CR_FAILURE
;
526 DPRINT("PNP_EnumerateSubKeys() done (returns %lx)\n", ret
);
534 GetDeviceInstanceList(
535 _In_ PWSTR pszDevice
,
536 _Inout_ PWSTR pszBuffer
,
537 _Inout_ PDWORD pulLength
)
539 WCHAR szInstanceBuffer
[MAX_DEVICE_ID_LEN
];
540 WCHAR szPathBuffer
[512];
542 DWORD dwInstanceLength
, dwPathLength
, dwUsedLength
;
543 DWORD dwIndex
, dwError
;
545 CONFIGRET ret
= CR_SUCCESS
;
547 dwError
= RegOpenKeyExW(hEnumKey
,
550 KEY_ENUMERATE_SUB_KEYS
,
552 if (dwError
!= ERROR_SUCCESS
)
554 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
555 return CR_REGISTRY_ERROR
;
561 for (dwIndex
= 0; ; dwIndex
++)
563 dwInstanceLength
= MAX_DEVICE_ID_LEN
;
564 dwError
= RegEnumKeyExW(hDeviceKey
,
572 if (dwError
!= ERROR_SUCCESS
)
575 wsprintf(szPathBuffer
, L
"%s\\%s", pszDevice
, szInstanceBuffer
);
576 DPRINT("Path: %S\n", szPathBuffer
);
578 dwPathLength
= wcslen(szPathBuffer
) + 1;
579 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
581 ret
= CR_BUFFER_SMALL
;
585 wcscpy(pPtr
, szPathBuffer
);
586 dwUsedLength
+= dwPathLength
;
587 pPtr
+= dwPathLength
;
589 *pPtr
= UNICODE_NULL
;
592 RegCloseKey(hDeviceKey
);
594 if (ret
== CR_SUCCESS
)
595 *pulLength
= dwUsedLength
+ 1;
610 PNP_RPC_STRING_LEN
*pulLength
,
613 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
614 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
615 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
616 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
617 CONFIGRET ret
= CR_SUCCESS
;
620 DPRINT("PNP_GetDeviceList() called\n");
622 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
623 return CR_INVALID_FLAG
;
625 if (pulLength
== NULL
)
626 return CR_INVALID_POINTER
;
628 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
630 return CR_INVALID_POINTER
;
633 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
634 CM_GETIDLIST_FILTER_POWERRELATIONS
|
635 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
636 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
638 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
640 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
642 PlugPlayData
.Relations
= 3;
644 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
646 PlugPlayData
.Relations
= 2;
648 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
650 PlugPlayData
.Relations
= 1;
652 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
654 PlugPlayData
.Relations
= 0;
657 PlugPlayData
.BufferSize
= *pulLength
* sizeof(WCHAR
);
658 PlugPlayData
.Buffer
= Buffer
;
660 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
661 (PVOID
)&PlugPlayData
,
662 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
663 if (NT_SUCCESS(Status
))
665 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
669 ret
= NtStatusToCrError(Status
);
672 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
674 ret
= CR_CALL_NOT_IMPLEMENTED
;
676 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
678 SplitDeviceInstanceID(pszFilter
,
683 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
685 ret
= GetDeviceInstanceList(pszFilter
,
691 ret
= CR_CALL_NOT_IMPLEMENTED
;
694 else /* CM_GETIDLIST_FILTER_NONE */
696 ret
= CR_CALL_NOT_IMPLEMENTED
;
705 GetDeviceInstanceListSize(
706 _In_ LPCWSTR pszDevice
,
707 _Out_ PULONG pulLength
)
710 DWORD dwSubKeys
, dwMaxSubKeyLength
;
713 /* Open the device key */
714 dwError
= RegOpenKeyExW(hEnumKey
,
719 if (dwError
!= ERROR_SUCCESS
)
721 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
722 return CR_REGISTRY_ERROR
;
725 /* Retrieve the number of device instances and the maximum name length */
726 dwError
= RegQueryInfoKeyW(hDeviceKey
,
738 if (dwError
!= ERROR_SUCCESS
)
740 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
742 dwMaxSubKeyLength
= 0;
745 /* Close the device key */
746 RegCloseKey(hDeviceKey
);
748 /* Return the largest possible buffer size */
749 *pulLength
= (dwSubKeys
* (wcslen(pszDevice
) + 1 + dwMaxSubKeyLength
+ 1)) + 1;
758 PNP_GetDeviceListSize(
761 PNP_RPC_BUFFER_SIZE
*pulLength
,
764 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
765 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
766 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
767 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
768 CONFIGRET ret
= CR_SUCCESS
;
771 DPRINT("PNP_GetDeviceListSize() called\n");
773 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
774 return CR_INVALID_FLAG
;
776 if (pulLength
== NULL
)
777 return CR_INVALID_POINTER
;
779 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
781 return CR_INVALID_POINTER
;
786 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
787 CM_GETIDLIST_FILTER_POWERRELATIONS
|
788 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
789 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
791 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
793 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
795 PlugPlayData
.Relations
= 3;
797 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
799 PlugPlayData
.Relations
= 2;
801 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
803 PlugPlayData
.Relations
= 1;
805 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
807 PlugPlayData
.Relations
= 0;
810 PlugPlayData
.BufferSize
= 0;
811 PlugPlayData
.Buffer
= NULL
;
813 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
814 (PVOID
)&PlugPlayData
,
815 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
816 if (NT_SUCCESS(Status
))
818 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
822 ret
= NtStatusToCrError(Status
);
825 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
827 ret
= CR_CALL_NOT_IMPLEMENTED
;
829 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
831 SplitDeviceInstanceID(pszFilter
,
836 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
838 ret
= GetDeviceInstanceListSize(pszFilter
,
843 ret
= CR_CALL_NOT_IMPLEMENTED
;
846 else /* CM_GETIDLIST_FILTER_NONE */
848 ret
= CR_CALL_NOT_IMPLEMENTED
;
864 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
865 CONFIGRET ret
= CR_SUCCESS
;
868 UNREFERENCED_PARAMETER(hBinding
);
869 UNREFERENCED_PARAMETER(ulFlags
);
871 DPRINT("PNP_GetDepth() called\n");
873 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
876 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
877 (PVOID
)&PlugPlayData
,
878 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
879 if (NT_SUCCESS(Status
))
881 *pulDepth
= PlugPlayData
.Depth
;
885 ret
= NtStatusToCrError(Status
);
888 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
897 PNP_GetDeviceRegProp(
901 DWORD
*pulRegDataType
,
903 PNP_PROP_SIZE
*pulTransferLen
,
904 PNP_PROP_SIZE
*pulLength
,
907 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
908 CONFIGRET ret
= CR_SUCCESS
;
909 LPWSTR lpValueName
= NULL
;
914 UNREFERENCED_PARAMETER(hBinding
);
916 DPRINT("PNP_GetDeviceRegProp() called\n");
918 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
920 ret
= CR_INVALID_POINTER
;
926 ret
= CR_INVALID_FLAG
;
930 /* FIXME: Check pDeviceID */
932 if (*pulLength
< *pulTransferLen
)
933 *pulLength
= *pulTransferLen
;
939 case CM_DRP_DEVICEDESC
:
940 lpValueName
= L
"DeviceDesc";
943 case CM_DRP_HARDWAREID
:
944 lpValueName
= L
"HardwareID";
947 case CM_DRP_COMPATIBLEIDS
:
948 lpValueName
= L
"CompatibleIDs";
952 lpValueName
= L
"Service";
956 lpValueName
= L
"Class";
959 case CM_DRP_CLASSGUID
:
960 lpValueName
= L
"ClassGUID";
964 lpValueName
= L
"Driver";
967 case CM_DRP_CONFIGFLAGS
:
968 lpValueName
= L
"ConfigFlags";
972 lpValueName
= L
"Mfg";
975 case CM_DRP_FRIENDLYNAME
:
976 lpValueName
= L
"FriendlyName";
979 case CM_DRP_LOCATION_INFORMATION
:
980 lpValueName
= L
"LocationInformation";
983 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
984 PlugPlayData
.Property
= PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME
;
987 case CM_DRP_CAPABILITIES
:
988 lpValueName
= L
"Capabilities";
991 case CM_DRP_UI_NUMBER
:
992 PlugPlayData
.Property
= PNP_PROPERTY_UI_NUMBER
;
995 case CM_DRP_UPPERFILTERS
:
996 lpValueName
= L
"UpperFilters";
999 case CM_DRP_LOWERFILTERS
:
1000 lpValueName
= L
"LowerFilters";
1003 case CM_DRP_BUSTYPEGUID
:
1004 PlugPlayData
.Property
= PNP_PROPERTY_BUSTYPEGUID
;
1007 case CM_DRP_LEGACYBUSTYPE
:
1008 PlugPlayData
.Property
= PNP_PROPERTY_LEGACYBUSTYPE
;
1011 case CM_DRP_BUSNUMBER
:
1012 PlugPlayData
.Property
= PNP_PROPERTY_BUSNUMBER
;
1015 case CM_DRP_ENUMERATOR_NAME
:
1016 PlugPlayData
.Property
= PNP_PROPERTY_ENUMERATOR_NAME
;
1019 case CM_DRP_SECURITY
:
1020 lpValueName
= L
"Security";
1023 case CM_DRP_DEVTYPE
:
1024 lpValueName
= L
"DeviceType";
1027 case CM_DRP_EXCLUSIVE
:
1028 lpValueName
= L
"Exclusive";
1031 case CM_DRP_CHARACTERISTICS
:
1032 lpValueName
= L
"DeviceCharacteristics";
1035 case CM_DRP_ADDRESS
:
1036 PlugPlayData
.Property
= PNP_PROPERTY_ADDRESS
;
1039 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1040 lpValueName
= L
"UINumberDescFormat";
1043 case CM_DRP_DEVICE_POWER_DATA
:
1044 PlugPlayData
.Property
= PNP_PROPERTY_POWER_DATA
;
1047 case CM_DRP_REMOVAL_POLICY
:
1048 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY
;
1051 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
1052 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
;
1055 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1056 lpValueName
= L
"RemovalPolicy";
1059 case CM_DRP_INSTALL_STATE
:
1060 PlugPlayData
.Property
= PNP_PROPERTY_INSTALL_STATE
;
1063 #if (WINVER >= _WIN32_WINNT_WS03)
1064 case CM_DRP_LOCATION_PATHS
:
1065 PlugPlayData
.Property
= PNP_PROPERTY_LOCATION_PATHS
;
1069 #if (WINVER >= _WIN32_WINNT_WIN7)
1070 case CM_DRP_BASE_CONTAINERID
:
1071 PlugPlayData
.Property
= PNP_PROPERTY_CONTAINERID
;
1076 ret
= CR_INVALID_PROPERTY
;
1080 DPRINT("Value name: %S\n", lpValueName
);
1084 /* Retrieve information from the Registry */
1085 lError
= RegOpenKeyExW(hEnumKey
,
1090 if (lError
!= ERROR_SUCCESS
)
1094 ret
= CR_INVALID_DEVNODE
;
1098 lError
= RegQueryValueExW(hKey
,
1104 if (lError
!= ERROR_SUCCESS
)
1106 if (lError
== ERROR_MORE_DATA
)
1108 ret
= CR_BUFFER_SMALL
;
1113 ret
= CR_NO_SUCH_VALUE
;
1119 /* Retrieve information from the Device Node */
1120 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1122 PlugPlayData
.Buffer
= Buffer
;
1123 PlugPlayData
.BufferSize
= *pulLength
;
1125 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
1126 (PVOID
)&PlugPlayData
,
1127 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
1128 if (NT_SUCCESS(Status
))
1130 *pulLength
= PlugPlayData
.BufferSize
;
1134 ret
= NtStatusToCrError(Status
);
1140 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1145 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1154 PNP_SetDeviceRegProp(
1160 PNP_PROP_SIZE ulLength
,
1163 CONFIGRET ret
= CR_SUCCESS
;
1164 LPWSTR lpValueName
= NULL
;
1167 UNREFERENCED_PARAMETER(hBinding
);
1168 UNREFERENCED_PARAMETER(ulFlags
);
1170 DPRINT("PNP_SetDeviceRegProp() called\n");
1172 DPRINT("DeviceId: %S\n", pDeviceId
);
1173 DPRINT("Property: %lu\n", ulProperty
);
1174 DPRINT("DataType: %lu\n", ulDataType
);
1175 DPRINT("Length: %lu\n", ulLength
);
1179 case CM_DRP_DEVICEDESC
:
1180 lpValueName
= L
"DeviceDesc";
1183 case CM_DRP_HARDWAREID
:
1184 lpValueName
= L
"HardwareID";
1187 case CM_DRP_COMPATIBLEIDS
:
1188 lpValueName
= L
"CompatibleIDs";
1191 case CM_DRP_SERVICE
:
1192 lpValueName
= L
"Service";
1196 lpValueName
= L
"Class";
1199 case CM_DRP_CLASSGUID
:
1200 lpValueName
= L
"ClassGUID";
1204 lpValueName
= L
"Driver";
1207 case CM_DRP_CONFIGFLAGS
:
1208 lpValueName
= L
"ConfigFlags";
1212 lpValueName
= L
"Mfg";
1215 case CM_DRP_FRIENDLYNAME
:
1216 lpValueName
= L
"FriendlyName";
1219 case CM_DRP_LOCATION_INFORMATION
:
1220 lpValueName
= L
"LocationInformation";
1223 case CM_DRP_UPPERFILTERS
:
1224 lpValueName
= L
"UpperFilters";
1227 case CM_DRP_LOWERFILTERS
:
1228 lpValueName
= L
"LowerFilters";
1231 case CM_DRP_SECURITY
:
1232 lpValueName
= L
"Security";
1235 case CM_DRP_DEVTYPE
:
1236 lpValueName
= L
"DeviceType";
1239 case CM_DRP_EXCLUSIVE
:
1240 lpValueName
= L
"Exclusive";
1243 case CM_DRP_CHARACTERISTICS
:
1244 lpValueName
= L
"DeviceCharacteristics";
1247 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1248 lpValueName
= L
"UINumberDescFormat";
1251 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1252 lpValueName
= L
"RemovalPolicy";
1256 return CR_INVALID_PROPERTY
;
1259 DPRINT("Value name: %S\n", lpValueName
);
1261 if (RegOpenKeyExW(hEnumKey
,
1266 return CR_INVALID_DEVNODE
;
1270 if (RegDeleteValueW(hKey
,
1272 ret
= CR_REGISTRY_ERROR
;
1276 if (RegSetValueExW(hKey
,
1282 ret
= CR_REGISTRY_ERROR
;
1287 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1296 PNP_GetClassInstance(
1299 LPWSTR pszClassInstance
,
1300 PNP_RPC_STRING_LEN ulLength
)
1303 return CR_CALL_NOT_IMPLEMENTED
;
1318 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1327 return CR_REGISTRY_ERROR
;
1329 /* FIXME: Set security key */
1340 PNP_DeleteRegistryKey(
1343 LPWSTR pszParentKey
,
1348 return CR_CALL_NOT_IMPLEMENTED
;
1357 DWORD
*pulClassCount
,
1363 UNREFERENCED_PARAMETER(hBinding
);
1364 UNREFERENCED_PARAMETER(ulFlags
);
1366 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1371 if (dwError
!= ERROR_SUCCESS
)
1372 return CR_INVALID_DATA
;
1374 dwError
= RegQueryInfoKeyW(hKey
,
1387 if (dwError
!= ERROR_SUCCESS
)
1388 return CR_INVALID_DATA
;
1399 LPWSTR pszClassGuid
,
1401 PNP_RPC_STRING_LEN
*pulLength
,
1404 WCHAR szKeyName
[MAX_PATH
];
1405 CONFIGRET ret
= CR_SUCCESS
;
1409 UNREFERENCED_PARAMETER(hBinding
);
1410 UNREFERENCED_PARAMETER(ulFlags
);
1412 DPRINT("PNP_GetClassName() called\n");
1414 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1415 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1416 lstrcatW(szKeyName
, pszClassGuid
);
1418 return CR_INVALID_DATA
;
1420 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1425 return CR_REGISTRY_ERROR
;
1427 dwSize
= *pulLength
* sizeof(WCHAR
);
1428 if (RegQueryValueExW(hKey
,
1436 ret
= CR_REGISTRY_ERROR
;
1440 *pulLength
= dwSize
/ sizeof(WCHAR
);
1445 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1456 LPWSTR pszClassGuid
,
1459 CONFIGRET ret
= CR_SUCCESS
;
1461 UNREFERENCED_PARAMETER(hBinding
);
1463 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1465 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1467 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1468 ret
= CR_REGISTRY_ERROR
;
1472 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1473 ret
= CR_REGISTRY_ERROR
;
1476 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1485 PNP_GetInterfaceDeviceAlias(
1487 LPWSTR pszInterfaceDevice
,
1488 GUID
*AliasInterfaceGuid
,
1489 LPWSTR pszAliasInterfaceDevice
,
1490 PNP_RPC_STRING_LEN
*pulLength
,
1491 PNP_RPC_STRING_LEN
*pulTransferLen
,
1495 return CR_CALL_NOT_IMPLEMENTED
;
1502 PNP_GetInterfaceDeviceList(
1504 GUID
*InterfaceGuid
,
1507 PNP_RPC_BUFFER_SIZE
*pulLength
,
1511 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1512 DWORD ret
= CR_SUCCESS
;
1514 UNREFERENCED_PARAMETER(hBinding
);
1516 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1519 PlugPlayData
.Flags
= ulFlags
;
1520 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1521 PlugPlayData
.Buffer
= Buffer
;
1522 PlugPlayData
.BufferSize
= *pulLength
;
1524 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1525 (PVOID
)&PlugPlayData
,
1526 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1527 if (NT_SUCCESS(Status
))
1529 *pulLength
= PlugPlayData
.BufferSize
;
1533 ret
= NtStatusToCrError(Status
);
1536 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1544 PNP_GetInterfaceDeviceListSize(
1546 PNP_RPC_BUFFER_SIZE
*pulLen
,
1547 GUID
*InterfaceGuid
,
1552 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1553 DWORD ret
= CR_SUCCESS
;
1555 UNREFERENCED_PARAMETER(hBinding
);
1557 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1559 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1562 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1563 PlugPlayData
.Buffer
= NULL
;
1564 PlugPlayData
.BufferSize
= 0;
1565 PlugPlayData
.Flags
= ulFlags
;
1567 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1568 (PVOID
)&PlugPlayData
,
1569 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1570 if (NT_SUCCESS(Status
))
1572 *pulLen
= PlugPlayData
.BufferSize
;
1576 ret
= NtStatusToCrError(Status
);
1579 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1587 PNP_RegisterDeviceClassAssociation(
1590 GUID
*InterfaceGuid
,
1591 LPWSTR pszReference
,
1593 PNP_RPC_STRING_LEN
*pulLength
,
1594 PNP_RPC_STRING_LEN
*pulTransferLen
,
1598 return CR_CALL_NOT_IMPLEMENTED
;
1605 PNP_UnregisterDeviceClassAssociation(
1607 LPWSTR pszInterfaceDevice
,
1611 return CR_CALL_NOT_IMPLEMENTED
;
1618 PNP_GetClassRegProp(
1620 LPWSTR pszClassGuid
,
1622 DWORD
*pulRegDataType
,
1624 PNP_RPC_STRING_LEN
*pulTransferLen
,
1625 PNP_RPC_STRING_LEN
*pulLength
,
1628 CONFIGRET ret
= CR_SUCCESS
;
1629 LPWSTR lpValueName
= NULL
;
1630 HKEY hInstKey
= NULL
;
1631 HKEY hPropKey
= NULL
;
1634 UNREFERENCED_PARAMETER(hBinding
);
1636 DPRINT("PNP_GetClassRegProp() called\n");
1638 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1640 ret
= CR_INVALID_POINTER
;
1646 ret
= CR_INVALID_FLAG
;
1650 if (*pulLength
< *pulTransferLen
)
1651 *pulLength
= *pulTransferLen
;
1653 *pulTransferLen
= 0;
1657 case CM_CRP_SECURITY
:
1658 lpValueName
= L
"Security";
1661 case CM_CRP_DEVTYPE
:
1662 lpValueName
= L
"DeviceType";
1665 case CM_CRP_EXCLUSIVE
:
1666 lpValueName
= L
"Exclusive";
1669 case CM_CRP_CHARACTERISTICS
:
1670 lpValueName
= L
"DeviceCharacteristics";
1674 ret
= CR_INVALID_PROPERTY
;
1678 DPRINT("Value name: %S\n", lpValueName
);
1680 lError
= RegOpenKeyExW(hClassKey
,
1685 if (lError
!= ERROR_SUCCESS
)
1688 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1692 lError
= RegOpenKeyExW(hInstKey
,
1697 if (lError
!= ERROR_SUCCESS
)
1700 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1704 lError
= RegQueryValueExW(hPropKey
,
1710 if (lError
!= ERROR_SUCCESS
)
1712 if (lError
== ERROR_MORE_DATA
)
1714 ret
= CR_BUFFER_SMALL
;
1719 ret
= CR_NO_SUCH_VALUE
;
1724 if (ret
== CR_SUCCESS
)
1725 *pulTransferLen
= *pulLength
;
1727 if (hPropKey
!= NULL
)
1728 RegCloseKey(hPropKey
);
1730 if (hInstKey
!= NULL
)
1731 RegCloseKey(hInstKey
);
1733 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1742 PNP_SetClassRegProp(
1744 LPWSTR pszClassGuid
,
1748 PNP_PROP_SIZE ulLength
,
1751 CONFIGRET ret
= CR_SUCCESS
;
1752 LPWSTR lpValueName
= NULL
;
1757 UNREFERENCED_PARAMETER(hBinding
);
1759 DPRINT("PNP_SetClassRegProp() called\n");
1762 return CR_INVALID_FLAG
;
1766 case CM_CRP_SECURITY
:
1767 lpValueName
= L
"Security";
1770 case CM_CRP_DEVTYPE
:
1771 lpValueName
= L
"DeviceType";
1774 case CM_CRP_EXCLUSIVE
:
1775 lpValueName
= L
"Exclusive";
1778 case CM_CRP_CHARACTERISTICS
:
1779 lpValueName
= L
"DeviceCharacteristics";
1783 return CR_INVALID_PROPERTY
;
1786 lError
= RegOpenKeyExW(hClassKey
,
1791 if (lError
!= ERROR_SUCCESS
)
1793 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1797 /* FIXME: Set security descriptor */
1798 lError
= RegCreateKeyExW(hInstKey
,
1802 REG_OPTION_NON_VOLATILE
,
1807 if (lError
!= ERROR_SUCCESS
)
1809 ret
= CR_REGISTRY_ERROR
;
1815 if (RegDeleteValueW(hPropKey
,
1817 ret
= CR_REGISTRY_ERROR
;
1821 if (RegSetValueExW(hPropKey
,
1827 ret
= CR_REGISTRY_ERROR
;
1831 if (hPropKey
!= NULL
)
1832 RegCloseKey(hPropKey
);
1834 if (hInstKey
!= NULL
)
1835 RegCloseKey(hInstKey
);
1842 CreateDeviceInstance(LPWSTR pszDeviceID
)
1844 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1845 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1846 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1847 HKEY hKeyEnumerator
;
1853 /* Split the instance ID */
1854 SplitDeviceInstanceID(pszDeviceID
,
1859 /* Open or create the enumerator key */
1860 lError
= RegCreateKeyExW(hEnumKey
,
1864 REG_OPTION_NON_VOLATILE
,
1869 if (lError
!= ERROR_SUCCESS
)
1871 return CR_REGISTRY_ERROR
;
1874 /* Open or create the device key */
1875 lError
= RegCreateKeyExW(hKeyEnumerator
,
1879 REG_OPTION_NON_VOLATILE
,
1885 /* Close the enumerator key */
1886 RegCloseKey(hKeyEnumerator
);
1888 if (lError
!= ERROR_SUCCESS
)
1890 return CR_REGISTRY_ERROR
;
1893 /* Try to open the instance key and fail if it exists */
1894 lError
= RegOpenKeyExW(hKeyDevice
,
1899 if (lError
== ERROR_SUCCESS
)
1901 DPRINT1("Instance %S already exists!\n", szInstance
);
1902 RegCloseKey(hKeyInstance
);
1903 RegCloseKey(hKeyDevice
);
1904 return CR_ALREADY_SUCH_DEVINST
;
1907 /* Create a new instance key */
1908 lError
= RegCreateKeyExW(hKeyDevice
,
1912 REG_OPTION_NON_VOLATILE
,
1918 /* Close the device key */
1919 RegCloseKey(hKeyDevice
);
1921 if (lError
!= ERROR_SUCCESS
)
1923 return CR_REGISTRY_ERROR
;
1926 /* Create the 'Control' sub key */
1927 lError
= RegCreateKeyExW(hKeyInstance
,
1931 REG_OPTION_NON_VOLATILE
,
1936 if (lError
== ERROR_SUCCESS
)
1938 RegCloseKey(hKeyControl
);
1941 RegCloseKey(hKeyInstance
);
1943 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
1953 LPWSTR pszParentDeviceID
,
1954 PNP_RPC_STRING_LEN ulLength
,
1957 CONFIGRET ret
= CR_SUCCESS
;
1959 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
1961 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
1963 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
1964 DWORD dwInstanceNumber
;
1966 /* Generated ID is: Root\<Device ID>\<Instance number> */
1967 dwInstanceNumber
= 0;
1970 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
1971 pszDeviceID
, dwInstanceNumber
);
1973 /* Try to create a device instance with this ID */
1974 ret
= CreateDeviceInstance(szGeneratedInstance
);
1978 while (ret
== CR_ALREADY_SUCH_DEVINST
);
1980 if (ret
== CR_SUCCESS
)
1982 /* pszDeviceID is an out parameter too for generated IDs */
1983 if (wcslen(szGeneratedInstance
) > ulLength
)
1985 ret
= CR_BUFFER_SMALL
;
1989 wcscpy(pszDeviceID
, szGeneratedInstance
);
1995 /* Create the device instance */
1996 ret
= CreateDeviceInstance(pszDeviceID
);
1999 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
2006 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
2007 LPWSTR pszDeviceInstanceSource
)
2009 DPRINT("MoveDeviceInstance: not implemented\n");
2011 return CR_CALL_NOT_IMPLEMENTED
;
2016 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
2019 DPRINT("SetupDeviceInstance: not implemented\n");
2021 return CR_CALL_NOT_IMPLEMENTED
;
2026 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
2028 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
2029 CONFIGRET ret
= CR_SUCCESS
;
2032 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
2034 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
2035 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
2036 if (!NT_SUCCESS(Status
))
2037 ret
= NtStatusToCrError(Status
);
2044 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
2046 DPRINT("DisableDeviceInstance: not implemented\n");
2048 return CR_CALL_NOT_IMPLEMENTED
;
2053 ReenumerateDeviceInstance(
2054 _In_ LPWSTR pszDeviceInstance
,
2057 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData
;
2058 CONFIGRET ret
= CR_SUCCESS
;
2061 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
2062 pszDeviceInstance
, ulFlags
);
2064 if (ulFlags
& ~CM_REENUMERATE_BITS
)
2065 return CR_INVALID_FLAG
;
2067 if (ulFlags
& CM_REENUMERATE_RETRY_INSTALLATION
)
2069 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
2072 RtlInitUnicodeString(&EnumerateDeviceData
.DeviceInstance
,
2074 EnumerateDeviceData
.Flags
= 0;
2076 Status
= NtPlugPlayControl(PlugPlayControlEnumerateDevice
,
2077 &EnumerateDeviceData
,
2078 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA
));
2079 if (!NT_SUCCESS(Status
))
2080 ret
= NtStatusToCrError(Status
);
2089 PNP_DeviceInstanceAction(
2093 LPWSTR pszDeviceInstance1
,
2094 LPWSTR pszDeviceInstance2
)
2096 CONFIGRET ret
= CR_SUCCESS
;
2098 UNREFERENCED_PARAMETER(hBinding
);
2100 DPRINT("PNP_DeviceInstanceAction() called\n");
2104 case PNP_DEVINST_MOVE
:
2105 ret
= MoveDeviceInstance(pszDeviceInstance1
,
2106 pszDeviceInstance2
);
2109 case PNP_DEVINST_SETUP
:
2110 ret
= SetupDeviceInstance(pszDeviceInstance1
,
2114 case PNP_DEVINST_ENABLE
:
2115 ret
= EnableDeviceInstance(pszDeviceInstance1
);
2118 case PNP_DEVINST_DISABLE
:
2119 ret
= DisableDeviceInstance(pszDeviceInstance1
);
2122 case PNP_DEVINST_REENUMERATE
:
2123 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
,
2128 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2129 ret
= CR_CALL_NOT_IMPLEMENTED
;
2132 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2141 PNP_GetDeviceStatus(
2148 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
2149 CONFIGRET ret
= CR_SUCCESS
;
2152 UNREFERENCED_PARAMETER(hBinding
);
2153 UNREFERENCED_PARAMETER(ulFlags
);
2155 DPRINT("PNP_GetDeviceStatus() called\n");
2157 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2159 PlugPlayData
.Operation
= 0; /* Get status */
2161 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2162 (PVOID
)&PlugPlayData
,
2163 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2164 if (NT_SUCCESS(Status
))
2166 *pulStatus
= PlugPlayData
.DeviceStatus
;
2167 *pulProblem
= PlugPlayData
.DeviceProblem
;
2171 ret
= NtStatusToCrError(Status
);
2174 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2183 PNP_SetDeviceProblem(
2190 return CR_CALL_NOT_IMPLEMENTED
;
2200 PPNP_VETO_TYPE pVetoType
,
2206 return CR_CALL_NOT_IMPLEMENTED
;
2212 PNP_UninstallDevInst(
2218 return CR_CALL_NOT_IMPLEMENTED
;
2223 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2229 lpPtr
= lpDeviceIdList
;
2232 dwLength
= wcslen(lpPtr
);
2233 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2236 lpPtr
+= (dwLength
+ 1);
2244 AppendDeviceId(LPWSTR lpDeviceIdList
,
2245 LPDWORD lpDeviceIdListSize
,
2251 dwLen
= wcslen(lpDeviceId
);
2252 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2254 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2256 dwPos
+= (dwLen
+ 1);
2258 lpDeviceIdList
[dwPos
] = 0;
2260 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2273 CONFIGRET ret
= CR_SUCCESS
;
2276 DWORD dwDeviceIdListSize
;
2277 DWORD dwNewDeviceIdSize
;
2278 WCHAR
* pszDeviceIdList
= NULL
;
2280 UNREFERENCED_PARAMETER(hBinding
);
2282 DPRINT("PNP_AddID() called\n");
2283 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2284 DPRINT(" DeviceId: %S\n", pszID
);
2285 DPRINT(" Flags: %lx\n", ulFlags
);
2287 if (RegOpenKeyExW(hEnumKey
,
2290 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2291 &hDeviceKey
) != ERROR_SUCCESS
)
2293 DPRINT("Failed to open the device key!\n");
2294 return CR_INVALID_DEVNODE
;
2297 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2299 if (RegQueryValueExW(hDeviceKey
,
2304 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2306 DPRINT("Failed to query the desired ID string!\n");
2307 ret
= CR_REGISTRY_ERROR
;
2311 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2312 if (!dwNewDeviceIdSize
)
2314 ret
= CR_INVALID_POINTER
;
2318 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2320 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2321 if (!pszDeviceIdList
)
2323 DPRINT("Failed to allocate memory for the desired ID string!\n");
2324 ret
= CR_OUT_OF_MEMORY
;
2328 if (RegQueryValueExW(hDeviceKey
,
2332 (LPBYTE
)pszDeviceIdList
,
2333 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2335 DPRINT("Failed to query the desired ID string!\n");
2336 ret
= CR_REGISTRY_ERROR
;
2340 /* Check whether the device ID is already in use */
2341 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2343 DPRINT("Device ID was found in the ID string!\n");
2348 /* Append the Device ID */
2349 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2351 if (RegSetValueExW(hDeviceKey
,
2355 (LPBYTE
)pszDeviceIdList
,
2356 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2358 DPRINT("Failed to set the desired ID string!\n");
2359 ret
= CR_REGISTRY_ERROR
;
2363 RegCloseKey(hDeviceKey
);
2364 if (pszDeviceIdList
)
2365 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2367 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2382 return CR_CALL_NOT_IMPLEMENTED
;
2392 PPNP_VETO_TYPE pVetoType
,
2398 return CR_CALL_NOT_IMPLEMENTED
;
2405 PNP_RequestDeviceEject(
2408 PPNP_VETO_TYPE pVetoType
,
2414 return CR_CALL_NOT_IMPLEMENTED
;
2421 PNP_IsDockStationPresent(
2429 CONFIGRET ret
= CR_SUCCESS
;
2431 UNREFERENCED_PARAMETER(hBinding
);
2433 DPRINT1("PNP_IsDockStationPresent() called\n");
2437 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2441 &hKey
) != ERROR_SUCCESS
)
2442 return CR_REGISTRY_ERROR
;
2444 dwSize
= sizeof(DWORD
);
2445 if (RegQueryValueExW(hKey
,
2450 &dwSize
) != ERROR_SUCCESS
)
2451 ret
= CR_REGISTRY_ERROR
;
2455 if (ret
== CR_SUCCESS
)
2457 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2459 ret
= CR_REGISTRY_ERROR
;
2461 else if (dwValue
!= 0)
2467 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2480 return CR_CALL_NOT_IMPLEMENTED
;
2493 PPNP_VETO_TYPE pVetoType
,
2498 CONFIGRET ret
= CR_SUCCESS
;
2499 WCHAR szKeyName
[MAX_PATH
];
2504 UNREFERENCED_PARAMETER(hBinding
);
2506 DPRINT("PNP_HwProfFlags() called\n");
2511 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2516 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2520 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2524 &hKey
) != ERROR_SUCCESS
)
2525 return CR_REGISTRY_ERROR
;
2527 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2529 if (RegOpenKeyExW(hKey
,
2533 &hDeviceKey
) != ERROR_SUCCESS
)
2539 dwSize
= sizeof(DWORD
);
2540 if (RegQueryValueExW(hDeviceKey
,
2545 &dwSize
) != ERROR_SUCCESS
)
2550 RegCloseKey(hDeviceKey
);
2553 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2555 /* FIXME: not implemented yet */
2556 ret
= CR_CALL_NOT_IMPLEMENTED
;
2571 HWPROFILEINFO
*pHWProfileInfo
,
2572 DWORD ulProfileInfoSize
,
2575 WCHAR szProfileName
[5];
2576 HKEY hKeyConfig
= NULL
;
2577 HKEY hKeyProfiles
= NULL
;
2578 HKEY hKeyProfile
= NULL
;
2579 DWORD dwDisposition
;
2582 CONFIGRET ret
= CR_SUCCESS
;
2584 UNREFERENCED_PARAMETER(hBinding
);
2586 DPRINT("PNP_GetHwProfInfo() called\n");
2588 if (ulProfileInfoSize
== 0)
2590 ret
= CR_INVALID_DATA
;
2596 ret
= CR_INVALID_FLAG
;
2600 /* Initialize the profile information */
2601 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2602 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2603 pHWProfileInfo
->HWPI_dwFlags
= 0;
2605 /* Open the 'IDConfigDB' key */
2606 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2607 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2610 REG_OPTION_NON_VOLATILE
,
2615 if (lError
!= ERROR_SUCCESS
)
2617 ret
= CR_REGISTRY_ERROR
;
2621 /* Open the 'Hardware Profiles' subkey */
2622 lError
= RegCreateKeyExW(hKeyConfig
,
2623 L
"Hardware Profiles",
2626 REG_OPTION_NON_VOLATILE
,
2627 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2631 if (lError
!= ERROR_SUCCESS
)
2633 ret
= CR_REGISTRY_ERROR
;
2637 if (ulIndex
== (ULONG
)-1)
2639 dwSize
= sizeof(ULONG
);
2640 lError
= RegQueryValueExW(hKeyConfig
,
2644 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2646 if (lError
!= ERROR_SUCCESS
)
2648 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2649 ret
= CR_REGISTRY_ERROR
;
2655 /* FIXME: not implemented yet */
2656 ret
= CR_CALL_NOT_IMPLEMENTED
;
2660 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2662 lError
= RegOpenKeyExW(hKeyProfiles
,
2667 if (lError
!= ERROR_SUCCESS
)
2669 ret
= CR_REGISTRY_ERROR
;
2673 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2674 lError
= RegQueryValueExW(hKeyProfile
,
2678 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2680 if (lError
!= ERROR_SUCCESS
)
2682 ret
= CR_REGISTRY_ERROR
;
2687 if (hKeyProfile
!= NULL
)
2688 RegCloseKey(hKeyProfile
);
2690 if (hKeyProfiles
!= NULL
)
2691 RegCloseKey(hKeyProfiles
);
2693 if (hKeyConfig
!= NULL
)
2694 RegCloseKey(hKeyConfig
);
2703 PNP_AddEmptyLogConf(
2707 DWORD
*pulLogConfTag
,
2711 return CR_CALL_NOT_IMPLEMENTED
;
2721 DWORD ulLogConfType
,
2726 return CR_CALL_NOT_IMPLEMENTED
;
2733 PNP_GetFirstLogConf(
2736 DWORD ulLogConfType
,
2737 DWORD
*pulLogConfTag
,
2741 return CR_CALL_NOT_IMPLEMENTED
;
2751 DWORD ulLogConfType
,
2757 return CR_CALL_NOT_IMPLEMENTED
;
2764 PNP_GetLogConfPriority(
2773 return CR_CALL_NOT_IMPLEMENTED
;
2784 DWORD ulLogConfType
,
2785 RESOURCEID ResourceID
,
2786 DWORD
*pulResourceTag
,
2788 PNP_RPC_BUFFER_SIZE ResourceLen
,
2792 return CR_CALL_NOT_IMPLEMENTED
;
2803 DWORD ulLogConfType
,
2804 RESOURCEID ResourceID
,
2805 DWORD ulResourceTag
,
2806 DWORD
*pulPreviousResType
,
2807 DWORD
*pulPreviousResTag
,
2811 return CR_CALL_NOT_IMPLEMENTED
;
2822 DWORD ulLogConfType
,
2823 RESOURCEID ResourceID
,
2824 DWORD ulResourceTag
,
2825 DWORD
*pulNextResType
,
2826 DWORD
*pulNextResTag
,
2830 return CR_CALL_NOT_IMPLEMENTED
;
2841 DWORD ulLogConfType
,
2842 RESOURCEID ResourceID
,
2843 DWORD ulResourceTag
,
2845 PNP_RPC_BUFFER_SIZE BufferLen
,
2849 return CR_CALL_NOT_IMPLEMENTED
;
2856 PNP_GetResDesDataSize(
2860 DWORD ulLogConfType
,
2861 RESOURCEID ResourceID
,
2862 DWORD ulResourceTag
,
2867 return CR_CALL_NOT_IMPLEMENTED
;
2878 DWORD ulLogConfType
,
2879 RESOURCEID CurrentResourceID
,
2880 RESOURCEID NewResourceID
,
2881 DWORD ulResourceTag
,
2883 PNP_RPC_BUFFER_SIZE ResourceLen
,
2887 return CR_CALL_NOT_IMPLEMENTED
;
2894 PNP_DetectResourceConflict(
2897 RESOURCEID ResourceID
,
2899 PNP_RPC_BUFFER_SIZE ResourceLen
,
2900 BOOL
*pbConflictDetected
,
2903 DPRINT("PNP_DetectResourceConflict()\n");
2905 if (pbConflictDetected
!= NULL
)
2906 *pbConflictDetected
= FALSE
;
2908 return CR_CALL_NOT_IMPLEMENTED
;
2915 PNP_QueryResConfList(
2918 RESOURCEID ResourceID
,
2920 PNP_RPC_BUFFER_SIZE ResourceLen
,
2922 PNP_RPC_BUFFER_SIZE BufferLen
,
2926 return CR_CALL_NOT_IMPLEMENTED
;
2935 DWORD ulHardwareProfile
,
2939 return CR_CALL_NOT_IMPLEMENTED
;
2946 PNP_QueryArbitratorFreeData(
2951 RESOURCEID ResourceID
,
2955 return CR_CALL_NOT_IMPLEMENTED
;
2962 PNP_QueryArbitratorFreeSize(
2966 RESOURCEID ResourceID
,
2970 return CR_CALL_NOT_IMPLEMENTED
;
2981 return CR_CALL_NOT_IMPLEMENTED
;
2988 PNP_RegisterNotification(
2994 PNOTIFY_DATA pNotifyData
;
2997 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
2998 hBinding
, ulFlags
, pulNotify
);
3001 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
3002 if (pNotifyData
== NULL
)
3003 return CR_OUT_OF_MEMORY
;
3005 *pulNotify
= (DWORD
)pNotifyData
;
3017 PNP_UnregisterNotification(
3021 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
3022 hBinding
, ulNotify
);
3026 return CR_CALL_NOT_IMPLEMENTED
;
3036 PNP_GetCustomDevProp(
3039 LPWSTR CustomPropName
,
3040 DWORD
*pulRegDataType
,
3042 PNP_RPC_STRING_LEN
*pulTransferLen
,
3043 PNP_RPC_STRING_LEN
*pulLength
,
3046 HKEY hDeviceKey
= NULL
;
3047 HKEY hParamKey
= NULL
;
3049 CONFIGRET ret
= CR_SUCCESS
;
3051 UNREFERENCED_PARAMETER(hBinding
);
3053 DPRINT("PNP_GetCustomDevProp() called\n");
3055 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
3057 ret
= CR_INVALID_POINTER
;
3061 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
3063 ret
= CR_INVALID_FLAG
;
3067 if (*pulLength
< *pulTransferLen
)
3068 *pulLength
= *pulTransferLen
;
3070 *pulTransferLen
= 0;
3072 lError
= RegOpenKeyExW(hEnumKey
,
3077 if (lError
!= ERROR_SUCCESS
)
3079 ret
= CR_REGISTRY_ERROR
;
3083 lError
= RegOpenKeyExW(hDeviceKey
,
3084 L
"Device Parameters",
3088 if (lError
!= ERROR_SUCCESS
)
3090 ret
= CR_REGISTRY_ERROR
;
3094 lError
= RegQueryValueExW(hParamKey
,
3100 if (lError
!= ERROR_SUCCESS
)
3102 if (lError
== ERROR_MORE_DATA
)
3104 ret
= CR_BUFFER_SMALL
;
3109 ret
= CR_NO_SUCH_VALUE
;
3114 if (ret
== CR_SUCCESS
)
3115 *pulTransferLen
= *pulLength
;
3117 if (hParamKey
!= NULL
)
3118 RegCloseKey(hParamKey
);
3120 if (hDeviceKey
!= NULL
)
3121 RegCloseKey(hDeviceKey
);
3123 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3132 PNP_GetVersionInternal(
3136 UNREFERENCED_PARAMETER(hBinding
);
3146 PNP_GetBlockedDriverInfo(
3149 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3150 PNP_RPC_BUFFER_SIZE
*pulLength
,
3154 return CR_CALL_NOT_IMPLEMENTED
;
3161 PNP_GetServerSideDeviceInstallFlags(
3163 DWORD
*pulSSDIFlags
,
3166 UNREFERENCED_PARAMETER(hBinding
);
3168 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
3169 hBinding
, pulSSDIFlags
, ulFlags
);
3171 if (pulSSDIFlags
== NULL
)
3172 return CR_INVALID_POINTER
;
3175 return CR_INVALID_FLAG
;
3187 PNP_GetObjectPropKeys(
3191 LPWSTR PropertyCultureName
,
3192 PNP_PROP_COUNT
*PropertyCount
,
3193 PNP_PROP_COUNT
*TransferLen
,
3194 DEVPROPKEY
*PropertyKeys
,
3198 return CR_CALL_NOT_IMPLEMENTED
;
3209 LPWSTR PropertyCultureName
,
3210 const DEVPROPKEY
*PropertyKey
,
3211 DEVPROPTYPE
*PropertyType
,
3212 PNP_PROP_SIZE
*PropertySize
,
3213 PNP_PROP_SIZE
*TransferLen
,
3214 BYTE
*PropertyBuffer
,
3218 return CR_CALL_NOT_IMPLEMENTED
;
3229 LPWSTR PropertyCultureName
,
3230 const DEVPROPKEY
*PropertyKey
,
3231 DEVPROPTYPE PropertyType
,
3232 PNP_PROP_SIZE PropertySize
,
3233 BYTE
*PropertyBuffer
,
3237 return CR_CALL_NOT_IMPLEMENTED
;
3248 return CR_CALL_NOT_IMPLEMENTED
;
3255 PNP_ApplyPowerSettings(
3259 return CR_CALL_NOT_IMPLEMENTED
;
3266 PNP_DriverStoreAddDriverPackage(
3270 return CR_CALL_NOT_IMPLEMENTED
;
3277 PNP_DriverStoreDeleteDriverPackage(
3281 return CR_CALL_NOT_IMPLEMENTED
;
3288 PNP_RegisterServiceNotification(
3292 return CR_CALL_NOT_IMPLEMENTED
;
3299 PNP_SetActiveService(
3305 return CR_CALL_NOT_IMPLEMENTED
;
3312 PNP_DeleteServiceDevices(
3316 return CR_CALL_NOT_IMPLEMENTED
;
3321 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3323 BOOL DeviceInstalled
= FALSE
;
3326 HANDLE hInstallEvent
;
3327 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3328 LPVOID Environment
= NULL
;
3329 PROCESS_INFORMATION ProcessInfo
;
3330 STARTUPINFOW StartupInfo
;
3334 /* The following lengths are constant (see below), they cannot overflow */
3335 WCHAR CommandLine
[116];
3336 WCHAR InstallEventName
[73];
3338 WCHAR UuidString
[39];
3340 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3342 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3344 if (RegOpenKeyExW(hEnumKey
,
3348 &DeviceKey
) == ERROR_SUCCESS
)
3350 if (RegQueryValueExW(DeviceKey
,
3355 NULL
) == ERROR_SUCCESS
)
3357 DPRINT("No need to install: %S\n", DeviceInstance
);
3358 RegCloseKey(DeviceKey
);
3362 BytesWritten
= sizeof(DWORD
);
3363 if (RegQueryValueExW(DeviceKey
,
3368 &BytesWritten
) == ERROR_SUCCESS
)
3370 if (Value
& CONFIGFLAG_FAILEDINSTALL
)
3372 DPRINT("No need to install: %S\n", DeviceInstance
);
3373 RegCloseKey(DeviceKey
);
3378 RegCloseKey(DeviceKey
);
3381 DPRINT1("Installing: %S\n", DeviceInstance
);
3383 /* Create a random UUID for the named pipe & event*/
3384 UuidCreate(&RandomUuid
);
3385 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3386 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3387 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3388 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3389 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3391 /* Create the event */
3392 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3393 wcscat(InstallEventName
, UuidString
);
3394 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3397 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3401 /* Create the named pipe */
3402 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3403 wcscat(PipeName
, UuidString
);
3404 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3405 if (hPipe
== INVALID_HANDLE_VALUE
)
3407 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3411 /* Launch rundll32 to call ClientSideInstallW */
3412 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3413 wcscat(CommandLine
, PipeName
);
3415 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3416 StartupInfo
.cb
= sizeof(StartupInfo
);
3420 /* newdev has to run under the environment of the current user */
3421 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3423 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3427 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3429 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3435 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3437 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3438 (ShowWizard is only set to FALSE for these two modes) */
3439 ASSERT(!ShowWizard
);
3441 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3443 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3448 /* Wait for the function to connect to our pipe */
3449 if (!ConnectNamedPipe(hPipe
, NULL
))
3451 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3453 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3458 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3459 Value
= sizeof(InstallEventName
);
3460 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3461 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3463 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3464 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3465 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3467 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3468 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3469 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3471 /* Wait for newdev.dll to finish processing */
3472 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3474 /* If the event got signalled, this is success */
3475 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3479 CloseHandle(hInstallEvent
);
3481 if (hPipe
!= INVALID_HANDLE_VALUE
)
3485 DestroyEnvironmentBlock(Environment
);
3487 if (ProcessInfo
.hProcess
)
3488 CloseHandle(ProcessInfo
.hProcess
);
3490 if (ProcessInfo
.hThread
)
3491 CloseHandle(ProcessInfo
.hThread
);
3493 if (!DeviceInstalled
)
3495 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3498 return DeviceInstalled
;
3514 return ERROR_INVALID_PARAMETER
;
3517 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3518 if (rc
!= ERROR_SUCCESS
)
3520 if (dwType
!= REG_SZ
)
3521 return ERROR_FILE_NOT_FOUND
;
3522 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3524 return ERROR_NOT_ENOUGH_MEMORY
;
3525 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3526 if (rc
!= ERROR_SUCCESS
)
3528 HeapFree(GetProcessHeap(), 0, Value
);
3531 /* NULL-terminate the string */
3532 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3535 return ERROR_SUCCESS
;
3543 DWORD regType
, active
, size
;
3547 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3548 if (rc
!= ERROR_SUCCESS
)
3551 size
= sizeof(DWORD
);
3552 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3553 if (rc
!= ERROR_SUCCESS
)
3555 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3558 ret
= (active
!= 0);
3564 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3573 HKEY ControlKey
= NULL
;
3574 LPWSTR SystemStartOptions
= NULL
;
3575 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3576 BOOL ConsoleBoot
= FALSE
;
3581 L
"SYSTEM\\CurrentControlSet\\Control",
3586 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3587 if (rc
!= ERROR_SUCCESS
)
3590 /* Check for CONSOLE switch in SystemStartOptions */
3591 CurrentOption
= SystemStartOptions
;
3592 while (CurrentOption
)
3594 NextOption
= wcschr(CurrentOption
, L
' ');
3596 *NextOption
= L
'\0';
3597 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3599 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3603 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3607 if (ControlKey
!= NULL
)
3608 RegCloseKey(ControlKey
);
3609 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3614 /* Loop to install all queued devices installations */
3616 DeviceInstallThread(LPVOID lpParameter
)
3618 PSLIST_ENTRY ListEntry
;
3619 DeviceInstallParams
* Params
;
3622 UNREFERENCED_PARAMETER(lpParameter
);
3624 WaitForSingleObject(hInstallEvent
, INFINITE
);
3626 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3630 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3632 if (ListEntry
== NULL
)
3634 SetEvent(hNoPendingInstalls
);
3635 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3639 ResetEvent(hNoPendingInstalls
);
3640 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3641 InstallDevice(Params
->DeviceIds
, showWizard
);
3642 HeapFree(GetProcessHeap(), 0, Params
);
3651 PnpEventThread(LPVOID lpParameter
)
3653 DWORD dwRet
= ERROR_SUCCESS
;
3655 RPC_STATUS RpcStatus
;
3656 PPLUGPLAY_EVENT_BLOCK PnpEvent
, NewPnpEvent
;
3659 UNREFERENCED_PARAMETER(lpParameter
);
3661 PnpEventSize
= 0x1000;
3662 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3663 if (PnpEvent
== NULL
)
3664 return ERROR_OUTOFMEMORY
;
3668 DPRINT("Calling NtGetPlugPlayEvent()\n");
3670 /* Wait for the next PnP event */
3671 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3673 /* Resize the buffer for the PnP event if it's too small */
3674 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3676 PnpEventSize
+= 0x400;
3677 NewPnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
3678 if (NewPnpEvent
== NULL
)
3680 dwRet
= ERROR_OUTOFMEMORY
;
3683 PnpEvent
= NewPnpEvent
;
3687 if (!NT_SUCCESS(Status
))
3689 DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status
);
3693 /* Process the PnP event */
3694 DPRINT("Received PnP Event\n");
3695 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3697 DeviceInstallParams
* Params
;
3699 DWORD DeviceIdLength
;
3701 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3703 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3706 /* Queue device install (will be dequeued by DeviceInstallThread) */
3707 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3708 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3711 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3712 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3713 SetEvent(hDeviceInstallListNotEmpty
);
3717 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3719 // DWORD dwRecipient;
3721 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3723 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3724 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3727 // DBT_DEVNODES_CHANGED,
3729 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3731 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3733 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3735 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3737 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3739 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3741 // DWORD dwRecipient;
3743 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3745 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3746 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3749 // DBT_DEVNODES_CHANGED,
3751 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3753 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3755 // DWORD dwRecipient;
3757 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3759 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3760 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3763 // DBT_DEVNODES_CHANGED,
3765 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3767 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3769 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3771 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3773 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3777 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3778 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3779 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3780 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3781 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3784 /* Dequeue the current PnP event and signal the next one */
3785 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3788 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3795 UpdateServiceStatus(DWORD dwState
)
3797 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3798 ServiceStatus
.dwCurrentState
= dwState
;
3799 ServiceStatus
.dwControlsAccepted
= 0;
3800 ServiceStatus
.dwWin32ExitCode
= 0;
3801 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3802 ServiceStatus
.dwCheckPoint
= 0;
3804 if (dwState
== SERVICE_START_PENDING
||
3805 dwState
== SERVICE_STOP_PENDING
||
3806 dwState
== SERVICE_PAUSE_PENDING
||
3807 dwState
== SERVICE_CONTINUE_PENDING
)
3808 ServiceStatus
.dwWaitHint
= 10000;
3810 ServiceStatus
.dwWaitHint
= 0;
3812 SetServiceStatus(ServiceStatusHandle
,
3818 ServiceControlHandler(DWORD dwControl
,
3823 DPRINT1("ServiceControlHandler() called\n");
3827 case SERVICE_CONTROL_STOP
:
3828 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3829 /* Stop listening to RPC Messages */
3830 RpcMgmtStopServerListening(NULL
);
3831 UpdateServiceStatus(SERVICE_STOPPED
);
3832 return ERROR_SUCCESS
;
3834 case SERVICE_CONTROL_PAUSE
:
3835 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3836 UpdateServiceStatus(SERVICE_PAUSED
);
3837 return ERROR_SUCCESS
;
3839 case SERVICE_CONTROL_CONTINUE
:
3840 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3841 UpdateServiceStatus(SERVICE_RUNNING
);
3842 return ERROR_SUCCESS
;
3844 case SERVICE_CONTROL_INTERROGATE
:
3845 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3846 SetServiceStatus(ServiceStatusHandle
,
3848 return ERROR_SUCCESS
;
3850 case SERVICE_CONTROL_SHUTDOWN
:
3851 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3852 /* Stop listening to RPC Messages */
3853 RpcMgmtStopServerListening(NULL
);
3854 UpdateServiceStatus(SERVICE_STOPPED
);
3855 return ERROR_SUCCESS
;
3858 DPRINT1(" Control %lu received\n", dwControl
);
3859 return ERROR_CALL_NOT_IMPLEMENTED
;
3865 ServiceMain(DWORD argc
, LPTSTR
*argv
)
3870 UNREFERENCED_PARAMETER(argc
);
3871 UNREFERENCED_PARAMETER(argv
);
3873 DPRINT("ServiceMain() called\n");
3875 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
3876 ServiceControlHandler
,
3878 if (!ServiceStatusHandle
)
3880 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
3884 UpdateServiceStatus(SERVICE_START_PENDING
);
3886 hThread
= CreateThread(NULL
,
3892 if (hThread
!= NULL
)
3893 CloseHandle(hThread
);
3895 hThread
= CreateThread(NULL
,
3901 if (hThread
!= NULL
)
3902 CloseHandle(hThread
);
3904 hThread
= CreateThread(NULL
,
3906 DeviceInstallThread
,
3910 if (hThread
!= NULL
)
3911 CloseHandle(hThread
);
3913 UpdateServiceStatus(SERVICE_RUNNING
);
3915 DPRINT("ServiceMain() done\n");
3919 InitializePnPManager(VOID
)
3924 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
3926 /* We need this privilege for using CreateProcessAsUserW */
3927 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
3929 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
3930 if (hInstallEvent
== NULL
)
3932 dwError
= GetLastError();
3933 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
3937 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
3938 if (hDeviceInstallListNotEmpty
== NULL
)
3940 dwError
= GetLastError();
3941 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3945 hNoPendingInstalls
= CreateEventW(NULL
,
3948 L
"Global\\PnP_No_Pending_Install_Events");
3949 if (hNoPendingInstalls
== NULL
)
3951 dwError
= GetLastError();
3952 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
3956 InitializeSListHead(&DeviceInstallListHead
);
3958 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3959 L
"System\\CurrentControlSet\\Enum",
3963 if (dwError
!= ERROR_SUCCESS
)
3965 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
3969 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
3970 L
"System\\CurrentControlSet\\Control\\Class",
3974 if (dwError
!= ERROR_SUCCESS
)
3976 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
3980 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
3986 DllMain(HINSTANCE hinstDLL
,
3992 case DLL_PROCESS_ATTACH
:
3993 DisableThreadLibraryCalls(hinstDLL
);
3994 InitializePnPManager();
3997 case DLL_PROCESS_DETACH
: