Delen via


Activiteit-id-GUID's gebruiken in USB ETW-traceringen

Dit onderwerp bevat informatie over GUID's voor activiteits-id's, het toevoegen van deze GUID's in de gebeurtenistraceringsproviders en het weergeven ervan in Netmon.

Stuurprogramma's in de USB-stuurprogrammastack (zowel 2.0 als 3.0) zijn ETW-gebeurtenistraceringsproviders. In Windows 7 kunt u tijdens het vastleggen van gebeurtenistraceringen van de USB-stuurprogrammastack traceringen van andere providers, zoals andere stuurprogramma's en toepassingen, vastleggen. U kunt vervolgens het gecombineerde logboek lezen (ervan uitgaande dat u een Netmon-parser hebt gemaakt voor de gebeurtenistraceringen van uw provider).

Vanaf Windows 8 kunt u gebeurtenissen koppelen tussen providers (zoals toepassingen, clientstuurprogramma's en de USB-stuurprogrammastack) met behulp van activiteit-ID-GUID's. Gebeurtenissen van meerdere providers kunnen worden gekoppeld in Netmon wanneer de gebeurtenissen dezelfde activiteits-id-GUID hebben. Op basis van deze GUID's kan Netmon u de set USB-gebeurtenissen laten zien die het gevolg zijn van een geïnstrumenteerde activiteit op een bovenste laag.

Terwijl u gecombineerde gebeurtenistraceringen van andere providers in Netmon bekijkt, klikt u met de rechtermuisknop op een gebeurtenis in een toepassing en kiest u Gesprekken zoeken -> NetEvent- om de bijbehorende stuurprogrammagebeurtenissen te bekijken.

In deze afbeelding ziet u gerelateerde gebeurtenissen van een toepassing, UMDF-stuurprogramma en Ucx01000.sys (een van de stuurprogramma's in de USB-stuurprogrammastack). Deze gebeurtenissen hebben dezelfde GUID voor de activiteits-id.

Microsoft-netwerkmonitor.

Een activiteits-id-GUID toevoegen in een toepassing

Een toepassing kan GUID's voor activiteits-ID's bevatten door te bellen met EventActivityIdControl. Zie voor meer informatie Functies voor gebeurtenistracering.

Deze voorbeeldcode laat zien hoe een toepassing een activiteits-id-GUID kan instellen en deze kan verzenden naar de ETW-provider, een UMDF-stuurprogramma.

EventActivityIdControl(EVENT_ACTIVITY_CTRL_CREATE_ID, &activityIdStruct.ActivityId); 
EventActivityIdControl(EVENT_ACTIVITY_CTRL_SET_ID,    &activityIdStruct.ActivityId); 

if (!DeviceIoControl(hRead,
                     IOCTL_OSRUSBFX2_SET_ACTIVITY_ID,
                     &activityIdStruct,         // Ptr to InBuffer
                     sizeof(activityIdStruct),  // Length of InBuffer
                     NULL,                      // Ptr to OutBuffer
                     0,                         // Length of OutBuffer
                     NULL,                      // BytesReturned
                     0))                        // Ptr to Overlapped structure
{         

          wprintf(L"Failed to set activity ID - error %d\n", GetLastError());
}

...

success = ReadFile(hRead, pinBuf, G_ReadLen, (PULONG) &nBytesRead, NULL);

if(success == 0) 
{
          wprintf(L"ReadFile failed - error %d\n", GetLastError());

          EventWriteReadFail(0, GetLastError());

          ...

}

In het vorige voorbeeld roept een toepassing EventActivityIdControl- aan om een activiteits-id (EVENT_ACTIVITY_CTRL_CREATE_ID) te maken en deze vervolgens in te stellen (EVENT_ACTIVITY_CTRL_SET_ID) voor de huidige thread. De toepassing specificeert die activiteit-GUID aan de ETW-evenementprovider, zoals een stuurprogramma voor de gebruikersmodus, door een door het stuurprogramma gedefinieerde IOCTL te verzenden (beschreven in de volgende sectie).

De gebeurtenisprovider moet een instrumentatiemanifestbestand (.MAN-bestand) publiceren. Door de berichtcompilator (Mc.exe) uit te voeren, wordt er een headerbestand gegenereerd dat definities bevat voor de gebeurtenisprovider, gebeurteniskenmerken, kanalen en gebeurtenissen. In het voorbeeld roept de toepassing EventWriteReadFail aan, die zijn gedefinieerd in het gegenereerde headerbestand, om tracerings-gebeurtenisberichten te schrijven in geval van een fout.

De GUID van de activiteits-id instellen in een UMDF-stuurprogramma

Een stuurprogramma in de gebruikersmodus maakt en stelt activiteits-id-GUID's in door EventActivityIdControl aan te roepen en de aanroepen zijn vergelijkbaar met de manier waarop een toepassing deze aanroept, zoals beschreven in de vorige sectie. Deze aanroepen voegen de GUID van de activiteits-id toe aan de huidige thread en die activiteits-id-GUID wordt gebruikt wanneer de thread een gebeurtenis registreert. Zie Gebruik van Activiteitsidentificatorenvoor meer informatie.

In deze voorbeeldcode ziet u hoe een UMDF-stuurprogramma de activiteits-id-GUID instelt die door de toepassing is gemaakt en opgegeven via een IOCTL.

VOID
STDMETHODCALLTYPE
CMyControlQueue::OnDeviceIoControl(
    _In_ IWDFIoQueue *FxQueue,
    _In_ IWDFIoRequest *FxRequest,
    _In_ ULONG ControlCode,
    _In_ SIZE_T InputBufferSizeInBytes,
    _In_ SIZE_T OutputBufferSizeInBytes
    )
/*++

Routine Description:

    DeviceIoControl dispatch routine

Arguments:

    FxQueue - Framework Queue instance
    FxRequest - Framework Request  instance
    ControlCode - IO Control Code
    InputBufferSizeInBytes - Lenth of input buffer
    OutputBufferSizeInBytes - Lenth of output buffer

    Always succeeds DeviceIoIoctl
Return Value:

    VOID

--*/
{
    ...

    switch (ControlCode)
    {

        ....

        case IOCTL_OSRUSBFX2_SET_ACTIVITY_ID:
        {
            if (InputBufferSizeInBytes < sizeof(UMDF_ACTIVITY_ID))
            {
                hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
            }
            else
            {
                FxRequest->GetInputMemory(&memory );
            }

            if (SUCCEEDED(hr)) 
            {
                buffer = memory->GetDataBuffer(&bigBufferCb);
                memory->Release();

                m_Device->SetActivityId(&((PUMDF_ACTIVITY_ID)buffer)->ActivityId);
                hr = S_OK;
            }

            break;
        }
    } 
}

VOID
 SetActivityId(
        LPCGUID ActivityId
        )
    {
        CopyMemory(&m_ActivityId, ActivityId, sizeof(m_ActivityId));
    }

void
CMyReadWriteQueue::ForwardFormattedRequest(
    _In_ IWDFIoRequest*                         pRequest,
    _In_ IWDFIoTarget*                          pIoTarget
    )
{
...
    pRequest->SetCompletionCallback(
        pCompletionCallback,
        NULL
        );

...
    hrSend = pRequest->Send(pIoTarget,
                            0,  //flags
                            0); //timeout

...
    if (FAILED(hrSend))
    {
        contextHr = pRequest->RetrieveContext((void**)&pRequestContext);

        if (SUCCEEDED(contextHr)) {

            EventActivityIdControl(EVENT_ACTIVITY_CTRL_SET_ID, &pRequestContext->ActivityId);

            if (pRequestContext->RequestType == RequestTypeRead)
            {
                EventWriteReadFail(m_Device, hrSend);
            }

            delete pRequestContext;
        }

        pRequest->CompleteWithInformation(hrSend, 0);
    }

    return;
}

Laten we nagaan hoe de GUID van de activiteit-ID die door de applicatie is gemaakt, wordt gekoppeld aan een User-Mode Driver Framework clientstuurprogramma (UMDF). Wanneer het stuurprogramma de IOCTL-aanvraag van de toepassing ontvangt, wordt de GUID in een privélid gekopieerd. Op een bepaald moment roept de toepassing ReadFile- aan om een leesbewerking uit te voeren. Het framework maakt een aanvraag en roept de handler van het stuurprogramma ForwardFormattedRequest aan. In de handler zet de bestuurder de eerder opgeslagen activiteits-id-GUID op de thread door EventActivityIdControl en EventWriteReadFail aan te roepen om gebeurtenisberichten te traceren.

Opmerking Het UMDF-stuurprogramma moet ook het headerbestand bevatten dat wordt gegenereerd via het manifestbestand voor instrumentatie. Het headerbestand definieert macro's zoals EventWriteReadFail die traceringsberichten schrijven.

Activiteit-ID GUID toevoegen in een kernelmodusstuurprogramma

In de kernelmodus kan een stuurprogramma berichten traceren op de thread die afkomstig is uit de gebruikersmodus of een thread die door het stuurprogramma wordt gemaakt. In beide gevallen vereist het stuurprogramma de GUID van de activiteits-id van de thread.

Als u berichten wilt traceren, moet de driver de registratiehandle verkrijgen als gebeurtenisprovider (zie EtwRegister) en vervolgens EtwWrite aanroepen door de GUID en het gebeurtenisbericht op te geven. Zie Gebeurtenistracering toevoegen aan Kernel-Mode Stuurprogramma'svoor meer informatie.

Als uw kernelmodusstuurprogramma een aanvraag verwerkt die is gemaakt door een toepassing of een stuurprogramma voor de gebruikersmodus, maakt en stelt het stuurprogramma voor de kernelmodus geen activiteits-id-GUID in. In plaats daarvan verwerkt de I/O-manager de meeste doorgifte van activiteits-id's. Wanneer een thread in de gebruikersmodus een aanvraag initieert, maakt de I/O-manager een IRP voor de aanvraag en kopieert de activiteits-id-GUID van de huidige thread automatisch naar de nieuwe IRP. Als het stuurprogramma voor de kernelmodus gebeurtenissen op die thread wil traceren, moet deze de GUID ophalen door IoGetActivityIdIrp-aan te roepen en vervolgens EtwWriteaan te roepen.

Als uw kernelmodusstuurprogramma een IRP met een activiteits-id-GUID maakt, kan het stuurprogramma EtwActivityIdControl- aanroepen met EVENT_ACTIVITY_CTRL_CREATE_SET_ID om een nieuwe GUID te genereren. Het stuurprogramma kan de nieuwe GUID vervolgens koppelen aan de IRP door IoSetActivityIdIrp- aan te roepen en vervolgens EtwWrite-aan te roepen.

De GUID van de activiteits-id wordt samen met de IRP doorgegeven aan de volgende lagere stuurprogramma's. De lagere stuurprogramma's kunnen hun traceringsberichten toevoegen aan de thread.