Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530/*++
Copyright (c) Microsoft Corporation
Module Name:
FxDriverApi.cpp
Abstract:
This module contains the "C" interface for the FxDriver object.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "coreprivshared.hpp"
// Tracing supportextern "C" {#include <ntverp.h>// #include "FxDriverApi.tmh"}
#include "fxtelemetry.hpp"
//// extern the whole file//extern "C" {
//// Driver Pool Allocations//
__drv_maxIRQL(PASSIVE_LEVEL)PWSTRNTAPIWDFEXPORT(WdfDriverGetRegistryPath)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDRIVER Driver ){ DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals; NTSTATUS status; FxDriver *pDriver;
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Driver, FX_TYPE_DRIVER, (PVOID *)&pDriver, &pFxDriverGlobals);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return NULL; }
return pDriver->GetRegistryPathUnicodeString()->Buffer;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfDriverCreate)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in MdDriverObject DriverObject, __in PCUNICODE_STRING RegistryPath, __in_opt PWDF_OBJECT_ATTRIBUTES DriverAttributes, __in PWDF_DRIVER_CONFIG DriverConfig, __out_opt WDFDRIVER* Driver ){ DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals; FxDriver *pDriver; NTSTATUS status; WDFDRIVER hDriver; const LONG validFlags = WdfDriverInitNonPnpDriver | WdfDriverInitNoDispatchOverride;
hDriver = NULL; pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
FxPointerNotNull(pFxDriverGlobals, DriverObject); FxPointerNotNull(pFxDriverGlobals, RegistryPath); FxPointerNotNull(pFxDriverGlobals, DriverConfig);
// // Validate the size of the input Driver Config structure. The size changed // after v1.1. The size is the same for v1.1 and v1.0, verify that. // WDFCASSERT(sizeof(WDF_DRIVER_CONFIG_V1_0) == sizeof(WDF_DRIVER_CONFIG_V1_1));
if (DriverConfig->Size != sizeof(WDF_DRIVER_CONFIG) && DriverConfig->Size != sizeof(WDF_DRIVER_CONFIG_V1_1)) {
status = STATUS_INFO_LENGTH_MISMATCH; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDRIVER, "WDF_DRIVER_CONFIG got Size %d, expected v1.1 size %d or cur ver size %d, %!STATUS!", DriverConfig->Size, sizeof(WDF_DRIVER_CONFIG_V1_1), sizeof(WDF_DRIVER_CONFIG), status);
return status; }
// // Validate the DriverInitFlags value in the Driver Config. // if ((DriverConfig->DriverInitFlags & ~validFlags) != 0) { status = STATUS_INVALID_PARAMETER; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDRIVER, "DriverInitFlags 0x%x invalid, valid flags are 0x%x, %!STATUS!", DriverConfig->DriverInitFlags, validFlags, status); return status; }
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return status; }
status = FxValidateUnicodeString(pFxDriverGlobals, RegistryPath); if (!NT_SUCCESS(status)) { return status; }
// // Driver and Public.Driver are set once WdfDriverCreate returns successfully. // If they are set, that means this DDI has already been called for this // client. Return an error if this occurrs. // if (pFxDriverGlobals->Driver != NULL || pFxDriverGlobals->Public.Driver != NULL) {
status = STATUS_DRIVER_INTERNAL_ERROR;
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDRIVER, "WdfDriverCreate can only be called one time per " "WDM PDRIVER_OBJECT %p, %!STATUS!", DriverObject, status);
return status; }
if (Driver != NULL) { *Driver = NULL; }
// // Initializing the tag requires initializing the driver name first. // FxDriver::_InitializeDriverName(pFxDriverGlobals, RegistryPath);
// // Initialize the tag before any allocation so that we can use the correct // tag value when allocating on behalf of the driver (for all allocations, // including FxDriver). // // Use the client's driver tag value if they specified one. First check // to make sure the size of the structure is the new size (vs the old size // in v1.1). // // ' kdD' - was the default tag in many DDKs, don't allow its use. // if (DriverConfig->Size == sizeof(WDF_DRIVER_CONFIG) && DriverConfig->DriverPoolTag != 0x0 && DriverConfig->DriverPoolTag != ' kdD') { // // Copy directly using the driver's value // pFxDriverGlobals->Tag = DriverConfig->DriverPoolTag; pFxDriverGlobals->Public.DriverTag = DriverConfig->DriverPoolTag; } else { // // Derive the value from the driver's service name // FxDriver::_InitializeTag(pFxDriverGlobals, DriverConfig); }
// // Check to see if this is an NT4 style device driver. If so, fail if they // specified an AddDevice routine. If no dispatch override is set, // do not do any checking at all. // if (DriverConfig->DriverInitFlags & WdfDriverInitNoDispatchOverride) { DO_NOTHING(); } else if ((DriverConfig->DriverInitFlags & WdfDriverInitNonPnpDriver) && DriverConfig->EvtDriverDeviceAdd != NULL) {
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDRIVER, "Invalid Driver flags or EvtDriverDeviceAdd callback already added" "STATUS_INVALID_PARAMETER");
return STATUS_INVALID_PARAMETER; }
status = FxValidateObjectAttributes(pFxDriverGlobals, DriverAttributes, (FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED | FX_VALIDATE_OPTION_EXECUTION_LEVEL_ALLOWED | FX_VALIDATE_OPTION_SYNCHRONIZATION_SCOPE_ALLOWED) );
if (!NT_SUCCESS(status)) { return status; }
// // FxDriver stores the driver wide configuration // FxInitialize(pFxDriverGlobals, DriverObject, RegistryPath, DriverConfig);
// // FxDriver stores the driver wide configuration // pDriver = new(pFxDriverGlobals, DriverAttributes) FxDriver(DriverObject, DriverConfig, pFxDriverGlobals);
if (pDriver != NULL) {
if (NT_SUCCESS(status)) {
status = pDriver->Initialize(RegistryPath, DriverConfig, DriverAttributes);
if (NT_SUCCESS(status)) { status = pDriver->Commit(DriverAttributes, (WDFOBJECT*)&hDriver, FALSE); } } } else { status = STATUS_INSUFFICIENT_RESOURCES; }
// // Only return a valid handle on success. Upon error, release any memory // and do not rely on any other function (like the driver unload routine) to // be called. // if (NT_SUCCESS(status)) { // // **** Note **** // Do not introduce failures after this point without ensuring // FxObject::DeleteFromFailedCreate has a chance to clear out any // assigned callbacks on the object. //
// // Store the WDFDRIVER and FxDriver* globally so the driver can retrieve // it anytime. // pFxDriverGlobals->Driver = pDriver; pFxDriverGlobals->Public.Driver = hDriver;
// // Record the flags so that diagnostics knows what type of driver it is. // pFxDriverGlobals->Public.DriverFlags |= DriverConfig->DriverInitFlags;
if (DriverConfig->DriverInitFlags & (WdfDriverInitNoDispatchOverride | WdfDriverInitNonPnpDriver)) { // // If there is no dispatch override or if it is an NT4 legacy style // driver then we will not displace unload in the stub if one was not // specified. // if (DriverConfig->EvtDriverUnload != NULL) { pFxDriverGlobals->Public.DisplaceDriverUnload = TRUE; } else { pFxDriverGlobals->Public.DisplaceDriverUnload = FALSE; } } else { pFxDriverGlobals->Public.DisplaceDriverUnload = TRUE; }
if (Driver != NULL) { *Driver = hDriver; }
#ifndef __REACTOS__ if (FX_TELEMETRY_ENABLED(g_TelemetryProvider, pFxDriverGlobals)) { FxAutoString imageName;
#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) const PWCHAR pVersionStr = FX_MAKE_WSTR(__WDF_MAJOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WDF_MINOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WDF_BUILD_NUMBER) ;#else // USER_MODE const PWCHAR pVersionStr = FX_MAKE_WSTR(__WUDF_MAJOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WUDF_MINOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WUDF_SERVICE_VERSION) ;#endif
// // GetImageName can fail if the registry cannot be accessed. This // can happen during system shutdown. Since the image name is only // used for telemetry the failure can be ignored. // (VOID) GetImageName(pFxDriverGlobals, &imageName.m_UnicodeString);
WDF_CENSUS_EVT_WRITE_DRIVER_LOAD(g_TelemetryProvider, pFxDriverGlobals, imageName.m_UnicodeString.Buffer, pVersionStr); }#endif // __REACTOS__ } else { if (pDriver != NULL) { pDriver->DeleteFromFailedCreate(); }
FxDestroy(pFxDriverGlobals); }
return status;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfDriverRegisterTraceInfo)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in PDRIVER_OBJECT DriverObject, __in PFN_WDF_TRACE_CALLBACK EvtTraceCallback, __in PVOID ControlBlock ){ DDI_ENTRY();
UNREFERENCED_PARAMETER(DriverGlobals); UNREFERENCED_PARAMETER(DriverObject); UNREFERENCED_PARAMETER(EvtTraceCallback); UNREFERENCED_PARAMETER(ControlBlock);
return STATUS_NOT_SUPPORTED;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)NTSTATUSNTAPIWDFEXPORT(WdfDriverRetrieveVersionString)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDRIVER Driver, __in WDFSTRING String ){ DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals; FxDriver* pDriver; FxString* pString; NTSTATUS status;
#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) const PWCHAR pVersionStr = L"Kernel Mode Driver Framework version " FX_MAKE_WSTR(__WDF_MAJOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WDF_MINOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WDF_BUILD_NUMBER) ;
const PWCHAR pVersionStrVerifier = L"Kernel Mode Driver Framework (verifier on) version " FX_MAKE_WSTR(__WDF_MAJOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WDF_MINOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WDF_BUILD_NUMBER);#else // USER_MODE const PWCHAR pVersionStr = L"User Mode Driver Framework version " FX_MAKE_WSTR(__WUDF_MAJOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WUDF_MINOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WUDF_SERVICE_VERSION) ;
const PWCHAR pVersionStrVerifier = L"User Mode Driver Framework (verifier on) version " FX_MAKE_WSTR(__WUDF_MAJOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WUDF_MINOR_VERSION_STRING) L"." FX_MAKE_WSTR(__WUDF_SERVICE_VERSION);#endif
// // Even though it is unused, still convert it to make sure a valid handle is // being passed in. // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Driver, FX_TYPE_DRIVER, (PVOID *)&pDriver, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, String);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return status; }
FxObjectHandleGetPtr(pFxDriverGlobals, String, FX_TYPE_STRING, (PVOID *)&pString);
status = pString->Assign( pFxDriverGlobals->FxVerifierOn ? pVersionStrVerifier : pVersionStr );
return status;}
_Must_inspect_result___drv_maxIRQL(PASSIVE_LEVEL)BOOLEANNTAPIWDFEXPORT(WdfDriverIsVersionAvailable)( __in PWDF_DRIVER_GLOBALS DriverGlobals, __in WDFDRIVER Driver, __in PWDF_DRIVER_VERSION_AVAILABLE_PARAMS VersionAvailableParams ){ DDI_ENTRY();
PFX_DRIVER_GLOBALS pFxDriverGlobals; FxDriver* pDriver; NTSTATUS status; ULONG major, minor;
#if (FX_CORE_MODE == FX_CORE_KERNEL_MODE) major = __WDF_MAJOR_VERSION; minor = __WDF_MINOR_VERSION;#else major = __WUDF_MAJOR_VERSION; minor = __WUDF_MINOR_VERSION;#endif
// // Even though it is unused, still convert it to make sure a valid handle is // being passed in. // FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Driver, FX_TYPE_DRIVER, (PVOID *)&pDriver, &pFxDriverGlobals);
FxPointerNotNull(pFxDriverGlobals, VersionAvailableParams);
status = FxVerifierCheckIrqlLevel(pFxDriverGlobals, PASSIVE_LEVEL); if (!NT_SUCCESS(status)) { return FALSE; }
if (VersionAvailableParams->Size != sizeof(WDF_DRIVER_VERSION_AVAILABLE_PARAMS)) { status = STATUS_INFO_LENGTH_MISMATCH;
DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDRIVER, "VersionAvailableParams Size 0x%x, expected 0x%x, %!STATUS!", VersionAvailableParams->Size, sizeof(WDF_DRIVER_VERSION_AVAILABLE_PARAMS), status);
return FALSE; }
// // We log at TRACE_LEVEL_INFORMATION so that we know it gets into the IFR at // all times. This will make it easier to debug drivers which fail to load // when a new minor version of WDF is installed b/c they are failing // version checks. // DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER, "IsVersionAvailable, current WDF ver major %d, minor %d, caller asking " "about major %d, minor %d", major, minor, VersionAvailableParams->MajorVersion, VersionAvailableParams->MinorVersion);
// // Currently we only support one major version per KMDF binary and we support // all minor versions of that major version down to 0x0. // if (VersionAvailableParams->MajorVersion == major && VersionAvailableParams->MinorVersion <= minor) { return TRUE; }
return FALSE;}
} // extern "C"