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 /* Open the device key */
548 dwError
= RegOpenKeyExW(hEnumKey
,
551 KEY_ENUMERATE_SUB_KEYS
,
553 if (dwError
!= ERROR_SUCCESS
)
555 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
556 return CR_REGISTRY_ERROR
;
562 for (dwIndex
= 0; ; dwIndex
++)
564 dwInstanceLength
= MAX_DEVICE_ID_LEN
;
565 dwError
= RegEnumKeyExW(hDeviceKey
,
573 if (dwError
!= ERROR_SUCCESS
)
576 wsprintf(szPathBuffer
, L
"%s\\%s", pszDevice
, szInstanceBuffer
);
577 DPRINT("Path: %S\n", szPathBuffer
);
579 dwPathLength
= wcslen(szPathBuffer
) + 1;
580 if (dwUsedLength
+ dwPathLength
+ 1 > *pulLength
)
582 ret
= CR_BUFFER_SMALL
;
586 wcscpy(pPtr
, szPathBuffer
);
587 dwUsedLength
+= dwPathLength
;
588 pPtr
+= dwPathLength
;
590 *pPtr
= UNICODE_NULL
;
593 RegCloseKey(hDeviceKey
);
595 if (ret
== CR_SUCCESS
)
596 *pulLength
= dwUsedLength
+ 1;
605 GetEnumeratorInstanceList(
606 _In_ PWSTR pszEnumerator
,
607 _Inout_ PWSTR pszBuffer
,
608 _Inout_ PDWORD pulLength
)
610 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
611 WCHAR szPathBuffer
[512];
614 DWORD dwIndex
, dwDeviceLength
, dwUsedLength
, dwRemainingLength
, dwPathLength
;
616 CONFIGRET ret
= CR_SUCCESS
;
618 /* Open the enumerator key */
619 dwError
= RegOpenKeyExW(hEnumKey
,
622 KEY_ENUMERATE_SUB_KEYS
,
624 if (dwError
!= ERROR_SUCCESS
)
626 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
627 return CR_REGISTRY_ERROR
;
631 dwRemainingLength
= *pulLength
;
634 for (dwIndex
= 0; ; dwIndex
++)
636 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
637 dwError
= RegEnumKeyExW(hEnumeratorKey
,
645 if (dwError
!= ERROR_SUCCESS
)
648 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
649 DPRINT("Path: %S\n", szPathBuffer
);
651 dwPathLength
= dwRemainingLength
;
652 ret
= GetDeviceInstanceList(szPathBuffer
,
655 if (ret
!= CR_SUCCESS
)
658 dwUsedLength
+= dwPathLength
- 1;
659 dwRemainingLength
+= dwPathLength
- 1;
660 pPtr
+= dwPathLength
- 1;
663 RegCloseKey(hEnumeratorKey
);
665 if (ret
== CR_SUCCESS
)
666 *pulLength
= dwUsedLength
+ 1;
681 PNP_RPC_STRING_LEN
*pulLength
,
684 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
685 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
686 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
687 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
688 CONFIGRET ret
= CR_SUCCESS
;
691 DPRINT("PNP_GetDeviceList() called\n");
693 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
694 return CR_INVALID_FLAG
;
696 if (pulLength
== NULL
)
697 return CR_INVALID_POINTER
;
699 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
701 return CR_INVALID_POINTER
;
704 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
705 CM_GETIDLIST_FILTER_POWERRELATIONS
|
706 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
707 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
709 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
711 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
713 PlugPlayData
.Relations
= 3;
715 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
717 PlugPlayData
.Relations
= 2;
719 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
721 PlugPlayData
.Relations
= 1;
723 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
725 PlugPlayData
.Relations
= 0;
728 PlugPlayData
.BufferSize
= *pulLength
* sizeof(WCHAR
);
729 PlugPlayData
.Buffer
= Buffer
;
731 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
732 (PVOID
)&PlugPlayData
,
733 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
734 if (NT_SUCCESS(Status
))
736 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
740 ret
= NtStatusToCrError(Status
);
743 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
745 ret
= CR_CALL_NOT_IMPLEMENTED
;
747 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
749 SplitDeviceInstanceID(pszFilter
,
754 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
756 ret
= GetDeviceInstanceList(pszFilter
,
762 ret
= GetEnumeratorInstanceList(pszFilter
,
767 else /* CM_GETIDLIST_FILTER_NONE */
769 ret
= CR_CALL_NOT_IMPLEMENTED
;
778 GetDeviceInstanceListSize(
779 _In_ LPCWSTR pszDevice
,
780 _Out_ PULONG pulLength
)
783 DWORD dwSubKeys
, dwMaxSubKeyLength
;
786 /* Open the device key */
787 dwError
= RegOpenKeyExW(hEnumKey
,
792 if (dwError
!= ERROR_SUCCESS
)
794 DPRINT("Failed to open the device key (Error %lu)\n", dwError
);
795 return CR_REGISTRY_ERROR
;
798 /* Retrieve the number of device instances and the maximum name length */
799 dwError
= RegQueryInfoKeyW(hDeviceKey
,
811 if (dwError
!= ERROR_SUCCESS
)
813 DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError
);
815 dwMaxSubKeyLength
= 0;
818 /* Close the device key */
819 RegCloseKey(hDeviceKey
);
821 /* Return the largest possible buffer size */
822 *pulLength
= dwSubKeys
* (wcslen(pszDevice
) + 1 + dwMaxSubKeyLength
+ 1);
830 GetEnumeratorInstanceListSize(
831 _In_ LPCWSTR pszEnumerator
,
832 _Out_ PULONG pulLength
)
834 WCHAR szDeviceBuffer
[MAX_DEVICE_ID_LEN
];
835 WCHAR szPathBuffer
[512];
837 DWORD dwIndex
, dwDeviceLength
, dwBufferLength
;
839 CONFIGRET ret
= CR_SUCCESS
;
843 /* Open the enumerator key */
844 dwError
= RegOpenKeyExW(hEnumKey
,
847 KEY_ENUMERATE_SUB_KEYS
,
849 if (dwError
!= ERROR_SUCCESS
)
851 DPRINT("Failed to open the enumerator key (Error %lu)\n", dwError
);
852 return CR_REGISTRY_ERROR
;
855 for (dwIndex
= 0; ; dwIndex
++)
857 dwDeviceLength
= MAX_DEVICE_ID_LEN
;
858 dwError
= RegEnumKeyExW(hEnumeratorKey
,
866 if (dwError
!= ERROR_SUCCESS
)
869 wsprintf(szPathBuffer
, L
"%s\\%s", pszEnumerator
, szDeviceBuffer
);
870 DPRINT("Path: %S\n", szPathBuffer
);
872 ret
= GetDeviceInstanceListSize(szPathBuffer
, &dwBufferLength
);
873 if (ret
!= CR_SUCCESS
)
879 *pulLength
+= dwBufferLength
;
882 /* Close the enumerator key */
883 RegCloseKey(hEnumeratorKey
);
892 PNP_GetDeviceListSize(
895 PNP_RPC_BUFFER_SIZE
*pulLength
,
898 PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData
;
899 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
900 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
901 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
902 CONFIGRET ret
= CR_SUCCESS
;
905 DPRINT("PNP_GetDeviceListSize() called\n");
907 if (ulFlags
& ~CM_GETIDLIST_FILTER_BITS
)
908 return CR_INVALID_FLAG
;
910 if (pulLength
== NULL
)
911 return CR_INVALID_POINTER
;
913 if ((ulFlags
!= CM_GETIDLIST_FILTER_NONE
) &&
915 return CR_INVALID_POINTER
;
920 (CM_GETIDLIST_FILTER_BUSRELATIONS
|
921 CM_GETIDLIST_FILTER_POWERRELATIONS
|
922 CM_GETIDLIST_FILTER_REMOVALRELATIONS
|
923 CM_GETIDLIST_FILTER_EJECTRELATIONS
))
925 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
927 if (ulFlags
& CM_GETIDLIST_FILTER_BUSRELATIONS
)
929 PlugPlayData
.Relations
= 3;
931 else if (ulFlags
& CM_GETIDLIST_FILTER_POWERRELATIONS
)
933 PlugPlayData
.Relations
= 2;
935 else if (ulFlags
& CM_GETIDLIST_FILTER_REMOVALRELATIONS
)
937 PlugPlayData
.Relations
= 1;
939 else if (ulFlags
& CM_GETIDLIST_FILTER_EJECTRELATIONS
)
941 PlugPlayData
.Relations
= 0;
944 PlugPlayData
.BufferSize
= 0;
945 PlugPlayData
.Buffer
= NULL
;
947 Status
= NtPlugPlayControl(PlugPlayControlQueryDeviceRelations
,
948 (PVOID
)&PlugPlayData
,
949 sizeof(PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
));
950 if (NT_SUCCESS(Status
))
952 *pulLength
= PlugPlayData
.BufferSize
/ sizeof(WCHAR
);
956 ret
= NtStatusToCrError(Status
);
959 else if (ulFlags
& CM_GETIDLIST_FILTER_SERVICE
)
961 ret
= CR_CALL_NOT_IMPLEMENTED
;
963 else if (ulFlags
& CM_GETIDLIST_FILTER_ENUMERATOR
)
965 SplitDeviceInstanceID(pszFilter
,
970 if (*szEnumerator
!= UNICODE_NULL
&& *szDevice
!= UNICODE_NULL
)
972 ret
= GetDeviceInstanceListSize(pszFilter
,
977 ret
= GetEnumeratorInstanceListSize(pszFilter
,
981 else /* CM_GETIDLIST_FILTER_NONE */
983 ret
= CR_CALL_NOT_IMPLEMENTED
;
986 /* Add one character for the terminating double UNICODE_NULL */
987 if (ret
== CR_SUCCESS
)
1003 PLUGPLAY_CONTROL_DEPTH_DATA PlugPlayData
;
1004 CONFIGRET ret
= CR_SUCCESS
;
1007 UNREFERENCED_PARAMETER(hBinding
);
1008 UNREFERENCED_PARAMETER(ulFlags
);
1010 DPRINT("PNP_GetDepth() called\n");
1012 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1015 Status
= NtPlugPlayControl(PlugPlayControlGetDeviceDepth
,
1016 (PVOID
)&PlugPlayData
,
1017 sizeof(PLUGPLAY_CONTROL_DEPTH_DATA
));
1018 if (NT_SUCCESS(Status
))
1020 *pulDepth
= PlugPlayData
.Depth
;
1024 ret
= NtStatusToCrError(Status
);
1027 DPRINT("PNP_GetDepth() done (returns %lx)\n", ret
);
1036 PNP_GetDeviceRegProp(
1040 DWORD
*pulRegDataType
,
1042 PNP_PROP_SIZE
*pulTransferLen
,
1043 PNP_PROP_SIZE
*pulLength
,
1046 PLUGPLAY_CONTROL_PROPERTY_DATA PlugPlayData
;
1047 CONFIGRET ret
= CR_SUCCESS
;
1048 LPWSTR lpValueName
= NULL
;
1053 UNREFERENCED_PARAMETER(hBinding
);
1055 DPRINT("PNP_GetDeviceRegProp() called\n");
1057 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1059 ret
= CR_INVALID_POINTER
;
1065 ret
= CR_INVALID_FLAG
;
1069 /* FIXME: Check pDeviceID */
1071 if (*pulLength
< *pulTransferLen
)
1072 *pulLength
= *pulTransferLen
;
1074 *pulTransferLen
= 0;
1078 case CM_DRP_DEVICEDESC
:
1079 lpValueName
= L
"DeviceDesc";
1082 case CM_DRP_HARDWAREID
:
1083 lpValueName
= L
"HardwareID";
1086 case CM_DRP_COMPATIBLEIDS
:
1087 lpValueName
= L
"CompatibleIDs";
1090 case CM_DRP_SERVICE
:
1091 lpValueName
= L
"Service";
1095 lpValueName
= L
"Class";
1098 case CM_DRP_CLASSGUID
:
1099 lpValueName
= L
"ClassGUID";
1103 lpValueName
= L
"Driver";
1106 case CM_DRP_CONFIGFLAGS
:
1107 lpValueName
= L
"ConfigFlags";
1111 lpValueName
= L
"Mfg";
1114 case CM_DRP_FRIENDLYNAME
:
1115 lpValueName
= L
"FriendlyName";
1118 case CM_DRP_LOCATION_INFORMATION
:
1119 lpValueName
= L
"LocationInformation";
1122 case CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME
:
1123 PlugPlayData
.Property
= PNP_PROPERTY_PHYSICAL_DEVICE_OBJECT_NAME
;
1126 case CM_DRP_CAPABILITIES
:
1127 lpValueName
= L
"Capabilities";
1130 case CM_DRP_UI_NUMBER
:
1131 PlugPlayData
.Property
= PNP_PROPERTY_UI_NUMBER
;
1134 case CM_DRP_UPPERFILTERS
:
1135 lpValueName
= L
"UpperFilters";
1138 case CM_DRP_LOWERFILTERS
:
1139 lpValueName
= L
"LowerFilters";
1142 case CM_DRP_BUSTYPEGUID
:
1143 PlugPlayData
.Property
= PNP_PROPERTY_BUSTYPEGUID
;
1146 case CM_DRP_LEGACYBUSTYPE
:
1147 PlugPlayData
.Property
= PNP_PROPERTY_LEGACYBUSTYPE
;
1150 case CM_DRP_BUSNUMBER
:
1151 PlugPlayData
.Property
= PNP_PROPERTY_BUSNUMBER
;
1154 case CM_DRP_ENUMERATOR_NAME
:
1155 PlugPlayData
.Property
= PNP_PROPERTY_ENUMERATOR_NAME
;
1158 case CM_DRP_SECURITY
:
1159 lpValueName
= L
"Security";
1162 case CM_DRP_DEVTYPE
:
1163 lpValueName
= L
"DeviceType";
1166 case CM_DRP_EXCLUSIVE
:
1167 lpValueName
= L
"Exclusive";
1170 case CM_DRP_CHARACTERISTICS
:
1171 lpValueName
= L
"DeviceCharacteristics";
1174 case CM_DRP_ADDRESS
:
1175 PlugPlayData
.Property
= PNP_PROPERTY_ADDRESS
;
1178 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1179 lpValueName
= L
"UINumberDescFormat";
1182 case CM_DRP_DEVICE_POWER_DATA
:
1183 PlugPlayData
.Property
= PNP_PROPERTY_POWER_DATA
;
1186 case CM_DRP_REMOVAL_POLICY
:
1187 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY
;
1190 case CM_DRP_REMOVAL_POLICY_HW_DEFAULT
:
1191 PlugPlayData
.Property
= PNP_PROPERTY_REMOVAL_POLICY_HARDWARE_DEFAULT
;
1194 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1195 lpValueName
= L
"RemovalPolicy";
1198 case CM_DRP_INSTALL_STATE
:
1199 PlugPlayData
.Property
= PNP_PROPERTY_INSTALL_STATE
;
1202 #if (WINVER >= _WIN32_WINNT_WS03)
1203 case CM_DRP_LOCATION_PATHS
:
1204 PlugPlayData
.Property
= PNP_PROPERTY_LOCATION_PATHS
;
1208 #if (WINVER >= _WIN32_WINNT_WIN7)
1209 case CM_DRP_BASE_CONTAINERID
:
1210 PlugPlayData
.Property
= PNP_PROPERTY_CONTAINERID
;
1215 ret
= CR_INVALID_PROPERTY
;
1219 DPRINT("Value name: %S\n", lpValueName
);
1223 /* Retrieve information from the Registry */
1224 lError
= RegOpenKeyExW(hEnumKey
,
1229 if (lError
!= ERROR_SUCCESS
)
1233 ret
= CR_INVALID_DEVNODE
;
1237 lError
= RegQueryValueExW(hKey
,
1243 if (lError
!= ERROR_SUCCESS
)
1245 if (lError
== ERROR_MORE_DATA
)
1247 ret
= CR_BUFFER_SMALL
;
1252 ret
= CR_NO_SUCH_VALUE
;
1258 /* Retrieve information from the Device Node */
1259 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1261 PlugPlayData
.Buffer
= Buffer
;
1262 PlugPlayData
.BufferSize
= *pulLength
;
1264 Status
= NtPlugPlayControl(PlugPlayControlProperty
,
1265 (PVOID
)&PlugPlayData
,
1266 sizeof(PLUGPLAY_CONTROL_PROPERTY_DATA
));
1267 if (NT_SUCCESS(Status
))
1269 *pulLength
= PlugPlayData
.BufferSize
;
1273 ret
= NtStatusToCrError(Status
);
1279 *pulTransferLen
= (ret
== CR_SUCCESS
) ? *pulLength
: 0;
1284 DPRINT("PNP_GetDeviceRegProp() done (returns %lx)\n", ret
);
1293 PNP_SetDeviceRegProp(
1299 PNP_PROP_SIZE ulLength
,
1302 CONFIGRET ret
= CR_SUCCESS
;
1303 LPWSTR lpValueName
= NULL
;
1306 UNREFERENCED_PARAMETER(hBinding
);
1307 UNREFERENCED_PARAMETER(ulFlags
);
1309 DPRINT("PNP_SetDeviceRegProp() called\n");
1311 DPRINT("DeviceId: %S\n", pDeviceId
);
1312 DPRINT("Property: %lu\n", ulProperty
);
1313 DPRINT("DataType: %lu\n", ulDataType
);
1314 DPRINT("Length: %lu\n", ulLength
);
1318 case CM_DRP_DEVICEDESC
:
1319 lpValueName
= L
"DeviceDesc";
1322 case CM_DRP_HARDWAREID
:
1323 lpValueName
= L
"HardwareID";
1326 case CM_DRP_COMPATIBLEIDS
:
1327 lpValueName
= L
"CompatibleIDs";
1330 case CM_DRP_SERVICE
:
1331 lpValueName
= L
"Service";
1335 lpValueName
= L
"Class";
1338 case CM_DRP_CLASSGUID
:
1339 lpValueName
= L
"ClassGUID";
1343 lpValueName
= L
"Driver";
1346 case CM_DRP_CONFIGFLAGS
:
1347 lpValueName
= L
"ConfigFlags";
1351 lpValueName
= L
"Mfg";
1354 case CM_DRP_FRIENDLYNAME
:
1355 lpValueName
= L
"FriendlyName";
1358 case CM_DRP_LOCATION_INFORMATION
:
1359 lpValueName
= L
"LocationInformation";
1362 case CM_DRP_UPPERFILTERS
:
1363 lpValueName
= L
"UpperFilters";
1366 case CM_DRP_LOWERFILTERS
:
1367 lpValueName
= L
"LowerFilters";
1370 case CM_DRP_SECURITY
:
1371 lpValueName
= L
"Security";
1374 case CM_DRP_DEVTYPE
:
1375 lpValueName
= L
"DeviceType";
1378 case CM_DRP_EXCLUSIVE
:
1379 lpValueName
= L
"Exclusive";
1382 case CM_DRP_CHARACTERISTICS
:
1383 lpValueName
= L
"DeviceCharacteristics";
1386 case CM_DRP_UI_NUMBER_DESC_FORMAT
:
1387 lpValueName
= L
"UINumberDescFormat";
1390 case CM_DRP_REMOVAL_POLICY_OVERRIDE
:
1391 lpValueName
= L
"RemovalPolicy";
1395 return CR_INVALID_PROPERTY
;
1398 DPRINT("Value name: %S\n", lpValueName
);
1400 if (RegOpenKeyExW(hEnumKey
,
1405 return CR_INVALID_DEVNODE
;
1409 if (RegDeleteValueW(hKey
,
1411 ret
= CR_REGISTRY_ERROR
;
1415 if (RegSetValueExW(hKey
,
1421 ret
= CR_REGISTRY_ERROR
;
1426 DPRINT("PNP_SetDeviceRegProp() done (returns %lx)\n", ret
);
1435 PNP_GetClassInstance(
1438 LPWSTR pszClassInstance
,
1439 PNP_RPC_STRING_LEN ulLength
)
1442 return CR_CALL_NOT_IMPLEMENTED
;
1457 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
1466 return CR_REGISTRY_ERROR
;
1468 /* FIXME: Set security key */
1479 PNP_DeleteRegistryKey(
1482 LPWSTR pszParentKey
,
1487 return CR_CALL_NOT_IMPLEMENTED
;
1496 DWORD
*pulClassCount
,
1502 UNREFERENCED_PARAMETER(hBinding
);
1503 UNREFERENCED_PARAMETER(ulFlags
);
1505 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1510 if (dwError
!= ERROR_SUCCESS
)
1511 return CR_INVALID_DATA
;
1513 dwError
= RegQueryInfoKeyW(hKey
,
1526 if (dwError
!= ERROR_SUCCESS
)
1527 return CR_INVALID_DATA
;
1538 LPWSTR pszClassGuid
,
1540 PNP_RPC_STRING_LEN
*pulLength
,
1543 WCHAR szKeyName
[MAX_PATH
];
1544 CONFIGRET ret
= CR_SUCCESS
;
1548 UNREFERENCED_PARAMETER(hBinding
);
1549 UNREFERENCED_PARAMETER(ulFlags
);
1551 DPRINT("PNP_GetClassName() called\n");
1553 lstrcpyW(szKeyName
, L
"System\\CurrentControlSet\\Control\\Class\\");
1554 if (lstrlenW(pszClassGuid
) + 1 < sizeof(szKeyName
)/sizeof(WCHAR
)-(lstrlenW(szKeyName
) * sizeof(WCHAR
)))
1555 lstrcatW(szKeyName
, pszClassGuid
);
1557 return CR_INVALID_DATA
;
1559 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
1564 return CR_REGISTRY_ERROR
;
1566 dwSize
= *pulLength
* sizeof(WCHAR
);
1567 if (RegQueryValueExW(hKey
,
1575 ret
= CR_REGISTRY_ERROR
;
1579 *pulLength
= dwSize
/ sizeof(WCHAR
);
1584 DPRINT("PNP_GetClassName() done (returns %lx)\n", ret
);
1595 LPWSTR pszClassGuid
,
1598 CONFIGRET ret
= CR_SUCCESS
;
1600 UNREFERENCED_PARAMETER(hBinding
);
1602 DPRINT("PNP_GetClassName(%S, %lx) called\n", pszClassGuid
, ulFlags
);
1604 if (ulFlags
& CM_DELETE_CLASS_SUBKEYS
)
1606 if (SHDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1607 ret
= CR_REGISTRY_ERROR
;
1611 if (RegDeleteKeyW(hClassKey
, pszClassGuid
) != ERROR_SUCCESS
)
1612 ret
= CR_REGISTRY_ERROR
;
1615 DPRINT("PNP_DeleteClassKey() done (returns %lx)\n", ret
);
1624 PNP_GetInterfaceDeviceAlias(
1626 LPWSTR pszInterfaceDevice
,
1627 GUID
*AliasInterfaceGuid
,
1628 LPWSTR pszAliasInterfaceDevice
,
1629 PNP_RPC_STRING_LEN
*pulLength
,
1630 PNP_RPC_STRING_LEN
*pulTransferLen
,
1634 return CR_CALL_NOT_IMPLEMENTED
;
1641 PNP_GetInterfaceDeviceList(
1643 GUID
*InterfaceGuid
,
1646 PNP_RPC_BUFFER_SIZE
*pulLength
,
1650 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1651 DWORD ret
= CR_SUCCESS
;
1653 UNREFERENCED_PARAMETER(hBinding
);
1655 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1658 PlugPlayData
.Flags
= ulFlags
;
1659 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1660 PlugPlayData
.Buffer
= Buffer
;
1661 PlugPlayData
.BufferSize
= *pulLength
;
1663 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1664 (PVOID
)&PlugPlayData
,
1665 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1666 if (NT_SUCCESS(Status
))
1668 *pulLength
= PlugPlayData
.BufferSize
;
1672 ret
= NtStatusToCrError(Status
);
1675 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1683 PNP_GetInterfaceDeviceListSize(
1685 PNP_RPC_BUFFER_SIZE
*pulLen
,
1686 GUID
*InterfaceGuid
,
1691 PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA PlugPlayData
;
1692 DWORD ret
= CR_SUCCESS
;
1694 UNREFERENCED_PARAMETER(hBinding
);
1696 DPRINT("PNP_GetInterfaceDeviceListSize() called\n");
1698 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
1701 PlugPlayData
.FilterGuid
= InterfaceGuid
;
1702 PlugPlayData
.Buffer
= NULL
;
1703 PlugPlayData
.BufferSize
= 0;
1704 PlugPlayData
.Flags
= ulFlags
;
1706 Status
= NtPlugPlayControl(PlugPlayControlGetInterfaceDeviceList
,
1707 (PVOID
)&PlugPlayData
,
1708 sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA
));
1709 if (NT_SUCCESS(Status
))
1711 *pulLen
= PlugPlayData
.BufferSize
;
1715 ret
= NtStatusToCrError(Status
);
1718 DPRINT("PNP_GetInterfaceDeviceListSize() done (returns %lx)\n", ret
);
1726 PNP_RegisterDeviceClassAssociation(
1729 GUID
*InterfaceGuid
,
1730 LPWSTR pszReference
,
1732 PNP_RPC_STRING_LEN
*pulLength
,
1733 PNP_RPC_STRING_LEN
*pulTransferLen
,
1737 return CR_CALL_NOT_IMPLEMENTED
;
1744 PNP_UnregisterDeviceClassAssociation(
1746 LPWSTR pszInterfaceDevice
,
1750 return CR_CALL_NOT_IMPLEMENTED
;
1757 PNP_GetClassRegProp(
1759 LPWSTR pszClassGuid
,
1761 DWORD
*pulRegDataType
,
1763 PNP_RPC_STRING_LEN
*pulTransferLen
,
1764 PNP_RPC_STRING_LEN
*pulLength
,
1767 CONFIGRET ret
= CR_SUCCESS
;
1768 LPWSTR lpValueName
= NULL
;
1769 HKEY hInstKey
= NULL
;
1770 HKEY hPropKey
= NULL
;
1773 UNREFERENCED_PARAMETER(hBinding
);
1775 DPRINT("PNP_GetClassRegProp() called\n");
1777 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
1779 ret
= CR_INVALID_POINTER
;
1785 ret
= CR_INVALID_FLAG
;
1789 if (*pulLength
< *pulTransferLen
)
1790 *pulLength
= *pulTransferLen
;
1792 *pulTransferLen
= 0;
1796 case CM_CRP_SECURITY
:
1797 lpValueName
= L
"Security";
1800 case CM_CRP_DEVTYPE
:
1801 lpValueName
= L
"DeviceType";
1804 case CM_CRP_EXCLUSIVE
:
1805 lpValueName
= L
"Exclusive";
1808 case CM_CRP_CHARACTERISTICS
:
1809 lpValueName
= L
"DeviceCharacteristics";
1813 ret
= CR_INVALID_PROPERTY
;
1817 DPRINT("Value name: %S\n", lpValueName
);
1819 lError
= RegOpenKeyExW(hClassKey
,
1824 if (lError
!= ERROR_SUCCESS
)
1827 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1831 lError
= RegOpenKeyExW(hInstKey
,
1836 if (lError
!= ERROR_SUCCESS
)
1839 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1843 lError
= RegQueryValueExW(hPropKey
,
1849 if (lError
!= ERROR_SUCCESS
)
1851 if (lError
== ERROR_MORE_DATA
)
1853 ret
= CR_BUFFER_SMALL
;
1858 ret
= CR_NO_SUCH_VALUE
;
1863 if (ret
== CR_SUCCESS
)
1864 *pulTransferLen
= *pulLength
;
1866 if (hPropKey
!= NULL
)
1867 RegCloseKey(hPropKey
);
1869 if (hInstKey
!= NULL
)
1870 RegCloseKey(hInstKey
);
1872 DPRINT("PNP_GetClassRegProp() done (returns %lx)\n", ret
);
1881 PNP_SetClassRegProp(
1883 LPWSTR pszClassGuid
,
1887 PNP_PROP_SIZE ulLength
,
1890 CONFIGRET ret
= CR_SUCCESS
;
1891 LPWSTR lpValueName
= NULL
;
1896 UNREFERENCED_PARAMETER(hBinding
);
1898 DPRINT("PNP_SetClassRegProp() called\n");
1901 return CR_INVALID_FLAG
;
1905 case CM_CRP_SECURITY
:
1906 lpValueName
= L
"Security";
1909 case CM_CRP_DEVTYPE
:
1910 lpValueName
= L
"DeviceType";
1913 case CM_CRP_EXCLUSIVE
:
1914 lpValueName
= L
"Exclusive";
1917 case CM_CRP_CHARACTERISTICS
:
1918 lpValueName
= L
"DeviceCharacteristics";
1922 return CR_INVALID_PROPERTY
;
1925 lError
= RegOpenKeyExW(hClassKey
,
1930 if (lError
!= ERROR_SUCCESS
)
1932 ret
= CR_NO_SUCH_REGISTRY_KEY
;
1936 /* FIXME: Set security descriptor */
1937 lError
= RegCreateKeyExW(hInstKey
,
1941 REG_OPTION_NON_VOLATILE
,
1946 if (lError
!= ERROR_SUCCESS
)
1948 ret
= CR_REGISTRY_ERROR
;
1954 if (RegDeleteValueW(hPropKey
,
1956 ret
= CR_REGISTRY_ERROR
;
1960 if (RegSetValueExW(hPropKey
,
1966 ret
= CR_REGISTRY_ERROR
;
1970 if (hPropKey
!= NULL
)
1971 RegCloseKey(hPropKey
);
1973 if (hInstKey
!= NULL
)
1974 RegCloseKey(hInstKey
);
1981 CreateDeviceInstance(LPWSTR pszDeviceID
)
1983 WCHAR szEnumerator
[MAX_DEVICE_ID_LEN
];
1984 WCHAR szDevice
[MAX_DEVICE_ID_LEN
];
1985 WCHAR szInstance
[MAX_DEVICE_ID_LEN
];
1986 HKEY hKeyEnumerator
;
1992 /* Split the instance ID */
1993 SplitDeviceInstanceID(pszDeviceID
,
1998 /* Open or create the enumerator key */
1999 lError
= RegCreateKeyExW(hEnumKey
,
2003 REG_OPTION_NON_VOLATILE
,
2008 if (lError
!= ERROR_SUCCESS
)
2010 return CR_REGISTRY_ERROR
;
2013 /* Open or create the device key */
2014 lError
= RegCreateKeyExW(hKeyEnumerator
,
2018 REG_OPTION_NON_VOLATILE
,
2024 /* Close the enumerator key */
2025 RegCloseKey(hKeyEnumerator
);
2027 if (lError
!= ERROR_SUCCESS
)
2029 return CR_REGISTRY_ERROR
;
2032 /* Try to open the instance key and fail if it exists */
2033 lError
= RegOpenKeyExW(hKeyDevice
,
2038 if (lError
== ERROR_SUCCESS
)
2040 DPRINT1("Instance %S already exists!\n", szInstance
);
2041 RegCloseKey(hKeyInstance
);
2042 RegCloseKey(hKeyDevice
);
2043 return CR_ALREADY_SUCH_DEVINST
;
2046 /* Create a new instance key */
2047 lError
= RegCreateKeyExW(hKeyDevice
,
2051 REG_OPTION_NON_VOLATILE
,
2057 /* Close the device key */
2058 RegCloseKey(hKeyDevice
);
2060 if (lError
!= ERROR_SUCCESS
)
2062 return CR_REGISTRY_ERROR
;
2065 /* Create the 'Control' sub key */
2066 lError
= RegCreateKeyExW(hKeyInstance
,
2070 REG_OPTION_NON_VOLATILE
,
2075 if (lError
== ERROR_SUCCESS
)
2077 RegCloseKey(hKeyControl
);
2080 RegCloseKey(hKeyInstance
);
2082 return (lError
== ERROR_SUCCESS
) ? CR_SUCCESS
: CR_REGISTRY_ERROR
;
2092 LPWSTR pszParentDeviceID
,
2093 PNP_RPC_STRING_LEN ulLength
,
2096 CONFIGRET ret
= CR_SUCCESS
;
2098 DPRINT("PNP_CreateDevInst: %S\n", pszDeviceID
);
2100 if (ulFlags
& CM_CREATE_DEVNODE_GENERATE_ID
)
2102 WCHAR szGeneratedInstance
[MAX_DEVICE_ID_LEN
];
2103 DWORD dwInstanceNumber
;
2105 /* Generated ID is: Root\<Device ID>\<Instance number> */
2106 dwInstanceNumber
= 0;
2109 swprintf(szGeneratedInstance
, L
"Root\\%ls\\%04lu",
2110 pszDeviceID
, dwInstanceNumber
);
2112 /* Try to create a device instance with this ID */
2113 ret
= CreateDeviceInstance(szGeneratedInstance
);
2117 while (ret
== CR_ALREADY_SUCH_DEVINST
);
2119 if (ret
== CR_SUCCESS
)
2121 /* pszDeviceID is an out parameter too for generated IDs */
2122 if (wcslen(szGeneratedInstance
) > ulLength
)
2124 ret
= CR_BUFFER_SMALL
;
2128 wcscpy(pszDeviceID
, szGeneratedInstance
);
2134 /* Create the device instance */
2135 ret
= CreateDeviceInstance(pszDeviceID
);
2138 DPRINT("PNP_CreateDevInst() done (returns %lx)\n", ret
);
2145 MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination
,
2146 LPWSTR pszDeviceInstanceSource
)
2148 DPRINT("MoveDeviceInstance: not implemented\n");
2150 return CR_CALL_NOT_IMPLEMENTED
;
2155 SetupDeviceInstance(LPWSTR pszDeviceInstance
,
2158 DPRINT("SetupDeviceInstance: not implemented\n");
2160 return CR_CALL_NOT_IMPLEMENTED
;
2165 EnableDeviceInstance(LPWSTR pszDeviceInstance
)
2167 PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData
;
2168 CONFIGRET ret
= CR_SUCCESS
;
2171 DPRINT("Enable device instance %S\n", pszDeviceInstance
);
2173 RtlInitUnicodeString(&ResetDeviceData
.DeviceInstance
, pszDeviceInstance
);
2174 Status
= NtPlugPlayControl(PlugPlayControlResetDevice
, &ResetDeviceData
, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA
));
2175 if (!NT_SUCCESS(Status
))
2176 ret
= NtStatusToCrError(Status
);
2183 DisableDeviceInstance(LPWSTR pszDeviceInstance
)
2185 DPRINT("DisableDeviceInstance: not implemented\n");
2187 return CR_CALL_NOT_IMPLEMENTED
;
2192 ReenumerateDeviceInstance(
2193 _In_ LPWSTR pszDeviceInstance
,
2196 PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData
;
2197 CONFIGRET ret
= CR_SUCCESS
;
2200 DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n",
2201 pszDeviceInstance
, ulFlags
);
2203 if (ulFlags
& ~CM_REENUMERATE_BITS
)
2204 return CR_INVALID_FLAG
;
2206 if (ulFlags
& CM_REENUMERATE_RETRY_INSTALLATION
)
2208 DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n");
2211 RtlInitUnicodeString(&EnumerateDeviceData
.DeviceInstance
,
2213 EnumerateDeviceData
.Flags
= 0;
2215 Status
= NtPlugPlayControl(PlugPlayControlEnumerateDevice
,
2216 &EnumerateDeviceData
,
2217 sizeof(PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA
));
2218 if (!NT_SUCCESS(Status
))
2219 ret
= NtStatusToCrError(Status
);
2228 PNP_DeviceInstanceAction(
2232 LPWSTR pszDeviceInstance1
,
2233 LPWSTR pszDeviceInstance2
)
2235 CONFIGRET ret
= CR_SUCCESS
;
2237 UNREFERENCED_PARAMETER(hBinding
);
2239 DPRINT("PNP_DeviceInstanceAction() called\n");
2243 case PNP_DEVINST_MOVE
:
2244 ret
= MoveDeviceInstance(pszDeviceInstance1
,
2245 pszDeviceInstance2
);
2248 case PNP_DEVINST_SETUP
:
2249 ret
= SetupDeviceInstance(pszDeviceInstance1
,
2253 case PNP_DEVINST_ENABLE
:
2254 ret
= EnableDeviceInstance(pszDeviceInstance1
);
2257 case PNP_DEVINST_DISABLE
:
2258 ret
= DisableDeviceInstance(pszDeviceInstance1
);
2261 case PNP_DEVINST_REENUMERATE
:
2262 ret
= ReenumerateDeviceInstance(pszDeviceInstance1
,
2267 DPRINT1("Unknown device action %lu: not implemented\n", ulAction
);
2268 ret
= CR_CALL_NOT_IMPLEMENTED
;
2271 DPRINT("PNP_DeviceInstanceAction() done (returns %lx)\n", ret
);
2280 PNP_GetDeviceStatus(
2287 PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData
;
2288 CONFIGRET ret
= CR_SUCCESS
;
2291 UNREFERENCED_PARAMETER(hBinding
);
2292 UNREFERENCED_PARAMETER(ulFlags
);
2294 DPRINT("PNP_GetDeviceStatus() called\n");
2296 RtlInitUnicodeString(&PlugPlayData
.DeviceInstance
,
2298 PlugPlayData
.Operation
= 0; /* Get status */
2300 Status
= NtPlugPlayControl(PlugPlayControlDeviceStatus
,
2301 (PVOID
)&PlugPlayData
,
2302 sizeof(PLUGPLAY_CONTROL_STATUS_DATA
));
2303 if (NT_SUCCESS(Status
))
2305 *pulStatus
= PlugPlayData
.DeviceStatus
;
2306 *pulProblem
= PlugPlayData
.DeviceProblem
;
2310 ret
= NtStatusToCrError(Status
);
2313 DPRINT("PNP_GetDeviceStatus() done (returns %lx)\n", ret
);
2322 PNP_SetDeviceProblem(
2329 return CR_CALL_NOT_IMPLEMENTED
;
2339 PPNP_VETO_TYPE pVetoType
,
2345 return CR_CALL_NOT_IMPLEMENTED
;
2351 PNP_UninstallDevInst(
2357 return CR_CALL_NOT_IMPLEMENTED
;
2362 CheckForDeviceId(LPWSTR lpDeviceIdList
,
2368 lpPtr
= lpDeviceIdList
;
2371 dwLength
= wcslen(lpPtr
);
2372 if (0 == _wcsicmp(lpPtr
, lpDeviceId
))
2375 lpPtr
+= (dwLength
+ 1);
2383 AppendDeviceId(LPWSTR lpDeviceIdList
,
2384 LPDWORD lpDeviceIdListSize
,
2390 dwLen
= wcslen(lpDeviceId
);
2391 dwPos
= (*lpDeviceIdListSize
/ sizeof(WCHAR
)) - 1;
2393 wcscpy(&lpDeviceIdList
[dwPos
], lpDeviceId
);
2395 dwPos
+= (dwLen
+ 1);
2397 lpDeviceIdList
[dwPos
] = 0;
2399 *lpDeviceIdListSize
= dwPos
* sizeof(WCHAR
);
2412 CONFIGRET ret
= CR_SUCCESS
;
2415 DWORD dwDeviceIdListSize
;
2416 DWORD dwNewDeviceIdSize
;
2417 WCHAR
* pszDeviceIdList
= NULL
;
2419 UNREFERENCED_PARAMETER(hBinding
);
2421 DPRINT("PNP_AddID() called\n");
2422 DPRINT(" DeviceInstance: %S\n", pszDeviceID
);
2423 DPRINT(" DeviceId: %S\n", pszID
);
2424 DPRINT(" Flags: %lx\n", ulFlags
);
2426 if (RegOpenKeyExW(hEnumKey
,
2429 KEY_QUERY_VALUE
| KEY_SET_VALUE
,
2430 &hDeviceKey
) != ERROR_SUCCESS
)
2432 DPRINT("Failed to open the device key!\n");
2433 return CR_INVALID_DEVNODE
;
2436 pszSubKey
= (ulFlags
& CM_ADD_ID_COMPATIBLE
) ? L
"CompatibleIDs" : L
"HardwareID";
2438 if (RegQueryValueExW(hDeviceKey
,
2443 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2445 DPRINT("Failed to query the desired ID string!\n");
2446 ret
= CR_REGISTRY_ERROR
;
2450 dwNewDeviceIdSize
= lstrlenW(pszDeviceID
);
2451 if (!dwNewDeviceIdSize
)
2453 ret
= CR_INVALID_POINTER
;
2457 dwDeviceIdListSize
+= (dwNewDeviceIdSize
+ 2) * sizeof(WCHAR
);
2459 pszDeviceIdList
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwDeviceIdListSize
);
2460 if (!pszDeviceIdList
)
2462 DPRINT("Failed to allocate memory for the desired ID string!\n");
2463 ret
= CR_OUT_OF_MEMORY
;
2467 if (RegQueryValueExW(hDeviceKey
,
2471 (LPBYTE
)pszDeviceIdList
,
2472 &dwDeviceIdListSize
) != ERROR_SUCCESS
)
2474 DPRINT("Failed to query the desired ID string!\n");
2475 ret
= CR_REGISTRY_ERROR
;
2479 /* Check whether the device ID is already in use */
2480 if (CheckForDeviceId(pszDeviceIdList
, pszDeviceID
))
2482 DPRINT("Device ID was found in the ID string!\n");
2487 /* Append the Device ID */
2488 AppendDeviceId(pszDeviceIdList
, &dwDeviceIdListSize
, pszID
);
2490 if (RegSetValueExW(hDeviceKey
,
2494 (LPBYTE
)pszDeviceIdList
,
2495 dwDeviceIdListSize
) != ERROR_SUCCESS
)
2497 DPRINT("Failed to set the desired ID string!\n");
2498 ret
= CR_REGISTRY_ERROR
;
2502 RegCloseKey(hDeviceKey
);
2503 if (pszDeviceIdList
)
2504 HeapFree(GetProcessHeap(), 0, pszDeviceIdList
);
2506 DPRINT("PNP_AddID() done (returns %lx)\n", ret
);
2521 return CR_CALL_NOT_IMPLEMENTED
;
2531 PPNP_VETO_TYPE pVetoType
,
2537 return CR_CALL_NOT_IMPLEMENTED
;
2544 PNP_RequestDeviceEject(
2547 PPNP_VETO_TYPE pVetoType
,
2553 return CR_CALL_NOT_IMPLEMENTED
;
2560 PNP_IsDockStationPresent(
2568 CONFIGRET ret
= CR_SUCCESS
;
2570 UNREFERENCED_PARAMETER(hBinding
);
2572 DPRINT1("PNP_IsDockStationPresent() called\n");
2576 if (RegOpenKeyExW(HKEY_CURRENT_CONFIG
,
2580 &hKey
) != ERROR_SUCCESS
)
2581 return CR_REGISTRY_ERROR
;
2583 dwSize
= sizeof(DWORD
);
2584 if (RegQueryValueExW(hKey
,
2589 &dwSize
) != ERROR_SUCCESS
)
2590 ret
= CR_REGISTRY_ERROR
;
2594 if (ret
== CR_SUCCESS
)
2596 if (dwType
!= REG_DWORD
|| dwSize
!= sizeof(DWORD
))
2598 ret
= CR_REGISTRY_ERROR
;
2600 else if (dwValue
!= 0)
2606 DPRINT1("PNP_IsDockStationPresent() done (returns %lx)\n", ret
);
2619 return CR_CALL_NOT_IMPLEMENTED
;
2632 PPNP_VETO_TYPE pVetoType
,
2637 CONFIGRET ret
= CR_SUCCESS
;
2638 WCHAR szKeyName
[MAX_PATH
];
2643 UNREFERENCED_PARAMETER(hBinding
);
2645 DPRINT("PNP_HwProfFlags() called\n");
2650 L
"System\\CurrentControlSet\\HardwareProfiles\\Current\\System\\CurrentControlSet\\Enum");
2655 L
"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum",
2659 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
2663 &hKey
) != ERROR_SUCCESS
)
2664 return CR_REGISTRY_ERROR
;
2666 if (ulAction
== PNP_GET_HWPROFFLAGS
)
2668 if (RegOpenKeyExW(hKey
,
2672 &hDeviceKey
) != ERROR_SUCCESS
)
2678 dwSize
= sizeof(DWORD
);
2679 if (RegQueryValueExW(hDeviceKey
,
2684 &dwSize
) != ERROR_SUCCESS
)
2689 RegCloseKey(hDeviceKey
);
2692 else if (ulAction
== PNP_SET_HWPROFFLAGS
)
2694 /* FIXME: not implemented yet */
2695 ret
= CR_CALL_NOT_IMPLEMENTED
;
2710 HWPROFILEINFO
*pHWProfileInfo
,
2711 DWORD ulProfileInfoSize
,
2714 WCHAR szProfileName
[5];
2715 HKEY hKeyConfig
= NULL
;
2716 HKEY hKeyProfiles
= NULL
;
2717 HKEY hKeyProfile
= NULL
;
2718 DWORD dwDisposition
;
2721 CONFIGRET ret
= CR_SUCCESS
;
2723 UNREFERENCED_PARAMETER(hBinding
);
2725 DPRINT("PNP_GetHwProfInfo() called\n");
2727 if (ulProfileInfoSize
== 0)
2729 ret
= CR_INVALID_DATA
;
2735 ret
= CR_INVALID_FLAG
;
2739 /* Initialize the profile information */
2740 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2741 pHWProfileInfo
->HWPI_szFriendlyName
[0] = 0;
2742 pHWProfileInfo
->HWPI_dwFlags
= 0;
2744 /* Open the 'IDConfigDB' key */
2745 lError
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
2746 L
"System\\CurrentControlSet\\Control\\IDConfigDB",
2749 REG_OPTION_NON_VOLATILE
,
2754 if (lError
!= ERROR_SUCCESS
)
2756 ret
= CR_REGISTRY_ERROR
;
2760 /* Open the 'Hardware Profiles' subkey */
2761 lError
= RegCreateKeyExW(hKeyConfig
,
2762 L
"Hardware Profiles",
2765 REG_OPTION_NON_VOLATILE
,
2766 KEY_ENUMERATE_SUB_KEYS
| KEY_QUERY_VALUE
,
2770 if (lError
!= ERROR_SUCCESS
)
2772 ret
= CR_REGISTRY_ERROR
;
2776 if (ulIndex
== (ULONG
)-1)
2778 dwSize
= sizeof(ULONG
);
2779 lError
= RegQueryValueExW(hKeyConfig
,
2783 (LPBYTE
)&pHWProfileInfo
->HWPI_ulHWProfile
,
2785 if (lError
!= ERROR_SUCCESS
)
2787 pHWProfileInfo
->HWPI_ulHWProfile
= 0;
2788 ret
= CR_REGISTRY_ERROR
;
2794 /* FIXME: not implemented yet */
2795 ret
= CR_CALL_NOT_IMPLEMENTED
;
2799 swprintf(szProfileName
, L
"%04lu", pHWProfileInfo
->HWPI_ulHWProfile
);
2801 lError
= RegOpenKeyExW(hKeyProfiles
,
2806 if (lError
!= ERROR_SUCCESS
)
2808 ret
= CR_REGISTRY_ERROR
;
2812 dwSize
= sizeof(pHWProfileInfo
->HWPI_szFriendlyName
);
2813 lError
= RegQueryValueExW(hKeyProfile
,
2817 (LPBYTE
)&pHWProfileInfo
->HWPI_szFriendlyName
,
2819 if (lError
!= ERROR_SUCCESS
)
2821 ret
= CR_REGISTRY_ERROR
;
2826 if (hKeyProfile
!= NULL
)
2827 RegCloseKey(hKeyProfile
);
2829 if (hKeyProfiles
!= NULL
)
2830 RegCloseKey(hKeyProfiles
);
2832 if (hKeyConfig
!= NULL
)
2833 RegCloseKey(hKeyConfig
);
2842 PNP_AddEmptyLogConf(
2846 DWORD
*pulLogConfTag
,
2850 return CR_CALL_NOT_IMPLEMENTED
;
2860 DWORD ulLogConfType
,
2865 return CR_CALL_NOT_IMPLEMENTED
;
2872 PNP_GetFirstLogConf(
2875 DWORD ulLogConfType
,
2876 DWORD
*pulLogConfTag
,
2880 return CR_CALL_NOT_IMPLEMENTED
;
2890 DWORD ulLogConfType
,
2896 return CR_CALL_NOT_IMPLEMENTED
;
2903 PNP_GetLogConfPriority(
2912 return CR_CALL_NOT_IMPLEMENTED
;
2923 DWORD ulLogConfType
,
2924 RESOURCEID ResourceID
,
2925 DWORD
*pulResourceTag
,
2927 PNP_RPC_BUFFER_SIZE ResourceLen
,
2931 return CR_CALL_NOT_IMPLEMENTED
;
2942 DWORD ulLogConfType
,
2943 RESOURCEID ResourceID
,
2944 DWORD ulResourceTag
,
2945 DWORD
*pulPreviousResType
,
2946 DWORD
*pulPreviousResTag
,
2950 return CR_CALL_NOT_IMPLEMENTED
;
2961 DWORD ulLogConfType
,
2962 RESOURCEID ResourceID
,
2963 DWORD ulResourceTag
,
2964 DWORD
*pulNextResType
,
2965 DWORD
*pulNextResTag
,
2969 return CR_CALL_NOT_IMPLEMENTED
;
2980 DWORD ulLogConfType
,
2981 RESOURCEID ResourceID
,
2982 DWORD ulResourceTag
,
2984 PNP_RPC_BUFFER_SIZE BufferLen
,
2988 return CR_CALL_NOT_IMPLEMENTED
;
2995 PNP_GetResDesDataSize(
2999 DWORD ulLogConfType
,
3000 RESOURCEID ResourceID
,
3001 DWORD ulResourceTag
,
3006 return CR_CALL_NOT_IMPLEMENTED
;
3017 DWORD ulLogConfType
,
3018 RESOURCEID CurrentResourceID
,
3019 RESOURCEID NewResourceID
,
3020 DWORD ulResourceTag
,
3022 PNP_RPC_BUFFER_SIZE ResourceLen
,
3026 return CR_CALL_NOT_IMPLEMENTED
;
3033 PNP_DetectResourceConflict(
3036 RESOURCEID ResourceID
,
3038 PNP_RPC_BUFFER_SIZE ResourceLen
,
3039 BOOL
*pbConflictDetected
,
3042 DPRINT("PNP_DetectResourceConflict()\n");
3044 if (pbConflictDetected
!= NULL
)
3045 *pbConflictDetected
= FALSE
;
3047 return CR_CALL_NOT_IMPLEMENTED
;
3054 PNP_QueryResConfList(
3057 RESOURCEID ResourceID
,
3059 PNP_RPC_BUFFER_SIZE ResourceLen
,
3061 PNP_RPC_BUFFER_SIZE BufferLen
,
3065 return CR_CALL_NOT_IMPLEMENTED
;
3074 DWORD ulHardwareProfile
,
3078 return CR_CALL_NOT_IMPLEMENTED
;
3085 PNP_QueryArbitratorFreeData(
3090 RESOURCEID ResourceID
,
3094 return CR_CALL_NOT_IMPLEMENTED
;
3101 PNP_QueryArbitratorFreeSize(
3105 RESOURCEID ResourceID
,
3109 return CR_CALL_NOT_IMPLEMENTED
;
3120 return CR_CALL_NOT_IMPLEMENTED
;
3127 PNP_RegisterNotification(
3133 PNOTIFY_DATA pNotifyData
;
3136 DPRINT1("PNP_RegisterNotification(%p 0x%lx %p)\n",
3137 hBinding
, ulFlags
, pulNotify
);
3140 pNotifyData
= RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(NOTIFY_DATA
));
3141 if (pNotifyData
== NULL
)
3142 return CR_OUT_OF_MEMORY
;
3144 *pulNotify
= (DWORD
)pNotifyData
;
3156 PNP_UnregisterNotification(
3160 DPRINT1("PNP_UnregisterNotification(%p 0x%lx)\n",
3161 hBinding
, ulNotify
);
3165 return CR_CALL_NOT_IMPLEMENTED
;
3175 PNP_GetCustomDevProp(
3178 LPWSTR CustomPropName
,
3179 DWORD
*pulRegDataType
,
3181 PNP_RPC_STRING_LEN
*pulTransferLen
,
3182 PNP_RPC_STRING_LEN
*pulLength
,
3185 HKEY hDeviceKey
= NULL
;
3186 HKEY hParamKey
= NULL
;
3188 CONFIGRET ret
= CR_SUCCESS
;
3190 UNREFERENCED_PARAMETER(hBinding
);
3192 DPRINT("PNP_GetCustomDevProp() called\n");
3194 if (pulTransferLen
== NULL
|| pulLength
== NULL
)
3196 ret
= CR_INVALID_POINTER
;
3200 if (ulFlags
& ~CM_CUSTOMDEVPROP_BITS
)
3202 ret
= CR_INVALID_FLAG
;
3206 if (*pulLength
< *pulTransferLen
)
3207 *pulLength
= *pulTransferLen
;
3209 *pulTransferLen
= 0;
3211 lError
= RegOpenKeyExW(hEnumKey
,
3216 if (lError
!= ERROR_SUCCESS
)
3218 ret
= CR_REGISTRY_ERROR
;
3222 lError
= RegOpenKeyExW(hDeviceKey
,
3223 L
"Device Parameters",
3227 if (lError
!= ERROR_SUCCESS
)
3229 ret
= CR_REGISTRY_ERROR
;
3233 lError
= RegQueryValueExW(hParamKey
,
3239 if (lError
!= ERROR_SUCCESS
)
3241 if (lError
== ERROR_MORE_DATA
)
3243 ret
= CR_BUFFER_SMALL
;
3248 ret
= CR_NO_SUCH_VALUE
;
3253 if (ret
== CR_SUCCESS
)
3254 *pulTransferLen
= *pulLength
;
3256 if (hParamKey
!= NULL
)
3257 RegCloseKey(hParamKey
);
3259 if (hDeviceKey
!= NULL
)
3260 RegCloseKey(hDeviceKey
);
3262 DPRINT("PNP_GetCustomDevProp() done (returns %lx)\n", ret
);
3271 PNP_GetVersionInternal(
3275 UNREFERENCED_PARAMETER(hBinding
);
3285 PNP_GetBlockedDriverInfo(
3288 PNP_RPC_BUFFER_SIZE
*pulTransferLen
,
3289 PNP_RPC_BUFFER_SIZE
*pulLength
,
3293 return CR_CALL_NOT_IMPLEMENTED
;
3300 PNP_GetServerSideDeviceInstallFlags(
3302 DWORD
*pulSSDIFlags
,
3305 UNREFERENCED_PARAMETER(hBinding
);
3307 DPRINT1("PNP_GetServerSideDeviceInstallFlags(%p %p %lu)\n",
3308 hBinding
, pulSSDIFlags
, ulFlags
);
3310 if (pulSSDIFlags
== NULL
)
3311 return CR_INVALID_POINTER
;
3314 return CR_INVALID_FLAG
;
3326 PNP_GetObjectPropKeys(
3330 LPWSTR PropertyCultureName
,
3331 PNP_PROP_COUNT
*PropertyCount
,
3332 PNP_PROP_COUNT
*TransferLen
,
3333 DEVPROPKEY
*PropertyKeys
,
3337 return CR_CALL_NOT_IMPLEMENTED
;
3348 LPWSTR PropertyCultureName
,
3349 const DEVPROPKEY
*PropertyKey
,
3350 DEVPROPTYPE
*PropertyType
,
3351 PNP_PROP_SIZE
*PropertySize
,
3352 PNP_PROP_SIZE
*TransferLen
,
3353 BYTE
*PropertyBuffer
,
3357 return CR_CALL_NOT_IMPLEMENTED
;
3368 LPWSTR PropertyCultureName
,
3369 const DEVPROPKEY
*PropertyKey
,
3370 DEVPROPTYPE PropertyType
,
3371 PNP_PROP_SIZE PropertySize
,
3372 BYTE
*PropertyBuffer
,
3376 return CR_CALL_NOT_IMPLEMENTED
;
3387 return CR_CALL_NOT_IMPLEMENTED
;
3394 PNP_ApplyPowerSettings(
3398 return CR_CALL_NOT_IMPLEMENTED
;
3405 PNP_DriverStoreAddDriverPackage(
3409 return CR_CALL_NOT_IMPLEMENTED
;
3416 PNP_DriverStoreDeleteDriverPackage(
3420 return CR_CALL_NOT_IMPLEMENTED
;
3427 PNP_RegisterServiceNotification(
3431 return CR_CALL_NOT_IMPLEMENTED
;
3438 PNP_SetActiveService(
3444 return CR_CALL_NOT_IMPLEMENTED
;
3451 PNP_DeleteServiceDevices(
3455 return CR_CALL_NOT_IMPLEMENTED
;
3460 InstallDevice(PCWSTR DeviceInstance
, BOOL ShowWizard
)
3462 BOOL DeviceInstalled
= FALSE
;
3465 HANDLE hInstallEvent
;
3466 HANDLE hPipe
= INVALID_HANDLE_VALUE
;
3467 LPVOID Environment
= NULL
;
3468 PROCESS_INFORMATION ProcessInfo
;
3469 STARTUPINFOW StartupInfo
;
3473 /* The following lengths are constant (see below), they cannot overflow */
3474 WCHAR CommandLine
[116];
3475 WCHAR InstallEventName
[73];
3477 WCHAR UuidString
[39];
3479 DPRINT("InstallDevice(%S, %d)\n", DeviceInstance
, ShowWizard
);
3481 ZeroMemory(&ProcessInfo
, sizeof(ProcessInfo
));
3483 if (RegOpenKeyExW(hEnumKey
,
3487 &DeviceKey
) == ERROR_SUCCESS
)
3489 if (RegQueryValueExW(DeviceKey
,
3494 NULL
) == ERROR_SUCCESS
)
3496 DPRINT("No need to install: %S\n", DeviceInstance
);
3497 RegCloseKey(DeviceKey
);
3501 BytesWritten
= sizeof(DWORD
);
3502 if (RegQueryValueExW(DeviceKey
,
3507 &BytesWritten
) == ERROR_SUCCESS
)
3509 if (Value
& CONFIGFLAG_FAILEDINSTALL
)
3511 DPRINT("No need to install: %S\n", DeviceInstance
);
3512 RegCloseKey(DeviceKey
);
3517 RegCloseKey(DeviceKey
);
3520 DPRINT1("Installing: %S\n", DeviceInstance
);
3522 /* Create a random UUID for the named pipe & event*/
3523 UuidCreate(&RandomUuid
);
3524 swprintf(UuidString
, L
"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
3525 RandomUuid
.Data1
, RandomUuid
.Data2
, RandomUuid
.Data3
,
3526 RandomUuid
.Data4
[0], RandomUuid
.Data4
[1], RandomUuid
.Data4
[2],
3527 RandomUuid
.Data4
[3], RandomUuid
.Data4
[4], RandomUuid
.Data4
[5],
3528 RandomUuid
.Data4
[6], RandomUuid
.Data4
[7]);
3530 /* Create the event */
3531 wcscpy(InstallEventName
, L
"Global\\PNP_Device_Install_Event_0.");
3532 wcscat(InstallEventName
, UuidString
);
3533 hInstallEvent
= CreateEventW(NULL
, TRUE
, FALSE
, InstallEventName
);
3536 DPRINT1("CreateEventW('%ls') failed with error %lu\n", InstallEventName
, GetLastError());
3540 /* Create the named pipe */
3541 wcscpy(PipeName
, L
"\\\\.\\pipe\\PNP_Device_Install_Pipe_0.");
3542 wcscat(PipeName
, UuidString
);
3543 hPipe
= CreateNamedPipeW(PipeName
, PIPE_ACCESS_OUTBOUND
, PIPE_TYPE_BYTE
, 1, 512, 512, 0, NULL
);
3544 if (hPipe
== INVALID_HANDLE_VALUE
)
3546 DPRINT1("CreateNamedPipeW failed with error %u\n", GetLastError());
3550 /* Launch rundll32 to call ClientSideInstallW */
3551 wcscpy(CommandLine
, L
"rundll32.exe newdev.dll,ClientSideInstall ");
3552 wcscat(CommandLine
, PipeName
);
3554 ZeroMemory(&StartupInfo
, sizeof(StartupInfo
));
3555 StartupInfo
.cb
= sizeof(StartupInfo
);
3559 /* newdev has to run under the environment of the current user */
3560 if (!CreateEnvironmentBlock(&Environment
, hUserToken
, FALSE
))
3562 DPRINT1("CreateEnvironmentBlock failed with error %d\n", GetLastError());
3566 if (!CreateProcessAsUserW(hUserToken
, NULL
, CommandLine
, NULL
, NULL
, FALSE
, CREATE_UNICODE_ENVIRONMENT
, Environment
, NULL
, &StartupInfo
, &ProcessInfo
))
3568 DPRINT1("CreateProcessAsUserW failed with error %u\n", GetLastError());
3574 /* FIXME: This is probably not correct, I guess newdev should never be run with SYSTEM privileges.
3576 Still, we currently do that in 2nd stage setup and probably Console mode as well, so allow it here.
3577 (ShowWizard is only set to FALSE for these two modes) */
3578 ASSERT(!ShowWizard
);
3580 if (!CreateProcessW(NULL
, CommandLine
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &StartupInfo
, &ProcessInfo
))
3582 DPRINT1("CreateProcessW failed with error %u\n", GetLastError());
3587 /* Wait for the function to connect to our pipe */
3588 if (!ConnectNamedPipe(hPipe
, NULL
))
3590 if (GetLastError() != ERROR_PIPE_CONNECTED
)
3592 DPRINT1("ConnectNamedPipe failed with error %u\n", GetLastError());
3597 /* Pass the data. The following output is partly compatible to Windows XP SP2 (researched using a modified newdev.dll to log this stuff) */
3598 Value
= sizeof(InstallEventName
);
3599 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3600 WriteFile(hPipe
, InstallEventName
, Value
, &BytesWritten
, NULL
);
3602 /* I couldn't figure out what the following value means under WinXP. It's usually 0 in my tests, but was also 5 once.
3603 Therefore the following line is entirely ReactOS-specific. We use the value here to pass the ShowWizard variable. */
3604 WriteFile(hPipe
, &ShowWizard
, sizeof(ShowWizard
), &BytesWritten
, NULL
);
3606 Value
= (wcslen(DeviceInstance
) + 1) * sizeof(WCHAR
);
3607 WriteFile(hPipe
, &Value
, sizeof(Value
), &BytesWritten
, NULL
);
3608 WriteFile(hPipe
, DeviceInstance
, Value
, &BytesWritten
, NULL
);
3610 /* Wait for newdev.dll to finish processing */
3611 WaitForSingleObject(ProcessInfo
.hProcess
, INFINITE
);
3613 /* If the event got signalled, this is success */
3614 DeviceInstalled
= WaitForSingleObject(hInstallEvent
, 0) == WAIT_OBJECT_0
;
3618 CloseHandle(hInstallEvent
);
3620 if (hPipe
!= INVALID_HANDLE_VALUE
)
3624 DestroyEnvironmentBlock(Environment
);
3626 if (ProcessInfo
.hProcess
)
3627 CloseHandle(ProcessInfo
.hProcess
);
3629 if (ProcessInfo
.hThread
)
3630 CloseHandle(ProcessInfo
.hThread
);
3632 if (!DeviceInstalled
)
3634 DPRINT1("InstallDevice failed for DeviceInstance '%ws'\n", DeviceInstance
);
3637 return DeviceInstalled
;
3653 return ERROR_INVALID_PARAMETER
;
3656 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
3657 if (rc
!= ERROR_SUCCESS
)
3659 if (dwType
!= REG_SZ
)
3660 return ERROR_FILE_NOT_FOUND
;
3661 Value
= HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
3663 return ERROR_NOT_ENOUGH_MEMORY
;
3664 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
3665 if (rc
!= ERROR_SUCCESS
)
3667 HeapFree(GetProcessHeap(), 0, Value
);
3670 /* NULL-terminate the string */
3671 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
3674 return ERROR_SUCCESS
;
3682 DWORD regType
, active
, size
;
3686 rc
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
3687 if (rc
!= ERROR_SUCCESS
)
3690 size
= sizeof(DWORD
);
3691 rc
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
, ®Type
, (LPBYTE
)&active
, &size
);
3692 if (rc
!= ERROR_SUCCESS
)
3694 if (regType
!= REG_DWORD
|| size
!= sizeof(DWORD
))
3697 ret
= (active
!= 0);
3703 DPRINT("System setup in progress? %S\n", ret
? L
"YES" : L
"NO");
3712 HKEY ControlKey
= NULL
;
3713 LPWSTR SystemStartOptions
= NULL
;
3714 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
3715 BOOL ConsoleBoot
= FALSE
;
3720 L
"SYSTEM\\CurrentControlSet\\Control",
3725 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
3726 if (rc
!= ERROR_SUCCESS
)
3729 /* Check for CONSOLE switch in SystemStartOptions */
3730 CurrentOption
= SystemStartOptions
;
3731 while (CurrentOption
)
3733 NextOption
= wcschr(CurrentOption
, L
' ');
3735 *NextOption
= L
'\0';
3736 if (_wcsicmp(CurrentOption
, L
"CONSOLE") == 0)
3738 DPRINT("Found %S. Switching to console boot\n", CurrentOption
);
3742 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
3746 if (ControlKey
!= NULL
)
3747 RegCloseKey(ControlKey
);
3748 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
3753 /* Loop to install all queued devices installations */
3755 DeviceInstallThread(LPVOID lpParameter
)
3757 PSLIST_ENTRY ListEntry
;
3758 DeviceInstallParams
* Params
;
3761 UNREFERENCED_PARAMETER(lpParameter
);
3763 WaitForSingleObject(hInstallEvent
, INFINITE
);
3765 showWizard
= !SetupIsActive() && !IsConsoleBoot();
3769 ListEntry
= InterlockedPopEntrySList(&DeviceInstallListHead
);
3771 if (ListEntry
== NULL
)
3773 SetEvent(hNoPendingInstalls
);
3774 WaitForSingleObject(hDeviceInstallListNotEmpty
, INFINITE
);
3778 ResetEvent(hNoPendingInstalls
);
3779 Params
= CONTAINING_RECORD(ListEntry
, DeviceInstallParams
, ListEntry
);
3780 InstallDevice(Params
->DeviceIds
, showWizard
);
3781 HeapFree(GetProcessHeap(), 0, Params
);
3790 PnpEventThread(LPVOID lpParameter
)
3792 DWORD dwRet
= ERROR_SUCCESS
;
3794 RPC_STATUS RpcStatus
;
3795 PPLUGPLAY_EVENT_BLOCK PnpEvent
, NewPnpEvent
;
3798 UNREFERENCED_PARAMETER(lpParameter
);
3800 PnpEventSize
= 0x1000;
3801 PnpEvent
= HeapAlloc(GetProcessHeap(), 0, PnpEventSize
);
3802 if (PnpEvent
== NULL
)
3803 return ERROR_OUTOFMEMORY
;
3807 DPRINT("Calling NtGetPlugPlayEvent()\n");
3809 /* Wait for the next PnP event */
3810 Status
= NtGetPlugPlayEvent(0, 0, PnpEvent
, PnpEventSize
);
3812 /* Resize the buffer for the PnP event if it's too small */
3813 if (Status
== STATUS_BUFFER_TOO_SMALL
)
3815 PnpEventSize
+= 0x400;
3816 NewPnpEvent
= HeapReAlloc(GetProcessHeap(), 0, PnpEvent
, PnpEventSize
);
3817 if (NewPnpEvent
== NULL
)
3819 dwRet
= ERROR_OUTOFMEMORY
;
3822 PnpEvent
= NewPnpEvent
;
3826 if (!NT_SUCCESS(Status
))
3828 DPRINT1("NtGetPlugPlayEvent() failed (Status 0x%08lx)\n", Status
);
3832 /* Process the PnP event */
3833 DPRINT("Received PnP Event\n");
3834 if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ENUMERATED
, &RpcStatus
))
3836 DeviceInstallParams
* Params
;
3838 DWORD DeviceIdLength
;
3840 DPRINT("Device enumerated: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3842 DeviceIdLength
= lstrlenW(PnpEvent
->TargetDevice
.DeviceIds
);
3845 /* Queue device install (will be dequeued by DeviceInstallThread) */
3846 len
= FIELD_OFFSET(DeviceInstallParams
, DeviceIds
) + (DeviceIdLength
+ 1) * sizeof(WCHAR
);
3847 Params
= HeapAlloc(GetProcessHeap(), 0, len
);
3850 wcscpy(Params
->DeviceIds
, PnpEvent
->TargetDevice
.DeviceIds
);
3851 InterlockedPushEntrySList(&DeviceInstallListHead
, &Params
->ListEntry
);
3852 SetEvent(hDeviceInstallListNotEmpty
);
3856 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_ARRIVAL
, &RpcStatus
))
3858 // DWORD dwRecipient;
3860 DPRINT("Device arrival: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3862 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3863 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3866 // DBT_DEVNODES_CHANGED,
3868 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3870 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_EJECT_VETOED
, &RpcStatus
))
3872 DPRINT1("Eject vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3874 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_KERNEL_INITIATED_EJECT
, &RpcStatus
))
3876 DPRINT1("Kernel initiated eject: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3878 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SAFE_REMOVAL
, &RpcStatus
))
3880 // DWORD dwRecipient;
3882 DPRINT1("Safe removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3884 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3885 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3888 // DBT_DEVNODES_CHANGED,
3890 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3892 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_SURPRISE_REMOVAL
, &RpcStatus
))
3894 // DWORD dwRecipient;
3896 DPRINT1("Surprise removal: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3898 // dwRecipient = BSM_ALLDESKTOPS | BSM_APPLICATIONS;
3899 // BroadcastSystemMessageW(BSF_POSTMESSAGE,
3902 // DBT_DEVNODES_CHANGED,
3904 SendMessageW(HWND_BROADCAST
, WM_DEVICECHANGE
, DBT_DEVNODES_CHANGED
, 0);
3906 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVAL_VETOED
, &RpcStatus
))
3908 DPRINT1("Removal vetoed: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3910 else if (UuidEqual(&PnpEvent
->EventGuid
, (UUID
*)&GUID_DEVICE_REMOVE_PENDING
, &RpcStatus
))
3912 DPRINT1("Removal pending: %S\n", PnpEvent
->TargetDevice
.DeviceIds
);
3916 DPRINT1("Unknown event, GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
3917 PnpEvent
->EventGuid
.Data1
, PnpEvent
->EventGuid
.Data2
, PnpEvent
->EventGuid
.Data3
,
3918 PnpEvent
->EventGuid
.Data4
[0], PnpEvent
->EventGuid
.Data4
[1], PnpEvent
->EventGuid
.Data4
[2],
3919 PnpEvent
->EventGuid
.Data4
[3], PnpEvent
->EventGuid
.Data4
[4], PnpEvent
->EventGuid
.Data4
[5],
3920 PnpEvent
->EventGuid
.Data4
[6], PnpEvent
->EventGuid
.Data4
[7]);
3923 /* Dequeue the current PnP event and signal the next one */
3924 NtPlugPlayControl(PlugPlayControlUserResponse
, NULL
, 0);
3927 HeapFree(GetProcessHeap(), 0, PnpEvent
);
3934 UpdateServiceStatus(DWORD dwState
)
3936 ServiceStatus
.dwServiceType
= SERVICE_WIN32_OWN_PROCESS
;
3937 ServiceStatus
.dwCurrentState
= dwState
;
3938 ServiceStatus
.dwControlsAccepted
= 0;
3939 ServiceStatus
.dwWin32ExitCode
= 0;
3940 ServiceStatus
.dwServiceSpecificExitCode
= 0;
3941 ServiceStatus
.dwCheckPoint
= 0;
3943 if (dwState
== SERVICE_START_PENDING
||
3944 dwState
== SERVICE_STOP_PENDING
||
3945 dwState
== SERVICE_PAUSE_PENDING
||
3946 dwState
== SERVICE_CONTINUE_PENDING
)
3947 ServiceStatus
.dwWaitHint
= 10000;
3949 ServiceStatus
.dwWaitHint
= 0;
3951 SetServiceStatus(ServiceStatusHandle
,
3957 ServiceControlHandler(DWORD dwControl
,
3962 DPRINT1("ServiceControlHandler() called\n");
3966 case SERVICE_CONTROL_STOP
:
3967 DPRINT1(" SERVICE_CONTROL_STOP received\n");
3968 /* Stop listening to RPC Messages */
3969 RpcMgmtStopServerListening(NULL
);
3970 UpdateServiceStatus(SERVICE_STOPPED
);
3971 return ERROR_SUCCESS
;
3973 case SERVICE_CONTROL_PAUSE
:
3974 DPRINT1(" SERVICE_CONTROL_PAUSE received\n");
3975 UpdateServiceStatus(SERVICE_PAUSED
);
3976 return ERROR_SUCCESS
;
3978 case SERVICE_CONTROL_CONTINUE
:
3979 DPRINT1(" SERVICE_CONTROL_CONTINUE received\n");
3980 UpdateServiceStatus(SERVICE_RUNNING
);
3981 return ERROR_SUCCESS
;
3983 case SERVICE_CONTROL_INTERROGATE
:
3984 DPRINT1(" SERVICE_CONTROL_INTERROGATE received\n");
3985 SetServiceStatus(ServiceStatusHandle
,
3987 return ERROR_SUCCESS
;
3989 case SERVICE_CONTROL_SHUTDOWN
:
3990 DPRINT1(" SERVICE_CONTROL_SHUTDOWN received\n");
3991 /* Stop listening to RPC Messages */
3992 RpcMgmtStopServerListening(NULL
);
3993 UpdateServiceStatus(SERVICE_STOPPED
);
3994 return ERROR_SUCCESS
;
3997 DPRINT1(" Control %lu received\n", dwControl
);
3998 return ERROR_CALL_NOT_IMPLEMENTED
;
4004 ServiceMain(DWORD argc
, LPTSTR
*argv
)
4009 UNREFERENCED_PARAMETER(argc
);
4010 UNREFERENCED_PARAMETER(argv
);
4012 DPRINT("ServiceMain() called\n");
4014 ServiceStatusHandle
= RegisterServiceCtrlHandlerExW(ServiceName
,
4015 ServiceControlHandler
,
4017 if (!ServiceStatusHandle
)
4019 DPRINT1("RegisterServiceCtrlHandlerExW() failed! (Error %lu)\n", GetLastError());
4023 UpdateServiceStatus(SERVICE_START_PENDING
);
4025 hThread
= CreateThread(NULL
,
4031 if (hThread
!= NULL
)
4032 CloseHandle(hThread
);
4034 hThread
= CreateThread(NULL
,
4040 if (hThread
!= NULL
)
4041 CloseHandle(hThread
);
4043 hThread
= CreateThread(NULL
,
4045 DeviceInstallThread
,
4049 if (hThread
!= NULL
)
4050 CloseHandle(hThread
);
4052 UpdateServiceStatus(SERVICE_RUNNING
);
4054 DPRINT("ServiceMain() done\n");
4058 InitializePnPManager(VOID
)
4063 DPRINT("UMPNPMGR: InitializePnPManager() started\n");
4065 /* We need this privilege for using CreateProcessAsUserW */
4066 RtlAdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
, TRUE
, FALSE
, &OldValue
);
4068 hInstallEvent
= CreateEventW(NULL
, TRUE
, SetupIsActive()/*FALSE*/, NULL
);
4069 if (hInstallEvent
== NULL
)
4071 dwError
= GetLastError();
4072 DPRINT1("Could not create the Install Event! (Error %lu)\n", dwError
);
4076 hDeviceInstallListNotEmpty
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
4077 if (hDeviceInstallListNotEmpty
== NULL
)
4079 dwError
= GetLastError();
4080 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
4084 hNoPendingInstalls
= CreateEventW(NULL
,
4087 L
"Global\\PnP_No_Pending_Install_Events");
4088 if (hNoPendingInstalls
== NULL
)
4090 dwError
= GetLastError();
4091 DPRINT1("Could not create the Event! (Error %lu)\n", dwError
);
4095 InitializeSListHead(&DeviceInstallListHead
);
4097 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
4098 L
"System\\CurrentControlSet\\Enum",
4102 if (dwError
!= ERROR_SUCCESS
)
4104 DPRINT1("Could not open the Enum Key! (Error %lu)\n", dwError
);
4108 dwError
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
4109 L
"System\\CurrentControlSet\\Control\\Class",
4113 if (dwError
!= ERROR_SUCCESS
)
4115 DPRINT1("Could not open the Class Key! (Error %lu)\n", dwError
);
4119 DPRINT("UMPNPMGR: InitializePnPManager() done\n");
4125 DllMain(HINSTANCE hinstDLL
,
4131 case DLL_PROCESS_ATTACH
:
4132 DisableThreadLibraryCalls(hinstDLL
);
4133 InitializePnPManager();
4136 case DLL_PROCESS_DETACH
: