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 */; }
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 */; }
/** * 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"); }