Beispiel #1
0
//------------------------------------------------------------------------
// NotifyNowayAssert: Notification that a noway handling is under-way.
//
//  Arguments:
//      filename - The JIT source file name's absolute path at the time of
//                 building the JIT.
//      line     - The line number where the noway assert was hit.
//
//  Description:
//      If telemetry is enabled, then obtain data to collect from the
//      compiler or the VM and use the tracelogging APIs to write out.
//
void JitTelemetry::NotifyNowayAssert(const char* filename, unsigned line)
{
    if (!IsTelemetryEnabled())
    {
        return;
    }

    s_uMethodsHitNowayAssert++;

    // Check if our assumption that noways are rare is invalid for this
    // process. If so, return early than logging too much data.
    unsigned noways = s_uMethodsHitNowayAssert;
    unsigned attempts = max(1, s_uMethodsCompiled + noways);
    double ratio = (noways / ((double) attempts));
    if (noways > NOWAY_SUFFICIENCY_THRESHOLD && ratio > NOWAY_NOISE_RATIO)
    {
        return;
    }

    assert(comp);

    UINT32 nowayIndex = s_uMethodsHitNowayAssert;
    UINT32 codeSize = 0;
    INT32 minOpts = -1;
    const char* lastPhase = "";
    if (comp != nullptr)
    {
        codeSize = comp->info.compILCodeSize;
        minOpts = comp->opts.IsMinOptsSet() ? comp->opts.MinOpts() : -1;
        lastPhase = PhaseNames[comp->previousCompletedPhase];
    }
    
    CacheCurrentMethodInfo();

    TraceLoggingWrite(g_hClrJitProvider,
        "CLRJIT.NowayAssert",
        
        TraceLoggingUInt32(codeSize, "IL_CODE_SIZE"),
        TraceLoggingInt32(minOpts, "MINOPTS_MODE"),
        TraceLoggingString(lastPhase, "PREVIOUS_COMPLETED_PHASE"),

        TraceLoggingString(m_pszAssemblyName, "ASSEMBLY_NAME"),
        TraceLoggingString(m_pszMethodName, "METHOD_NAME"),
        TraceLoggingString(m_pszScopeName, "METHOD_SCOPE"),
        TraceLoggingUInt32(m_uMethodHash, "METHOD_HASH"),
        
        TraceLoggingString(filename, "FILENAME"),
        TraceLoggingUInt32(line, "LINE"),
        TraceLoggingUInt32(nowayIndex, "NOWAY_INDEX"),
        
        TraceLoggingString(TARGET_READABLE_NAME, "ARCH"),
        TraceLoggingString(VER_FILEVERSION_STR, "VERSION"),
        TraceLoggingString(BUILD_MACHINE, "BUILD"),
        TraceLoggingString(VER_COMMENTS_STR, "FLAVOR"),

        TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY));
}
NTSTATUS
NfcCxEvtUnregisterSequenceHandler(
    _In_ PNFCCX_DRIVER_GLOBALS NfcCxGlobals,
    _In_ WDFDEVICE Device,
    _In_ NFC_CX_SEQUENCE Sequence
    )
