VirtualBox

Changeset 72113 in vbox for trunk/src


Ignore:
Timestamp:
May 4, 2018 3:43:59 PM (7 years ago)
Author:
vboxsync
Message:

PS2K: Place only entire key press/release sequences in queue to avoid undesirable behavior (see bugref:4118).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Input/PS2K.cpp

    r71358 r72113  
    513513
    514514/**
     515 * Add a null-terminated byte sequence to a queue if there is enough room.
     516 *
     517 * @param   pQ                  Pointer to the queue.
     518 * @param   pStr                Pointer to the bytes to store.
     519 * @param   uReserve            Number of bytes that must still remain
     520 *                              available in queue.
     521 * @return  int                 VBox status/error code.
     522 */
     523static int ps2kInsertStrQueue(GeneriQ *pQ, const uint8_t *pStr, uint32_t uReserve)
     524{
     525    uint32_t    cbStr;
     526    unsigned    i;
     527
     528    cbStr = (uint32_t)strlen((const char *)pStr);
     529
     530    /* Check if queue has enough room. */
     531    if (pQ->cUsed + uReserve + cbStr >= pQ->cSize)
     532    {
     533        LogRelFlowFunc(("queue %p full (%u entries, want room for %u), cannot insert %u entries\n",
     534                        pQ, pQ->cUsed, uReserve, cbStr));
     535        return VERR_BUFFER_OVERFLOW;
     536    }
     537
     538    /* Insert byte sequence and update circular buffer write position. */
     539    for (i = 0; i < cbStr; ++i) {
     540        pQ->abQueue[pQ->wpos] = pStr[i];
     541        if (++pQ->wpos == pQ->cSize)
     542            pQ->wpos = 0;   /* Roll over. */
     543    }
     544    pQ->cUsed += cbStr;
     545    LogRelFlowFunc(("inserted %u bytes into queue %p\n", cbStr, pQ));
     546    return VINF_SUCCESS;
     547}
     548
     549/**
    515550 * Save a queue state.
    516551 *
     
    820855static int ps2kProcessKeyEvent(PPS2K pThis, uint8_t u8HidCode, bool fKeyDown)
    821856{
    822     unsigned int    i = 0;
    823857    key_def const   *pKeyDef;
    824858    uint8_t         abCodes[16];
    825     uint8_t         u8MakeCode;
     859    char            *pCodes;
     860    size_t          cbLeft;
     861    uint8_t         abScan[2];
    826862
    827863    LogFlowFunc(("key %s: 0x%02x (set %d)\n", fKeyDown ? "down" : "up", u8HidCode, pThis->u8ScanSet));
     
    855891        pThis->fNumLockOn ^= true;
    856892
     893    abCodes[0] = 0;
     894    pCodes = (char *)abCodes;
     895    cbLeft = sizeof(abCodes);
     896
    857897    if (pThis->u8ScanSet == 1 || pThis->u8ScanSet == 2)
    858898    {
     
    860900         * Since scan set 2 is used almost all the time, that case is handled first.
    861901         */
    862         abCodes[0] = 0;
    863902        if (fKeyDown)
    864903        {
     
    868907                /* Pause/Break sends different data if either Ctrl is held. */
    869908                if (pThis->u8Modifiers & (MOD_LCTRL | MOD_RCTRL))
    870                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    871                            "\xE0\x7E\xE0\xF0\x7E" : "\xE0\x46\xE0\xC6");
     909                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     910                              "\xE0\x7E\xE0\xF0\x7E" : "\xE0\x46\xE0\xC6");
    872911                else
    873                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    874                            "\xE1\x14\x77\xE1\xF0\x14\xF0\x77" : "\xE1\x1D\x45\xE1\x9D\xC5");
     912                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     913                              "\xE1\x14\x77\xE1\xF0\x14\xF0\x77" : "\xE1\x1D\x45\xE1\x9D\xC5");
    875914            }
    876915            else if (pKeyDef->keyFlags & KF_PS)
     
    878917                /* Print Screen depends on all of Ctrl, Shift, *and* Alt! */
    879918                if (pThis->u8Modifiers & (MOD_LALT | MOD_RALT))
    880                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    881                            "\x84" : "\x54");
     919                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     920                              "\x84" : "\x54");
    882921                else if (pThis->u8Modifiers & (MOD_LSHIFT | MOD_RSHIFT))
    883                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    884                            "\xE0\x7C" : "\xE0\x37");
     922                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     923                              "\xE0\x7C" : "\xE0\x37");
    885924                else
    886                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    887                            "\xE0\x12\xE0\x7C" : "\xE0\x2A\xE0\x37");
     925                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     926                              "\xE0\x12\xE0\x7C" : "\xE0\x2A\xE0\x37");
    888927            }
    889928            else if (pKeyDef->keyFlags & (KF_GK | KF_NS))
     
    897936                {
    898937                    if (pThis->u8Modifiers & MOD_LSHIFT)
    899                         strcat((char *)abCodes, pThis->u8ScanSet == 2 ?
    900                                "\xE0\xF0\x12" : "\xE0\xAA");
     938                        RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     939                                  "\xE0\xF0\x12" : "\xE0\xAA");
    901940                    if (pThis->u8Modifiers & MOD_RSHIFT)
    902                         strcat((char *)abCodes, pThis->u8ScanSet == 2 ?
    903                                "\xE0\xF0\x59" : "\xE0\xB6");
     941                        RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     942                                  "\xE0\xF0\x59" : "\xE0\xB6");
    904943                }
    905944                else
     
    907946                    Assert(pThis->fNumLockOn);  /* Not for KF_NS! */
    908947                    if ((pThis->u8Modifiers & (MOD_LSHIFT | MOD_RSHIFT)) == 0)
    909                         strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    910                                "\xE0\x12" : "\xE0\x2A");
     948                        RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     949                                  "\xE0\x12" : "\xE0\x2A");
    911950                    /* Else Shift cancels NumLock, so no prefix! */
    912951                }
    913952            }
    914             /* Feed the bytes to the queue if there is room. */
    915             /// @todo check empty space!
    916             while (abCodes[i])
    917                 ps2kInsertQueue((GeneriQ *)&pThis->keyQ, abCodes[i++]);
    918             Assert(i < sizeof(abCodes));
    919953
    920954            /* Standard processing for regular keys only. */
    921             u8MakeCode = pThis->u8ScanSet == 2 ? pKeyDef->makeS2 : pKeyDef->makeS1;
     955            abScan[0] = pThis->u8ScanSet == 2 ? pKeyDef->makeS2 : pKeyDef->makeS1;
     956            abScan[1] = '\0';
    922957            if (!(pKeyDef->keyFlags & (KF_PB | KF_PS)))
    923958            {
    924959                if (pKeyDef->keyFlags & (KF_E0 | KF_GK | KF_NS))
    925                     ps2kInsertQueue((GeneriQ *)&pThis->keyQ, 0xE0);
    926                 ps2kInsertQueue((GeneriQ *)&pThis->keyQ, u8MakeCode);
     960                    RTStrCatP(&pCodes, &cbLeft, "\xE0");
     961                RTStrCatP(&pCodes, &cbLeft, (const char *)abScan);
    927962            }
     963
     964            /* Feed the bytes to the queue if there is room. */
     965            //@todo: Send overrun code if sequence won't fit?
     966            ps2kInsertStrQueue((GeneriQ *)&pThis->keyQ, abCodes, 0);
    928967        }
    929968        else if (!(pKeyDef->keyFlags & (KF_NB | KF_PB)))
     
    936975                /* Undo faked Print Screen state as needed. */
    937976                if (pThis->u8Modifiers & (MOD_LALT | MOD_RALT))
    938                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    939                            "\xF0\x84" : "\xD4");
     977                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     978                              "\xF0\x84" : "\xD4");
    940979                else if (pThis->u8Modifiers & (MOD_LSHIFT | MOD_RSHIFT))
    941                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    942                            "\xE0\xF0\x7C" : "\xE0\xB7");
     980                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     981                              "\xE0\xF0\x7C" : "\xE0\xB7");
    943982                else
    944                     strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    945                            "\xE0\xF0\x7C\xE0\xF0\x12" : "\xE0\xB7\xE0\xAA");
     983                    RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     984                              "\xE0\xF0\x7C\xE0\xF0\x12" : "\xE0\xB7\xE0\xAA");
    946985            }
    947986            else
    948987            {
    949988                /* Process base scan code for less unusual keys. */
     989                abScan[0] = pThis->u8ScanSet == 2 ? pKeyDef->makeS2 : pKeyDef->makeS1 | 0x80;
     990                abScan[1] = '\0';
    950991                if (pKeyDef->keyFlags & (KF_E0 | KF_GK | KF_NS))
    951                     ps2kInsertQueue((GeneriQ *)&pThis->keyQ, 0xE0);
    952                 if (pThis->u8ScanSet == 2) {
    953                     ps2kInsertQueue((GeneriQ *)&pThis->keyQ, 0xF0);
    954                     ps2kInsertQueue((GeneriQ *)&pThis->keyQ, pKeyDef->makeS2);
    955                 } else {
    956                     Assert(pThis->u8ScanSet == 1);
    957                     ps2kInsertQueue((GeneriQ *)&pThis->keyQ, pKeyDef->makeS1 | 0x80);
    958                 }
     992                    RTStrCatP(&pCodes, &cbLeft, "\xE0");
     993                if (pThis->u8ScanSet == 2)
     994                    RTStrCatP(&pCodes, &cbLeft, "\xF0");
     995                RTStrCatP(&pCodes, &cbLeft, (const char *)abScan);
    959996
    960997                /* Restore shift state for gray keys. */
     
    9641001                    {
    9651002                        if (pThis->u8Modifiers & MOD_LSHIFT)
    966                             strcat((char *)abCodes, pThis->u8ScanSet == 2 ?
    967                                    "\xE0\x12" : "\xE0\x2A");
     1003                            RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     1004                                      "\xE0\x12" : "\xE0\x2A");
    9681005                        if (pThis->u8Modifiers & MOD_RSHIFT)
    969                             strcat((char *)abCodes, pThis->u8ScanSet == 2 ?
    970                                    "\xE0\x59" : "\xE0\x36");
     1006                            RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     1007                                      "\xE0\x59" : "\xE0\x36");
    9711008                    }
    9721009                    else
     
    9741011                        Assert(pThis->fNumLockOn);  /* Not for KF_NS! */
    9751012                        if ((pThis->u8Modifiers & (MOD_LSHIFT | MOD_RSHIFT)) == 0)
    976                             strcpy((char *)abCodes, pThis->u8ScanSet == 2 ?
    977                                    "\xE0\xF0\x12" : "\xE0\xAA");
     1013                            RTStrCatP(&pCodes, &cbLeft, pThis->u8ScanSet == 2 ?
     1014                                      "\xE0\xF0\x12" : "\xE0\xAA");
    9781015                    }
    9791016                }
    9801017            }
    9811018
    982             /* Feed any additional bytes to the queue if there is room. */
    983             /// @todo check empty space!
    984             while (abCodes[i])
    985                 ps2kInsertQueue((GeneriQ *)&pThis->keyQ, abCodes[i++]);
    986             Assert(i < sizeof(abCodes));
     1019            /* Feed the bytes to the queue if there is room. */
     1020            //@todo: Send overrun code if sequence won't fit?
     1021            ps2kInsertStrQueue((GeneriQ *)&pThis->keyQ, abCodes, 0);
    9871022        }
    9881023    }
     
    9911026        /* Handle Scan Set 3 - very straightforward. */
    9921027        Assert(pThis->u8ScanSet == 3);
     1028        abScan[0] = pKeyDef->makeS3;
     1029        abScan[1] = '\0';
    9931030        if (fKeyDown)
    9941031        {
    995             ps2kInsertQueue((GeneriQ *)&pThis->keyQ, pKeyDef->makeS3);
     1032            RTStrCatP(&pCodes, &cbLeft, (const char *)abScan);
    9961033        }
    9971034        else
     
    10011038            if (pKeyDef->keyMatic != T_M)
    10021039            {
    1003                 ps2kInsertQueue((GeneriQ *)&pThis->keyQ, 0xF0);
    1004                 ps2kInsertQueue((GeneriQ *)&pThis->keyQ, pKeyDef->makeS3);
     1040                RTStrCatP(&pCodes, &cbLeft, "\xF0");
     1041                RTStrCatP(&pCodes, &cbLeft, (const char *)abScan);
    10051042            }
    10061043        }
     1044        /* Feed the bytes to the queue if there is room. */
     1045        //@todo: Send overrun code if sequence won't fit?
     1046        ps2kInsertStrQueue((GeneriQ *)&pThis->keyQ, abCodes, 0);
    10071047    }
    10081048
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette