none
SetPortTimeouts on COM port RRS feed

  • Question

  • Hello,

    I'm working on a bidirectional  printer language monitor (V3) using part of the pjlmon DDK sample.

    It works fine when I use USB communication.

    I have troubles when I use serial RS232 com. The SetPortTimeouts function fails with error ERROR_INVALID_PARAMETER.

    I've tried different parameter values without success. This function is called  when the spooler calls OpenPortEx().

    If I remove this function, it seems that windows internally set the ReadIntervalTimeout to 5sec, that is the ReadPort waits 5000 ms before returning and this is too long for my application.

    I've tried another solution. Before  calling SetPortTimeouts , I use GetPrinterDataFromPort().  I supply IOCTL_SERIAL_GET_TIMEOUTS to get the COMMTIMEOUTS, and use this buffer to the call to SetPortTimeouts.

    Both calls return ERROR_INVALID_PARAMETER. I saw that there are WDFRequestRetrieveInputBuffer/OutputBuffer but I'm little bit confused on using these functions, especially regarding the WDFREQUEST parameter.


    Can someone help?

    here is a piece of my code:

    ......

    DWORD cbReturned;
    COMMTIMEOUTS* pCTO;
    DWORD cbOutBuffer = sizeof(COMMTIMEOUTS);
    PVOID lpOutBuffer = AllocSplMem(cbOutBuffer);
     if (!(*pIniPort->fn.pfnGetPrinterDataFromPort)(
                            pIniPort->hPort,
                            IOCTL_SERIAL_GET_TIMEOUTS,
                            NULL,
                            NULL,
                            NULL,
                            (LPWSTR)lpOutBuffer,  
                            cbOutBuffer,
                            &cbReturned)) {
                            DbgViewTracer(L"AXGENLMON", ERROR_DEBUG, L"ReadWorkerThread pfnGetPrinterDataFromPort. Error(%d)", GetLastError());
                        }
                        else {
                            pCTO = reinterpret_cast<COMMTIMEOUTS*>(lpOutBuffer);
                            if (pCTO) {
                                DbgViewTracer(L"AXGENLMON", INFO, L"ReadWorkerThread pfnGetPrinterDataFromPort. ReadIntervalTimeout(%s)", pCTO->ReadIntervalTimeout);
                                pCTO->ReadIntervalTimeout = 1000;
                                if (!(*pIniPort->fn.pfnSetPortTimeOuts)(pIniPort->hPort, pCTO, 0)) {
                                    DWORD dwRes = GetLastError();
                                    DbgViewTracer(L"AXGENLMON", ERROR_DEBUG, L"ReadWorkerThread SetPortTimeOuts Failed. Error(%d)", dwRes);
                                    pIniPort->status &= ~PP_RUN_THREAD;
                                }
                                else {
                                    DbgViewTracer(L"AXGENLMON", INFO, L"ReadWorkerThread:: SetPortTimeOuts Succeeded");
                                }
                            }
                        }

    Friday, December 12, 2014 8:39 AM

Answers

All replies

  • Hi Pavel,

    Thanks for your reply.

    I've tested many configurations with different values of Read/WriteIntervalleTimeout (1000ms 5000ms etc...) without success. If I don't call SetPorTimeouts, I see that the timeout for ReadPort is 5000ms (internally set by Windows). This default timeout of 5000 ms does not fit to my language monitor. 

    I've tried another solution by using CreateFile to get a Handle to a file mapped to the COM port. Calling SetCommTimeouts works fine, but the problem is that the port is automatically closed by the spooler. All the functions exposed by the language monitor use the handle to the COM port, not a handle to the created file.

    The same question has already been submitted by someone else, in an other forum seven years ago. I did not find any answer.

    Saturday, December 13, 2014 8:05 AM
  • Hi Pavel,

    I would like to print the pCTO filed values but the function call pfnGetPrinterDataFromPort returns also INVALID_PARAMETER. Maybe the supplied lpOutBuffer input parameter is not good. This buffer is allocated by the caller (my application). Instead,  I should retrieve the buffer allocated on other low level printer driver stack.

    I've seen in the code sample of the DDK that they use a WDF function WdfRequestRetrieveInputBuffer. But with this function, I don't know if it's possible to mix WDF and UMDF. This function, as first parameter, needs a handle to a framework request object (WDFREQUEST) and, in the context of the language monitor, I don't know how to get such a handle. Before going deeper in that way, I need your advise... or, is there an easier solution to my problem?

    Thanks very much for your support.

    Monday, December 15, 2014 10:51 AM
  • Hi Pavel,

    Yes I have a valid hPort. Before calling pfnGetPrinterDataFromPort, I call pfnOpenPort which returns a valid pIniPort->hPort.

    I've tried another solution found in localmon of  the DDK sample. This sample uses QueryDosDevice() function  to retrieve information about MS-DOS device name (symbolic filename), then CreateFile() to get a file handle. With a HANDLE of a file, I can call SetCommtimeouts(), WaitCommEvent... and all basic Win32 API routines, but it comes out that the Port is get disconnected after.

    Just an additionnal information, I use the WDK 8.1 in this project.

    Thanks for you support.


    Tuesday, December 16, 2014 9:53 AM