/*++

Routine Description:

    This routine is called by the CX client to unregister
    a previously registered sequence handler

Arguments:

    NfcCxGlobal - CX global pointer
    Device - WDF device to initialize
    Sequence - The sequence to unregister

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS status = STATUS_SUCCESS;
    PNFCCX_FDO_CONTEXT fdoContext;

    TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);

    if (!VerifyPrivateGlobals(NfcCxGlobals)) {
        TRACE_LINE(LEVEL_ERROR, "Invalid CX global pointer");
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    if (SequenceMaximum <= Sequence) {
        TRACE_LINE(LEVEL_ERROR, "Invalid Client Driver Parameters");
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    fdoContext = NfcCxFdoGetContext(Device);

    if (fdoContext->RFInterface == NULL) {
        TRACE_LINE(LEVEL_ERROR, "CX not initialized");
        status = STATUS_INVALID_DEVICE_STATE;
        goto Done;
    }

    TraceLoggingWrite(
        g_hNfcCxProvider,
        "NfcCxEvtUnregisterSequence",
        TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY),
        TraceLoggingValue((DWORD)Sequence, "sequence"));

    status = NfcCxRFInterfaceUnregisterSequenceHandler(fdoContext->RFInterface, Sequence);

Done:

    TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
    return status;
}
NTSTATUS
NfcCxEvtDeviceInitConfig(
    _In_ PNFCCX_DRIVER_GLOBALS NfcCxGlobals,
    _In_ PWDFDEVICE_INIT DeviceInit,
    _In_ PNFC_CX_CLIENT_CONFIG Config
    )
/*++
Routine Description:

    NfcCxEvtDeviceInitConfig is called by the client driver from within
    its AddDevice callback to finish initializing the device before creation.

Arguments:

    NfcCxGlobals - Pointer to the Class extension globals
    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
    Config - Pointer to a client provided structure with their configuration.

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS                          status = STATUS_SUCCESS; 
    WDFCX_FILEOBJECT_CONFIG           fileConfig;
    WDF_OBJECT_ATTRIBUTES             fileObjectAttributes;
    PWDFCXDEVICE_INIT                 exDeviceInit;
    PNFCCX_CLIENT_GLOBALS             nfcCxClientGlobal;

    TRACE_FUNCTION_ENTRY(LEVEL_VERBOSE);

    if (!VerifyPrivateGlobals(NfcCxGlobals)) {
        TRACE_LINE(LEVEL_ERROR, "Invalid CX global pointer");
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    if (NULL == Config ||
        sizeof(NFC_CX_CLIENT_CONFIG) != Config->Size ||
        NULL == Config->EvtNfcCxWriteNciPacket) {
        TRACE_LINE(LEVEL_ERROR, "Invalid Client Driver Configuration");
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    if (NFC_CX_DEVICE_MODE_NCI != Config->DeviceMode &&
        NFC_CX_DEVICE_MODE_DTA != Config->DeviceMode &&
        NFC_CX_DEVICE_MODE_RAW != Config->DeviceMode) {
        TRACE_LINE(LEVEL_ERROR, "Invalid Client Driver Device Mode %d", Config->DeviceMode);
        status = STATUS_INVALID_PARAMETER;
        goto Done;
    }

    nfcCxClientGlobal = GetPrivateGlobals(NfcCxGlobals);

    //
    // The CX is the power policy owner of this stack.
    //
    WdfDeviceInitSetPowerPolicyOwnership(DeviceInit, TRUE);

    //
    // Allocate the CX DeviceInit
    //
    exDeviceInit = WdfCxDeviceInitAllocate(DeviceInit);
    if (NULL == exDeviceInit) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TRACE_LINE(LEVEL_ERROR,
            "Failed WdfCxDeviceInitAllocate, status=%!STATUS!", status);
        goto Done;
    }

    //
    // Enable SelfIoTarget
    //
    WdfDeviceInitAllowSelfIoTarget(DeviceInit);

    //
    // Initialize WDF_FILEOBJECT_CONFIG_INIT struct to tell the
    // per handle (fileobject) context.
    //
    WDFCX_FILEOBJECT_CONFIG_INIT(
                            &fileConfig,
                            NfcCxEvtDeviceFileCreate,
                            NfcCxEvtFileClose,
                            WDF_NO_EVENT_CALLBACK // not interested in Cleanup
                            );

    WDF_OBJECT_ATTRIBUTES_INIT(&fileObjectAttributes);
    fileObjectAttributes.SynchronizationScope = WdfSynchronizationScopeNone;

    WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&fileObjectAttributes,
                                            NFCCX_FILE_CONTEXT);

    WdfCxDeviceInitSetFileObjectConfig(exDeviceInit,
                                       &fileConfig,
                                       &fileObjectAttributes);

    TRACE_LINE(LEVEL_INFO, "DriverFlags=0x%x PowerIdleType=%d PowerIdleTimeout=%d",
                            Config->DriverFlags, Config->PowerIdleType, Config->PowerIdleTimeout);

    TraceLoggingWrite(g_hNfcCxProvider,
        "NfcCxClientConfig",
        TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY),
        TraceLoggingHexInt32(Config->DriverFlags, "DriverFlags"),
        TraceLoggingValue((INT32)(Config->PowerIdleType), "PowerIdleType"),
        TraceLoggingValue(Config->PowerIdleTimeout, "PowerIdleTimeout"));

    //
    // Save the client driver configs
    //
    RtlCopyMemory(&nfcCxClientGlobal->Config, Config, Config->Size);

Done:
    
    TRACE_FUNCTION_EXIT_NTSTATUS(LEVEL_VERBOSE, status);
    TRACE_LOG_NTSTATUS_ON_FAILURE(status);
    
    return status;
}