/** * Connects to VBoxTray IPC under the behalf of the user running * in the current thread context. * * @return IPRT status code. * @param phSession Where to store the IPC session. */ static int vboxConnectToVBoxTray(RTLOCALIPCSESSION *phSession) { int rc = VINF_SUCCESS; RTUTF16 wszUserName[255]; DWORD cchUserName = sizeof(wszUserName) / sizeof(RTUTF16); BOOL fRc = GetUserNameW(wszUserName, &cchUserName); if (!fRc) rc = RTErrConvertFromWin32(GetLastError()); if (RT_SUCCESS(rc)) { char *pszUserName; rc = RTUtf16ToUtf8(wszUserName, &pszUserName); if (RT_SUCCESS(rc)) { char szPipeName[255]; if (RTStrPrintf(szPipeName, sizeof(szPipeName), "%s%s", VBOXTRAY_IPC_PIPE_PREFIX, pszUserName)) { rc = RTLocalIpcSessionConnect(phSession, szPipeName, 0 /* Flags */); } else rc = VERR_NO_MEMORY; RTStrFree(pszUserName); } } return rc; }
/** * Connects to VBoxTray IPC under the behalf of the user running * in the current thread context. * * @return IPRT status code. * @param phSession Where to store the IPC session. */ static int vboxConnectToVBoxTray(RTLOCALIPCSESSION *phSession) { char szPipeName[512 + sizeof(VBOXTRAY_IPC_PIPE_PREFIX)]; memcpy(szPipeName, VBOXTRAY_IPC_PIPE_PREFIX, sizeof(VBOXTRAY_IPC_PIPE_PREFIX)); int rc = RTProcQueryUsername(NIL_RTPROCESS, &szPipeName[sizeof(VBOXTRAY_IPC_PIPE_PREFIX) - 1], sizeof(szPipeName) - sizeof(VBOXTRAY_IPC_PIPE_PREFIX) + 1, NULL /*pcbUser*/); if (RT_SUCCESS(rc)) rc = RTLocalIpcSessionConnect(phSession, szPipeName, RTLOCALIPC_FLAGS_NATIVE_NAME); return rc; }
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; }
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 */; }
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; }
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); }