Esempio n. 1
0
static DECLCALLBACK(int) testSessionWaitThread(RTTHREAD hSelf, void *pvUser)
{
    PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser;
    AssertPtr(pCtx);

    int rc;
    for (;;)
    {
        RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Listening for incoming connections ...\n");
        RTLOCALIPCSESSION ipcSession;
        rc = RTLocalIpcServerListen(pCtx->hServer, &ipcSession);
        if (RT_SUCCESS(rc))
        {
            RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Got new client connection, waiting a bit ...\n");
            RTThreadSleep(2000);
            rc = RTLocalIpcSessionClose(ipcSession);
        }
        else
        {
            RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Listening ended with rc=%Rrc\n", rc);
            break;
        }
    }

    RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionWaitThread: Ended with rc=%Rrc\n", rc);
    return rc;
}
Esempio n. 2
0
static int testSessionDataThreadWorker(PLOCALIPCTHREADCTX pCtx)
{
    AssertPtr(pCtx);

    size_t cbScratchBuf = _1K; /** @todo Make this random in future. */
    uint8_t *pvScratchBuf = (uint8_t*)RTMemAlloc(cbScratchBuf);
    RTTEST_CHECK_RET(pCtx->hTest, pvScratchBuf != NULL, VERR_NO_MEMORY);

    do
    {
        /* Note: At the moment we only support one client per run. */
        RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Listening for incoming connections ...\n");
        RTLOCALIPCSESSION hSession;
        RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcServerListen(pCtx->hServer, &hSession), VINF_SUCCESS);
        RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Got new client connection\n");
        uint32_t cRounds = 256; /** @todo Use RTRand(). */
        /* Write how many rounds we're going to send data. */
        RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(hSession, &cRounds, sizeof(cRounds)), VINF_SUCCESS);
        RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Written number of rounds\n");
        for (uint32_t i = 0; i < cRounds; i++)
        {
            LOCALIPCTESTMSG msg;
            RTTEST_CHECK_BREAK(pCtx->hTest, RTStrPrintf(msg.szOp, sizeof(msg.szOp),
                               "YayIGotRound%RU32FromTheServer", i) > 0);
            RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(hSession, &msg, sizeof(msg)), VINF_SUCCESS);
        }
        if (!RTTestErrorCount(pCtx->hTest))
            RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Data successfully written\n");
        /* Try to receive the same amount of rounds from the client. */
        for (uint32_t i = 0; i < cRounds; i++)
        {
            RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWaitForData(hSession, RT_INDEFINITE_WAIT),
                                  VINF_SUCCESS);
            char szMsg[32];
            RTTEST_CHECK_BREAK(pCtx->hTest, RTStrPrintf(szMsg, sizeof(szMsg), "YayIGotRound%RU32FromTheClient", i) > 0);
            RTTEST_CHECK_RC_BREAK(pCtx->hTest, testSessionDataReadTestMsg(pCtx->hTest, hSession,
                                  pvScratchBuf, cbScratchBuf,
                                  szMsg), VINF_SUCCESS);
            if (RTTestErrorCount(pCtx->hTest))
                break;
        }
        if (!RTTestErrorCount(pCtx->hTest))
            RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Data successfully read\n");
        RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionClose(hSession), VINF_SUCCESS);

    } while (0);

    RTMemFree(pvScratchBuf);
    return !RTTestErrorCount(pCtx->hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */;
}
Esempio n. 3
0
static RTEXITCODE testSessionConnectionChild(int argc, char **argv, RTTEST hTest)
{
    do
    {
        RTThreadSleep(2000); /* Fudge */
        RTLOCALIPCSESSION clientSession;
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionConnection",
                              0 /* Flags */), VINF_SUCCESS);
        RTThreadSleep(5000); /* Fudge */
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS);

    } while (0);

    return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
