none
USB UMDF 1.1 отправка пустого пакета RRS feed

  • Вопрос

  • Доброе время суток, пишу драйвер на UMDF 1.1 для одного USB устройства и надо послать пустой пакет. Отправка пустой строки в IWDFMemory не помогает ( пакет не отправляется ). Отправляю обычным forwading в pipe - пример кода могу дать если надо. 
    23 октября 2021 г. 20:31

Ответы

Все ответы

  • Здравствуйте,

    А в чем цель данного пустого пакет? Покажите по возможности и код.


    Если Вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение" Мнения, высказанные здесь, являются отражение моих личных взглядов, а не позиции корпорации Microsoft. Вся информация предоставляется "как есть" без каких-либо гарантий.

    25 октября 2021 г. 5:53
    Модератор
  • Цель пустого пакета - запустить парсинг сообщения на устройстве. На https://www.jungo.com/st/products/windriver/windriver_usb/ это работало, на моей имплементации почему-то отказывается. 

    Если коротко - создаю VirtualFileSystem самописный - и открываю файл по адресу <INSTANCE_ID>/usb_ep/<PIPE_ID>. Делаю туда write file кодом : 

        char bytesToWrite[WRITE_BUFFER_SIZE] = "";
        DWORD dwBytesWritten = 0;
        ...
        dwResult = WDU_StreamWrite(hStream, bytesToWrite, lstrlenA(bytesToWrite), &dwBytesWritten);
        if (dwResult != WD_STATUS_SUCCESS)
        {
            _RPTFWN(_CRT_WARN, L"WDU_StreamWrite results 0x%X\n", dwResult);
            WDU_StreamClose(hStream);
            return FALSE;
        }
    
    DWORD DLLCALLCONV WDU_StreamWrite(HANDLE hStream, const PVOID pBuffer,
        DWORD bytes, DWORD *pdwBytesWritten)
    {
        if (!WriteFile(hStream, pBuffer, bytes, pdwBytesWritten, NULL))
        {
            switch (GetLastError())
            {
            case ERROR_IO_PENDING:
                break;
            case ERROR_INVALID_HANDLE:
                return WD_INVALID_HANDLE;
            case ERROR_INVALID_USER_BUFFER:
                return WD_INVALID_PARAMETER;
            case ERROR_NOT_ENOUGH_MEMORY:
                return WD_INSUFFICIENT_RESOURCES;
            case ERROR_BROKEN_PIPE:
                return WD_INVALID_PIPE_NUMBER;
            case ERROR_INVALID_FUNCTION:
                return WD_READ_WRITE_CONFLICT;
            case ERROR_SEM_TIMEOUT:
                return WD_TIME_OUT_EXPIRED;
            default:
                _RPTFWN(_CRT_WARN, L"WriteFile error 0x%X\n", GetLastError());
                return WD_OPERATION_FAILED;
            }
        }
    
        return WD_STATUS_SUCCESS;
    }
    
    

    В драйвере принимаю в control queue 

    void ControlQueue::OnWrite(IWDFIoQueue * pWdfQueue, IWDFIoRequest * pWdfRequest, SIZE_T NumOfBytesToWrite)
    {
        UNREFERENCED_PARAMETER(pWdfQueue);
        UNREFERENCED_PARAMETER(pWdfRequest);
        UNREFERENCED_PARAMETER(NumOfBytesToWrite);
    
        HRESULT hr = S_OK;
        IWDFFile* file = nullptr;
        pWdfRequest->GetFileObject(&file);
        if (!file)
        {
            pWdfRequest->Complete(E_NOTIMPL);
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! NOT found file!");
            return;
        }
    
        VFS_Item *ctx = nullptr;
        hr = file->RetrieveContext(reinterpret_cast<PVOID*>(&ctx));
    
        if (SUCCEEDED(hr))
        {
            if (!ctx)
            {
                pWdfRequest->Complete(E_NOTIMPL);
                TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! NOT CONTEXT");
                return;
            }
        }
        hr = ctx->onWriteFile(pWdfQueue, pWdfRequest, NumOfBytesToWrite, this);
        if (FAILED(hr))
        {
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Bad readfile call");
        }
    }

    Обрабатываю в VFS

    HRESULT VFS_CLASS(EndPoint)::onWriteFile(IWDFIoQueue * pWdfQueue, IWDFIoRequest * pWdfRequest, SIZE_T NumOfBytesToWrite, IRequestCallbackRequestCompletion* a_Callback)
    {
        std::string _path = get_path();
        UNREFERENCED_PARAMETER(pWdfQueue);
        UNREFERENCED_PARAMETER(pWdfRequest);
        UNREFERENCED_PARAMETER(NumOfBytesToWrite);
        UNREFERENCED_PARAMETER(a_Callback);
    
        if (!m_pipe)
        {
            pWdfRequest->Complete(E_NOTIMPL);
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_VFS, "%!FUNC!::%s:: You lost add pipe!", _path.c_str());
            return E_NOTIMPL;
        }
    
        if (!m_pipe->IsOutEndPoint())
        {
            pWdfRequest->Complete(E_NOTIMPL);
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_VFS, "%!FUNC!::%s:: You not possible write to read pipe!", _path.c_str());
            return E_NOTIMPL;
        }
    
        HRESULT hr = S_OK;
        IWDFFile* file = nullptr;
        pWdfRequest->GetFileObject(&file);
        if (!file)
        {
            pWdfRequest->Complete(E_NOTIMPL);
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_VFS, "%!FUNC!::%s:: NOT found file!", _path.c_str());
            return E_NOTIMPL;
        }
    
        IWDFMemory * pInputMemory = NULL;
        pWdfRequest->GetInputMemory(&pInputMemory);
    
        if (!pInputMemory)
        {
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_VFS, "%!FUNC!::%s:: pInputMemory fail?", _path.c_str());
        }
    
        hr = m_pipe->FormatRequestForWrite(
            pWdfRequest,
            file, //pFile
            pInputMemory,
            NULL, //Memory offset
            NULL  //DeviceOffset
        );
    
        if (FAILED(hr))
        {
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_VFS, "%!FUNC!::%s:: Forward fail? %d", _path.c_str(), hr);
            pWdfRequest->Complete(hr);
        }
        else
        {
            ForwardFormattedRequest(pWdfRequest, m_pipe,a_Callback);
        }
        ComPointerSafeRelease(pInputMemory);
    
        return S_OK;
    }
    
    void VFS_CLASS(EndPoint)::ForwardFormattedRequest(
        _In_ IWDFIoRequest*                         pRequest,
        _In_ IWDFIoTarget*                          pIoTarget,
        _In_ IRequestCallbackRequestCompletion*     pCompletionCallback
    )
    {
        std::string _path = get_path();
        //
        //First set the completion callback
        //
    
        pRequest->SetCompletionCallback(
            pCompletionCallback,
            NULL
        );
    
        //pCompletionCallback->Release();
        //pCompletionCallback = NULL;
    
        //
        //Send down the request
        //
    
        HRESULT hrSend = S_OK;
        hrSend = pRequest->Send(pIoTarget,
            0,  //flags
            0); //timeout
    
        if (FAILED(hrSend))
        {
            TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_VFS, "%!FUNC!::%s:: Fail send", _path.c_str());
            pRequest->CompleteWithInformation(hrSend, 0);
        }
    
        TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_VFS, "%!FUNC!::%s:: Forwaded!", _path.c_str());
    
    }

    Логи о том что запрос на запись получен ( от WriteFile ) - я получаю, но в WireShark не видно пакета

    27 октября 2021 г. 12:23
  • Возможно необходимо прописать политику umdf:

    UmdfFileObjectPolicy = <RejectNullAndUnknownFileObjects | AllowNullAndUnknownFileObjects>

    По умолчанию стоит Reject.

    Смотрите: Specifying WDF Directives in INF Files


    Если Вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение" Мнения, высказанные здесь, являются отражение моих личных взглядов, а не позиции корпорации Microsoft. Вся информация предоставляется "как есть" без каких-либо гарантий.


    27 октября 2021 г. 13:34
    Модератор
  • Стоит AllowNullAndUnknownFileObjects - проблем с открытием файла нету - проблема в записи в пайп. 
    28 октября 2021 г. 14:06
  • Хорошо тогда посмотрите оффициальную документацию: Working with USB Pipes in UMDF 1.x Drivers

    , в частности IWDFIoTarget::FormatRequestForWrite method (wudfddi.h)


    Если Вам помог чей-либо ответ, пожалуйста, не забывайте жать на кнопку "Предложить как ответ" или "Проголосовать за полезное сообщение" Мнения, высказанные здесь, являются отражение моих личных взглядов, а не позиции корпорации Microsoft. Вся информация предоставляется "как есть" без каких-либо гарантий.

    29 октября 2021 г. 10:33
    Модератор
  • Спасибо, помогло https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-functions-for-pipe-policy-modification (SHORT_PACKET_TERMINATE выставить в TRUE
    1 ноября 2021 г. 15:02