Sdílet prostřednictvím


Zpracování návratové hodnoty E_INVALIDARG

Ovladače zobrazení uživatelského režimu (UMD) musí při zpracování E_INVALIDARG kódu chyby dodržovat určitá pravidla. Tento článek vysvětluje, kdy a jak správně zpracovat tuto chybovou hodnotu v kódu ovladače.

Přehled

E_INVALIDARG Kód chyby označuje, že jeden nebo více argumentů předaných funkci jsou neplatné. V kontextu UMD je důležité rozlišovat:

  • Chyby generované ovladačem: Ovladač by neměl selhat v žádné ze svých funkcí vrácením E_INVALIDARG do prostředí Direct3D runtime.
  • Chyby propagované za běhu: Pokud váš ovladač obdrží E_INVALIDARG z funkce poskytované běhovým prostředím, musí tuto chybu šířit zpět do běhového prostředí.

Toto pravidlo vytvoří jasnou hranici přiřazení chyby mezi kódem ovladače a kódem modulu runtime.

Proč toto pravidlo existuje

Pravidlo E_INVALIDARG šíření slouží k několika důležitým účelům:

  • Jasné hranice odpovědnosti: Když modul runtime Direct3D obdrží E_INVALIDARG, ví, že chyba pochází z funkcí zadaných za běhu, ne ze samotného ovladače.

  • Efektivita ladění: Vývojáři můžou rychle zjistit, jestli chyba E_INVALIDARG značí, že:

    • Ovladač volá funkce modulu runtime s neplatnými parametry.
    • Škodlivý kód zasahuje do grafického zásobníku.
    • Interní problémy modulu runtime, které potřebují šetření.
  • Zabezpečení a spolehlivost: Požadováním, aby ovladače šířily (a negenerovaly) E_INVALIDARG, může systém rozpoznat anomální chování, které může naznačovat ohrožení bezpečnosti nebo poškození zásobníku.

Pokyny k implementaci

Základní vzor zpracování chyb

Když váš ovladač volá funkci poskytovanou modulem runtime, vždy zkontrolujte návratovou hodnotu a předejte E_INVALIDARG, pokud obdržíte:

HRESULT MyDriverFunction(/* parameters */)
{
    HRESULT hr;
    
    // Call a runtime-supplied function
    hr = pRuntimeCallbacks->pfnSomeRuntimeFunction(/* arguments */);
    
    // Propagate E_INVALIDARG if received from runtime
    if (hr == E_INVALIDARG)
    {
        // The runtime detected invalid arguments we passed
        // Must return this error back to the runtime
        return E_INVALIDARG;
    }
    
    // Handle other error codes appropriately
    if (FAILED(hr))
    {
        // Use appropriate error code for driver-specific failures
        return hr; // or return E_FAIL, E_OUTOFMEMORY, etc.
    }
    
    // Continue with driver logic
    // ...
    
    return S_OK;
}

Nevygenerujte E_INVALIDARG v ovladači

Nikdy negenerujte E_INVALIDARG přímo v kódu ovladače:

// INCORRECT - Do not do this
HRESULT MyDriverFunction(D3DDDIARG_SOMEARGS* pArgs)
{
    if (pArgs == NULL || pArgs->SomeValue > MAX_VALUE)
    {
        // Wrong: Driver should not return E_INVALIDARG for its own validation
        return E_INVALIDARG;  // DO NOT DO THIS
    }
    // ...
}

// CORRECT - Use appropriate error codes for driver-specific validation
HRESULT MyDriverFunction(D3DDDIARG_SOMEARGS* pArgs)
{
    if (pArgs == NULL)
    {
        // Correct: Use E_FAIL or E_POINTER for driver-specific validation
        return E_FAIL;
    }
    
    if (pArgs->SomeValue > MAX_VALUE)
    {
        // Correct: Use E_FAIL or other appropriate error code
        return E_FAIL;
    }
    // ...
}

Příklad: Volání funkcí přidělování modulu runtime

HRESULT MyDriver_CreateResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource)
{
    HRESULT hr;
    D3DDDICB_ALLOCATE AllocateData = {0};
    
    // Set up allocation parameters
    AllocateData.pPrivateDriverData = pMyDriverData;
    AllocateData.PrivateDriverDataSize = sizeof(MY_DRIVER_DATA);
    // ... other initialization ...
    
    // Call runtime-supplied allocation function
    hr = pCallbacks->pfnAllocateCb(hDevice, &AllocateData);
    
    if (hr == E_INVALIDARG)
    {
        // Runtime detected invalid allocation parameters
        // This likely indicates a bug in how we set up AllocateData
        // Must propagate this error back to the runtime
        return E_INVALIDARG;
    }
    
    if (FAILED(hr))
    {
        // Handle other allocation failures
        return hr;
    }
    
    // Continue with resource creation
    // ...
    return S_OK;
}

Osvědčené postupy

  • Použijte odpovídající kódy chyb: Pro chyby ověřování specifické pro ovladače, použijte E_FAIL, E_OUTOFMEMORY, E_NOTIMPLnebo jiné vhodné hodnoty HRESULT.

  • Vždy kontrolovat návratové hodnoty funkce modulu runtime: Nepředpokládáte, že funkce modulu runtime vždy proběhnou úspěšně.

  • Rozšířit E_INVALIDARG okamžitě: Když obdržíte E_INVALIDARG z funkce modulu runtime, vraťte ji přímo bez úprav.

  • Neočekávaný E_INVALIDARG v dokumentu: Pokud funkce modulu runtime vrátí E_INVALIDARG, může to znamenat chybu v nastavení parametrů ovladače – prošetřete a opravte.

  • Testování pomocí nástroje Driver Verifier: Pomocí nástroje Driver Verifier během vývoje zachyťte porušení tohoto pravidla zpracování chyb v rané fázi.