Esempio n. 4
0
static int testSessionDataChildWorker(RTTEST hTest)
{
    size_t cbScratchBuf = _1K; /** @todo Make this random in future. */
    uint8_t *pvScratchBuf = (uint8_t*)RTMemAlloc(cbScratchBuf);
    RTTEST_CHECK_RET(hTest, pvScratchBuf != NULL, RTEXITCODE_FAILURE);

    do
    {
        RTThreadSleep(2000); /* Fudge. */
        RTLOCALIPCSESSION hSession;
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&hSession, "tstRTLocalIpcSessionData",
                              0 /* Flags */), VINF_SUCCESS);
        /* Get number of rounds we want to read/write. */
        uint32_t cRounds = 0;
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(hSession, RT_INDEFINITE_WAIT),
                              VINF_SUCCESS);
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(hSession, &cRounds, sizeof(cRounds),
                              NULL /* Get exactly sizeof(cRounds) bytes */), VINF_SUCCESS);
        RTTEST_CHECK_BREAK(hTest, cRounds == 256); /** @todo Check for != 0 when using RTRand(). */
        /* Receive all rounds. */
        for (uint32_t i = 0; i < cRounds; i++)
        {
            RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(hSession, RT_INDEFINITE_WAIT),
                                  VINF_SUCCESS);
            char szMsg[32];
            RTTEST_CHECK_BREAK(hTest, RTStrPrintf(szMsg, sizeof(szMsg), "YayIGotRound%RU32FromTheServer", i) > 0);
            RTTEST_CHECK_RC_BREAK(hTest, testSessionDataReadTestMsg(hTest, hSession,
                                  pvScratchBuf, cbScratchBuf,
                                  szMsg), VINF_SUCCESS);
            if (RTTestErrorCount(hTest))
                break;
        }
        /* Send all rounds back to the server. */
        for (uint32_t i = 0; i < cRounds; i++)
        {
            LOCALIPCTESTMSG msg;
            RTTEST_CHECK_BREAK(hTest, RTStrPrintf(msg.szOp, sizeof(msg.szOp),
                                                  "YayIGotRound%RU32FromTheClient", i) > 0);
            RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWrite(hSession, &msg, sizeof(msg)), VINF_SUCCESS);
        }
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(hSession), VINF_SUCCESS);

    } while (0);

    RTMemFree(pvScratchBuf);
    return !RTTestErrorCount(hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */;
}
Esempio n. 5
0
static RTEXITCODE testSessionWaitChild(int argc, char **argv, RTTEST hTest)
{
    do
    {
        RTThreadSleep(2000); /* Fudge. */
        RTLOCALIPCSESSION clientSession;
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionWait",
                              0 /* Flags */), VINF_SUCCESS);
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 100       /* 100ms timeout */),
                              VERR_TIMEOUT);
        /* Next, try 60s timeout. Should be returning way earlier because the server closed the
         * connection after the first client connected. */
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 60 * 1000),
                              VERR_BROKEN_PIPE);
        /* Last try, also should fail because the server should be not around anymore. */
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, 5 * 1000),
                              VERR_BROKEN_PIPE);
        RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS);

    } while (0);

    return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
}
Esempio n. 6
0
/**
 * Shows a balloon message using VBoxTray's notification area in the
 * Windows task bar.
 *
 * @param   hwndParent          Window handle of parent.
 * @param   string_size         Size of variable string.
 * @param   variables           The actual variable string.
 * @param   stacktop            Pointer to a pointer to the current stack.
 */
