1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxWmiApi.cpp 8 9 Abstract: 10 11 This module implements the C interface to the WMI package 12 for the driver frameworks. 13 14 Author: 15 16 17 18 Environment: 19 20 Kernel mode only 21 22 Revision History: 23 24 25 26 --*/ 27 28 #include "fxwmipch.hpp" 29 30 // 31 // Extern "C" the tmh file and all external APIs 32 // 33 extern "C" { 34 #include "fxwmiapi.tmh" 35 36 _Must_inspect_result_ 37 __drv_maxIRQL(DISPATCH_LEVEL) 38 NTSTATUS 39 WDFEXPORT(WdfWmiProviderCreate)( 40 __in 41 PWDF_DRIVER_GLOBALS DriverGlobals, 42 __in 43 WDFDEVICE Device, 44 __in 45 PWDF_WMI_PROVIDER_CONFIG WmiProviderConfig, 46 __in_opt 47 PWDF_OBJECT_ATTRIBUTES ProviderAttributes, 48 __out 49 WDFWMIPROVIDER* WmiProvider 50 ) 51 { 52 FxDevice* pDevice; 53 FxPowerPolicyOwnerSettings* ownerSettings; 54 FxWmiProvider* pProvider; 55 56 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 57 Device, 58 FX_TYPE_DEVICE, 59 (PVOID*) &pDevice); 60 61 FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), WmiProviderConfig); 62 FxPointerNotNull(GetFxDriverGlobals(DriverGlobals), WmiProvider); 63 64 // 65 // If the Device is a power policy owner then do not allow client drivers 66 // to register for GUID_POWER_DEVICE_ENABLE or GUID_POWER_DEVICE_WAKE_ENABLE 67 // if the framework has already register a provider for those guids. 68 // 69 if (pDevice->m_PkgPnp->IsPowerPolicyOwner()) { 70 ownerSettings = pDevice->m_PkgPnp->m_PowerPolicyMachine.m_Owner; 71 72 if ((FxIsEqualGuid(&WmiProviderConfig->Guid, 73 &GUID_POWER_DEVICE_ENABLE) && 74 ownerSettings->m_IdleSettings.WmiInstance != NULL) || 75 76 (FxIsEqualGuid(&WmiProviderConfig->Guid, 77 &GUID_POWER_DEVICE_WAKE_ENABLE) && 78 ownerSettings->m_WakeSettings.WmiInstance != NULL)) { 79 80 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_ERROR, 81 TRACINGDEVICE, "WMI Guid already registered by " 82 "framework"); 83 return STATUS_WMI_GUID_DISCONNECTED; 84 } 85 } 86 87 return FxWmiProvider::_Create(GetFxDriverGlobals(DriverGlobals), 88 Device, 89 ProviderAttributes, 90 WmiProviderConfig, 91 WmiProvider, 92 &pProvider); 93 } 94 95 _Must_inspect_result_ 96 __drv_maxIRQL(DISPATCH_LEVEL) 97 NTSTATUS 98 WDFEXPORT(WdfWmiInstanceCreate)( 99 __in 100 PWDF_DRIVER_GLOBALS DriverGlobals, 101 __in 102 WDFDEVICE Device, 103 __in 104 PWDF_WMI_INSTANCE_CONFIG InstanceConfig, 105 __in_opt 106 PWDF_OBJECT_ATTRIBUTES InstanceAttributes, 107 __out_opt 108 WDFWMIINSTANCE* Instance 109 ) 110 { 111 PFX_DRIVER_GLOBALS pFxDriverGlobals; 112 FxWmiProvider* pProvider; 113 FxWmiInstanceExternal* pInstance; 114 WDFWMIINSTANCE hInstance; 115 NTSTATUS status; 116 117 pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals); 118 pInstance = NULL; 119 120 FxPointerNotNull(pFxDriverGlobals, InstanceConfig); 121 122 if (InstanceConfig->Size != sizeof(WDF_WMI_INSTANCE_CONFIG)) { 123 status = STATUS_INFO_LENGTH_MISMATCH; 124 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 125 "Expected InstanceConfig Size %d, got %d, %!STATUS!", 126 InstanceConfig->Size, sizeof(*InstanceConfig), 127 status); 128 return status; 129 } 130 131 if (InstanceConfig->Provider == NULL && 132 InstanceConfig->ProviderConfig == NULL) { 133 status = STATUS_INVALID_PARAMETER; 134 135 DoTraceLevelMessage( 136 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 137 "InstanceConfig %p Provider and ProviderConfig are both NULL, only " 138 "one can be, %!STATUS!", InstanceConfig, status); 139 140 return status; 141 } 142 else if (InstanceConfig->Provider != NULL && 143 InstanceConfig->ProviderConfig != NULL) { 144 status = STATUS_INVALID_PARAMETER; 145 146 DoTraceLevelMessage( 147 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 148 "InstanceConfig %p Provider %p and ProviderConfig %p are both not " 149 "NULL, only one can be, %!STATUS!", InstanceConfig, 150 InstanceConfig->Provider, InstanceConfig->ProviderConfig, status); 151 152 return status; 153 } 154 155 if (InstanceConfig->Provider != NULL) { 156 FxObjectHandleGetPtrAndGlobals(pFxDriverGlobals, 157 InstanceConfig->Provider, 158 FX_TYPE_WMI_PROVIDER, 159 (PVOID*) &pProvider, 160 &pFxDriverGlobals); 161 } 162 else { 163 FxDevice* pDevice; 164 FxPowerPolicyOwnerSettings* ownerSettings; 165 WDFWMIPROVIDER hProvider; 166 167 hProvider = NULL; 168 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 169 Device, 170 FX_TYPE_DEVICE, 171 (PVOID*) &pDevice); 172 173 // 174 // If the Device is a power policy owner then do not allow client drivers 175 // to register for GUID_POWER_DEVICE_ENABLE or GUID_POWER_DEVICE_WAKE_ENABLE 176 // if the framework has already register a provider for those guids. 177 // 178 if (pDevice->m_PkgPnp->IsPowerPolicyOwner()) { 179 ownerSettings = pDevice->m_PkgPnp->m_PowerPolicyMachine.m_Owner; 180 181 if ((FxIsEqualGuid(&InstanceConfig->ProviderConfig->Guid, 182 &GUID_POWER_DEVICE_ENABLE) && 183 ownerSettings->m_IdleSettings.WmiInstance != NULL) || 184 185 (FxIsEqualGuid(&InstanceConfig->ProviderConfig->Guid, 186 &GUID_POWER_DEVICE_WAKE_ENABLE) && 187 ownerSettings->m_WakeSettings.WmiInstance != NULL)) { 188 189 status = STATUS_WMI_GUID_DISCONNECTED; 190 DoTraceLevelMessage(GetFxDriverGlobals(DriverGlobals), TRACE_LEVEL_ERROR, 191 TRACINGDEVICE, "WMI Guid already registered by " 192 "framework"); 193 return status; 194 } 195 } 196 197 status = FxWmiProvider::_Create(pFxDriverGlobals, 198 Device, 199 NULL, 200 InstanceConfig->ProviderConfig, 201 &hProvider, 202 &pProvider); 203 204 if (!NT_SUCCESS(status)) { 205 return status; 206 } 207 208 // 209 // Use the object's globals and not the caller's 210 // 211 pFxDriverGlobals = pProvider->GetDriverGlobals(); 212 } 213 214 status = FxWmiInstanceExternal::_Create(pFxDriverGlobals, 215 pProvider, 216 InstanceConfig, 217 InstanceAttributes, 218 &hInstance, 219 &pInstance); 220 221 if (NT_SUCCESS(status) && InstanceConfig->Register) { 222 status = pProvider->AddInstance(pInstance); 223 } 224 225 if (NT_SUCCESS(status)) { 226 if (Instance != NULL) { 227 *Instance = hInstance; 228 } 229 } 230 else { 231 // 232 // Something went wrong, cleanup 233 // 234 if (pInstance != NULL) { 235 // 236 // This will remove the instance from the provider's list as well. 237 // 238 pInstance->DeleteFromFailedCreate(); 239 } 240 241 // 242 // Only remove the provider if we created it in this function 243 // 244 if (InstanceConfig->ProviderConfig != NULL) { 245 pProvider->DeleteFromFailedCreate(); 246 } 247 } 248 249 return status; 250 } 251 252 WDFAPI 253 __drv_maxIRQL(DISPATCH_LEVEL) 254 WDFDEVICE 255 WDFEXPORT(WdfWmiProviderGetDevice)( 256 __in 257 PWDF_DRIVER_GLOBALS DriverGlobals, 258 __in 259 WDFWMIPROVIDER WmiProvider 260 ) 261 { 262 FxWmiProvider *pProvider; 263 264 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 265 WmiProvider, 266 FX_TYPE_WMI_PROVIDER, 267 (PVOID*) &pProvider); 268 269 return pProvider->GetDevice()->GetHandle(); 270 } 271 272 __drv_maxIRQL(DISPATCH_LEVEL) 273 BOOLEAN 274 WDFEXPORT(WdfWmiProviderIsEnabled)( 275 __in 276 PWDF_DRIVER_GLOBALS DriverGlobals, 277 __in 278 WDFWMIPROVIDER WmiProvider, 279 __in 280 WDF_WMI_PROVIDER_CONTROL ProviderControl 281 ) 282 { 283 FxWmiProvider *pProvider; 284 285 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 286 WmiProvider, 287 FX_TYPE_WMI_PROVIDER, 288 (PVOID*) &pProvider); 289 290 return pProvider->IsEnabled(ProviderControl); 291 } 292 293 __drv_maxIRQL(DISPATCH_LEVEL) 294 ULONGLONG 295 WDFEXPORT(WdfWmiProviderGetTracingHandle)( 296 __in 297 PWDF_DRIVER_GLOBALS DriverGlobals, 298 __in 299 WDFWMIPROVIDER WmiProvider 300 ) 301 { 302 FxWmiProvider *pProvider; 303 304 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 305 WmiProvider, 306 FX_TYPE_WMI_PROVIDER, 307 (PVOID*) &pProvider); 308 309 return pProvider->GetTracingHandle(); 310 } 311 312 _Must_inspect_result_ 313 __drv_maxIRQL(DISPATCH_LEVEL) 314 NTSTATUS 315 WDFEXPORT(WdfWmiInstanceRegister)( 316 __in 317 PWDF_DRIVER_GLOBALS DriverGlobals, 318 __in 319 WDFWMIINSTANCE WmiInstance 320 ) 321 { 322 FxWmiInstanceExternal* pInstance; 323 FxWmiProvider* pProvider; 324 325 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 326 WmiInstance, 327 FX_TYPE_WMI_INSTANCE, 328 (PVOID*) &pInstance); 329 330 pProvider = pInstance->GetProvider(); 331 332 return pProvider->AddInstance(pInstance); 333 } 334 335 __drv_maxIRQL(DISPATCH_LEVEL) 336 VOID 337 WDFEXPORT(WdfWmiInstanceDeregister)( 338 __in 339 PWDF_DRIVER_GLOBALS DriverGlobals, 340 __in 341 WDFWMIINSTANCE WmiInstance 342 ) 343 { 344 FxWmiInstanceExternal* pInstance; 345 FxWmiProvider* pProvider; 346 347 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 348 WmiInstance, 349 FX_TYPE_WMI_INSTANCE, 350 (PVOID*) &pInstance); 351 352 pProvider = pInstance->GetProvider(); 353 pProvider->RemoveInstance(pInstance); 354 } 355 356 __drv_maxIRQL(DISPATCH_LEVEL) 357 WDFDEVICE 358 WDFEXPORT(WdfWmiInstanceGetDevice)( 359 __in 360 PWDF_DRIVER_GLOBALS DriverGlobals, 361 __in 362 WDFWMIINSTANCE WmiInstance 363 ) 364 { 365 FxWmiInstanceExternal* pInstance; 366 367 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 368 WmiInstance, 369 FX_TYPE_WMI_INSTANCE, 370 (PVOID*) &pInstance); 371 372 return pInstance->GetDevice()->GetHandle(); 373 } 374 375 __drv_maxIRQL(DISPATCH_LEVEL) 376 WDFWMIPROVIDER 377 WDFEXPORT(WdfWmiInstanceGetProvider)( 378 __in 379 PWDF_DRIVER_GLOBALS DriverGlobals, 380 __in 381 WDFWMIINSTANCE WmiInstance 382 ) 383 { 384 FxWmiInstanceExternal *pInstance; 385 386 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 387 WmiInstance, 388 FX_TYPE_WMI_INSTANCE, 389 (PVOID*) &pInstance); 390 391 return pInstance->GetProvider()->GetHandle(); 392 } 393 394 395 _Must_inspect_result_ 396 __drv_maxIRQL(APC_LEVEL) 397 NTSTATUS 398 WDFEXPORT(WdfWmiInstanceFireEvent)( 399 __in 400 PWDF_DRIVER_GLOBALS DriverGlobals, 401 __in 402 WDFWMIINSTANCE WmiInstance, 403 __in_opt 404 ULONG EventDataSize, 405 __in_bcount_opt(EventDataSize) 406 PVOID EventData 407 ) 408 /*++ 409 410 Routine Description: 411 Fires an event based on the instance handle. 412 413 Arguments: 414 WmiInstance - instance which the event is associated with 415 EventDataSize - size of EventData in bytes 416 EventData - buffer associated with the event 417 418 Return Value: 419 NTSTATUS 420 421 --*/ 422 { 423 FxWmiInstanceExternal* pInstance; 424 NTSTATUS status; 425 426 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), 427 WmiInstance, 428 FX_TYPE_WMI_INSTANCE, 429 (PVOID*) &pInstance); 430 431 status = FxVerifierCheckIrqlLevel(pInstance->GetDriverGlobals(), APC_LEVEL); 432 if (!NT_SUCCESS(status)) { 433 return status; 434 } 435 436 return pInstance->FireEvent(EventData, EventDataSize); 437 } 438 439 } // extern "C" 440