1 // 2 // Copyright (C) Microsoft. All rights reserved. 3 // 4 #include "../pnppriv.hpp" 5 6 #include <initguid.h> 7 #include <wdmguid.h> 8 9 extern "C" { 10 #if defined(EVENT_TRACING) 11 #include "FxPkgPnpUM.tmh" 12 #endif 13 } 14 15 NTSTATUS 16 FxPkgPnp::FilterResourceRequirements( 17 __in IO_RESOURCE_REQUIREMENTS_LIST **IoList 18 ) 19 { 20 UNREFERENCED_PARAMETER(IoList); 21 ASSERTMSG("Not implemented for UMDF\n", FALSE); 22 23 return STATUS_NOT_IMPLEMENTED; 24 } 25 26 _Must_inspect_result_ 27 NTSTATUS 28 FxPkgPnp::AllocateDmaEnablerList( 29 VOID 30 ) 31 { 32 ASSERTMSG("Not implemented for UMDF\n", FALSE); 33 34 return STATUS_NOT_IMPLEMENTED; 35 } 36 37 VOID 38 FxPkgPnp::AddDmaEnabler( 39 __in FxDmaEnabler* Enabler 40 ) 41 { 42 UNREFERENCED_PARAMETER(Enabler); 43 ASSERTMSG("Not implemented for UMDF\n", FALSE); 44 } 45 46 VOID 47 FxPkgPnp::RemoveDmaEnabler( 48 __in FxDmaEnabler* Enabler 49 ) 50 { 51 UNREFERENCED_PARAMETER(Enabler); 52 ASSERTMSG("Not implemented for UMDF\n", FALSE); 53 } 54 55 NTSTATUS 56 FxPkgPnp::UpdateWmiInstance( 57 _In_ FxWmiInstanceAction Action, 58 _In_ BOOLEAN ForS0Idle 59 ) 60 { 61 HRESULT hr; 62 NTSTATUS status; 63 IWudfDeviceStack* devStack; 64 WmiIdleWakeInstanceUpdate updateType; 65 66 devStack = m_Device->GetDeviceStack(); 67 68 ASSERT(Action != InstanceActionInvalid); 69 70 if (Action == AddInstance) { 71 updateType = ForS0Idle ? AddS0IdleInstance : AddSxWakeInstance; 72 } else { 73 updateType = ForS0Idle ? RemoveS0IdleInstance : RemoveSxWakeInstance; 74 } 75 76 hr = devStack->UpdateIdleWakeWmiInstance(updateType); 77 if (S_OK == hr) { 78 status = STATUS_SUCCESS; 79 } 80 else { 81 PUMDF_VERSION_DATA driverVersion = devStack->GetMinDriverVersion(); 82 BOOL preserveCompat = 83 devStack->ShouldPreserveIrpCompletionStatusCompatibility(); 84 85 status = CHostFxUtil::NtStatusFromHr(hr, 86 driverVersion->MajorNumber, 87 driverVersion->MinorNumber, 88 preserveCompat); 89 } 90 91 if (!NT_SUCCESS(status)) { 92 DoTraceLevelMessage(GetDriverGlobals(), 93 TRACE_LEVEL_ERROR, 94 TRACINGPNP, 95 "failed to send ioctl to update %s WMI instance " 96 "%!STATUS!", 97 ForS0Idle ? "S0Idle" : "SxWake", 98 status); 99 } 100 101 return status; 102 } 103 104 NTSTATUS 105 FxPkgPnp::ReadStateFromRegistry( 106 _In_ PCUNICODE_STRING ValueName, 107 _Out_ PULONG Value 108 ) 109 { 110 DWORD err; 111 NTSTATUS status; 112 DWORD data; 113 DWORD dataSize; 114 HKEY pwrPolKey = NULL; 115 IWudfDeviceStack* devStack; 116 117 ASSERT(NULL != Value); 118 ASSERT(ValueName != NULL && 119 ValueName->Length != 0 && 120 ValueName->Buffer != NULL); 121 122 *Value = 0; 123 devStack = m_Device->GetDeviceStack(); 124 125 err = RegOpenKeyEx(devStack->GetDeviceRegistryKey(), 126 WUDF_POWER_POLICY_SETTINGS, 127 0, 128 KEY_READ, 129 &pwrPolKey); 130 if (ERROR_SUCCESS != err) { 131 DoTraceLevelMessage(GetDriverGlobals(), 132 TRACE_LEVEL_ERROR, 133 TRACINGPNP, 134 "RegOpenKeyEx returned error %d", 135 err); 136 goto Clean; 137 } 138 139 dataSize = sizeof(data); 140 err = RegQueryValueEx(pwrPolKey, 141 ValueName->Buffer, 142 NULL, 143 NULL, 144 (BYTE*) &data, 145 &dataSize); 146 if (ERROR_SUCCESS != err) { 147 DoTraceLevelMessage(GetDriverGlobals(), 148 TRACE_LEVEL_ERROR, 149 TRACINGPNP, 150 "failed to read registry, " 151 "RegQueryValueEx returned error %d", 152 err); 153 goto Clean; 154 } 155 156 *Value = data; 157 err = ERROR_SUCCESS; 158 159 Clean: 160 if (NULL != pwrPolKey) { 161 RegCloseKey(pwrPolKey); 162 } 163 164 if (ERROR_SUCCESS == err) { 165 status = STATUS_SUCCESS; 166 } 167 else { 168 PUMDF_VERSION_DATA driverVersion = devStack->GetMinDriverVersion(); 169 BOOL preserveCompat = 170 devStack->ShouldPreserveIrpCompletionStatusCompatibility(); 171 172 status = CHostFxUtil::NtStatusFromHr(HRESULT_FROM_WIN32(err), 173 driverVersion->MajorNumber, 174 driverVersion->MinorNumber, 175 preserveCompat); 176 } 177 178 return status; 179 } 180 181 VOID 182 FxPkgPnp::WriteStateToRegistry( 183 __in HANDLE RegKey, 184 __in PUNICODE_STRING ValueName, 185 __in ULONG Value 186 ) 187 { 188 DWORD err; 189 HRESULT hr; 190 HKEY hKey = NULL; 191 IWudfDeviceStack* devStack; 192 UMINT::WDF_PROPERTY_STORE_ROOT propertyStore; 193 194 UNREFERENCED_PARAMETER(RegKey); 195 196 ASSERT(ValueName != NULL && 197 ValueName->Length != 0 && 198 ValueName->Buffer != NULL); 199 200 devStack = m_Device->GetDeviceStack(); 201 202 propertyStore.LengthCb = sizeof(UMINT::WDF_PROPERTY_STORE_ROOT); 203 propertyStore.RootClass = UMINT::WdfPropertyStoreRootClassHardwareKey; 204 propertyStore.Qualifier.HardwareKey.ServiceName = WUDF_POWER_POLICY_SETTINGS; 205 206 hr = devStack->CreateRegistryEntry(&propertyStore, 207 UMINT::WdfPropertyStoreCreateIfMissing, 208 KEY_QUERY_VALUE | KEY_SET_VALUE, 209 NULL, 210 &hKey, 211 NULL); 212 if (FAILED(hr)) { 213 goto Clean; 214 } 215 216 // 217 // Failure to save the user's idle/wake settings is not critical and we 218 // will continue on regardless. Hence we ignore the return value. 219 // 220 err = RegSetValueEx(hKey, 221 ValueName->Buffer, 222 0, 223 REG_DWORD, 224 (BYTE *) &Value, 225 sizeof(Value)); 226 if (err != ERROR_SUCCESS) { 227 DoTraceLevelMessage(GetDriverGlobals(), 228 TRACE_LEVEL_ERROR, 229 TRACINGPNP, 230 "Failed to set Registry value " 231 "for S0Idle/SxWake error %d", 232 err); 233 goto Clean; 234 } 235 236 Clean: 237 if (NULL != hKey) { 238 RegCloseKey(hKey); 239 } 240 } 241 242 NTSTATUS 243 FxPkgPnp::UpdateWmiInstanceForS0Idle( 244 __in FxWmiInstanceAction Action 245 ) 246 { 247 NTSTATUS status; 248 249 // 250 // Send an IOCTL to redirector 251 // to add/remove S0Idle WMI instance. 252 // 253 status = UpdateWmiInstance(Action, TRUE); 254 255 return status; 256 } 257 258 VOID 259 FxPkgPnp::ReadRegistryS0Idle( 260 __in PCUNICODE_STRING ValueName, 261 __out BOOLEAN *Enabled 262 ) 263 { 264 NTSTATUS status; 265 ULONG value; 266 267 status = ReadStateFromRegistry(ValueName, &value); 268 269 // 270 // Modify value of Enabled only if success 271 // 272 if (NT_SUCCESS(status)) { 273 // 274 // Normalize the ULONG value into a BOOLEAN 275 // 276 *Enabled = (value == FALSE) ? FALSE : TRUE; 277 } 278 } 279 280 NTSTATUS 281 FxPkgPnp::UpdateWmiInstanceForSxWake( 282 __in FxWmiInstanceAction Action 283 ) 284 { 285 NTSTATUS status; 286 287 // 288 // Send an IOCTL to redirector 289 // to add/remove SxWake WMI instance. 290 // 291 status = UpdateWmiInstance(Action, FALSE); 292 293 return status; 294 } 295 296 VOID 297 FxPkgPnp::ReadRegistrySxWake( 298 __in PCUNICODE_STRING ValueName, 299 __out BOOLEAN *Enabled 300 ) 301 { 302 NTSTATUS status; 303 ULONG value; 304 305 status = ReadStateFromRegistry(ValueName, &value); 306 307 // 308 // Modify value of Enabled only if success 309 // 310 if (NT_SUCCESS(status)) { 311 // 312 // Normalize the ULONG value into a BOOLEAN 313 // 314 *Enabled = (value == FALSE) ? FALSE : TRUE; 315 } 316 } 317 318 VOID 319 PnpPassThroughQIWorker( 320 __in MxDeviceObject* Device, 321 __inout FxIrp* Irp, 322 __inout FxIrp* ForwardIrp 323 ) 324 { 325 UNREFERENCED_PARAMETER(Device); 326 UNREFERENCED_PARAMETER(Irp); 327 UNREFERENCED_PARAMETER(ForwardIrp); 328 ASSERTMSG("Not implemented for UMDF\n", FALSE); 329 } 330 331 332 VOID 333 FxPkgPnp::RevokeDmaEnablerResources( 334 __in FxDmaEnabler * /* DmaEnabler */ 335 ) 336 { 337 // Do nothing 338 } 339 340