VBOXINSTALLHELPER_EXPORT VBoxTrayShowBallonMsg(HWND hwndParent, int string_size,
                                               TCHAR *variables, stack_t **stacktop)
{
    EXDLL_INIT();

    char szMsg[256];
    char szTitle[128];
    HRESULT hr = vboxPopString(szMsg, sizeof(szMsg) / sizeof(char));
    if (SUCCEEDED(hr))
        hr = vboxPopString(szTitle, sizeof(szTitle) / sizeof(char));

    /** @todo Do we need to restore the stack on failure? */

    if (SUCCEEDED(hr))
    {
        RTR3InitDll(0);

        uint32_t cbMsg = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG)
                       + strlen(szMsg) + 1    /* Include terminating zero */
                       + strlen(szTitle) + 1; /* Dito. */
        Assert(cbMsg);
        PVBOXTRAYIPCMSG_SHOWBALLOONMSG pIpcMsg =
            (PVBOXTRAYIPCMSG_SHOWBALLOONMSG)RTMemAlloc(cbMsg);
        if (pIpcMsg)
        {
            /* Stuff in the strings. */
            memcpy(pIpcMsg->szMsgContent, szMsg, strlen(szMsg)   + 1);
            memcpy(pIpcMsg->szMsgTitle, szTitle, strlen(szTitle) + 1);

            /* Pop off the values in reverse order from the stack. */
            if (SUCCEEDED(hr))
                hr = vboxPopULong((ULONG*)&pIpcMsg->uType);
            if (SUCCEEDED(hr))
                hr = vboxPopULong((ULONG*)&pIpcMsg->uShowMS);

            if (SUCCEEDED(hr))
            {
                RTLOCALIPCSESSION hSession = 0;
                int rc = vboxConnectToVBoxTray(&hSession);
                if (RT_SUCCESS(rc))
                {
                    VBOXTRAYIPCHEADER ipcHdr = { VBOXTRAY_IPC_HDR_MAGIC, 0 /* Header version */,
                                                 VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG, cbMsg };

                    rc = RTLocalIpcSessionWrite(hSession, &ipcHdr, sizeof(ipcHdr));
                    if (RT_SUCCESS(rc))
                        rc = RTLocalIpcSessionWrite(hSession, pIpcMsg, cbMsg);

                    int rc2 = RTLocalIpcSessionClose(hSession);
                    if (RT_SUCCESS(rc))
                        rc = rc2;
                }

                if (RT_FAILURE(rc))
                    hr = __HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE);
            }

            RTMemFree(pIpcMsg);
        }
        else
            hr = __HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
    }

    /* Push simple return value on stack. */
    SUCCEEDED(hr) ? pushstring("0") : pushstring("1");
}
Esempio n. 7
0
int main(int argc, char **argv)
{
    if (   argc > 2
            && !RTStrICmp(argv[1], "child"))
        return mainChild(argc, argv);

    RTTEST hTest;
    RTEXITCODE rcExit = RTTestInitAndCreate("tstRTLocalIpc", &hTest);
    if (rcExit)
        return rcExit;
    RTTestBanner(hTest);

    char szExecPath[RTPATH_MAX];
    if (!RTProcGetExecutablePath(szExecPath, sizeof(szExecPath)))
        RTStrCopy(szExecPath, sizeof(szExecPath), argv[0]);

    RTTestISub("Basics");

    RTAssertSetMayPanic(false);
#ifdef DEBUG_andy
    RTAssertSetQuiet(false);
#endif

    /* Server-side. */
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(NULL, NULL, 0), VERR_INVALID_POINTER, 1);
    RTLOCALIPCSERVER ipcServer;
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, NULL, 0), VERR_INVALID_POINTER, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "", 0), VERR_INVALID_PARAMETER, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", 0 /* Invalid flags */), VERR_INVALID_PARAMETER, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", 1234 /* Invalid flags */), VERR_INVALID_PARAMETER, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(NULL), VERR_INVALID_HANDLE, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(NULL), VINF_SUCCESS, 1);
    /* Basic server creation / destruction. */
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCreate(&ipcServer, "BasicTest", RTLOCALIPC_FLAGS_MULTI_SESSION), VINF_SUCCESS, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(ipcServer), VINF_SUCCESS, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS, 1);

    /* Client-side (per session). */
    RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(NULL, NULL, 0), VERR_INVALID_POINTER, 1);
    RTLOCALIPCSESSION ipcSession;
    RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, NULL, 0), VERR_INVALID_POINTER, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "", 0), VERR_INVALID_PARAMETER, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "BasicTest", 1234 /* Invalid flags */), VERR_INVALID_PARAMETER, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcSessionCancel(NULL), VERR_INVALID_HANDLE, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcSessionClose(NULL), VINF_SUCCESS, 1);
    /* Basic client creation / destruction. */
    RTTESTI_CHECK_RC_RET(RTLocalIpcSessionConnect(&ipcSession, "BasicTest", 0), VERR_FILE_NOT_FOUND, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerCancel(ipcServer), VERR_INVALID_MAGIC, 1);
    RTTESTI_CHECK_RC_RET(RTLocalIpcServerDestroy(ipcServer), VERR_INVALID_MAGIC, 1);

    if (RTTestErrorCount(hTest) == 0)
    {
        RTTESTI_CHECK_RC_RET(testServerListenAndCancel(hTest, szExecPath), VINF_SUCCESS, 1);
        RTTESTI_CHECK_RC_RET(testSessionConnection(hTest, szExecPath), VINF_SUCCESS, 1);
        RTTESTI_CHECK_RC_RET(testSessionWait(hTest, szExecPath), VINF_SUCCESS, 1);
        RTTESTI_CHECK_RC_RET(testSessionData(hTest, szExecPath), VINF_SUCCESS, 1);
    }

    /*
     * Summary.
     */
    return RTTestSummaryAndDestroy(hTest);
}