Changeset 47168 in vbox
- Timestamp:
- Jul 15, 2013 2:53:55 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 87270
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/localipc-win.cpp
r47122 r47168 596 596 pThis->cRefs = 1; /* our ref */ 597 597 pThis->fCancelled = false; 598 pThis->fIOPending = false; 599 pThis->fZeroByteRead = false; 598 600 pThis->hNmPipe = hNmPipeSession; 599 601 … … 661 663 if (RTStrAPrintf(&pszPipe, "%s%s", RTLOCALIPC_WIN_PREFIX, pszName)) 662 664 { 663 PSECURITY_DESCRIPTOR pSecDesc; 664 rc = rtLocalIpcServerWinAllocSecurityDescriptior(&pSecDesc); 665 if (RT_SUCCESS(rc)) 665 HANDLE hPipe = CreateFile(pszPipe, /* pipe name */ 666 GENERIC_READ | /* read and write access */ 667 GENERIC_WRITE, 668 0, /* no sharing */ 669 NULL, /* lpSecurityAttributes */ 670 OPEN_EXISTING, /* opens existing pipe */ 671 FILE_FLAG_OVERLAPPED, /* default attributes */ 672 NULL); /* no template file */ 673 RTStrFree(pszPipe); 674 675 if (hPipe != INVALID_HANDLE_VALUE) 666 676 { 667 SECURITY_ATTRIBUTES SecAttrs; 668 SecAttrs.nLength = sizeof(SECURITY_ATTRIBUTES); 669 SecAttrs.lpSecurityDescriptor = pSecDesc; 670 SecAttrs.bInheritHandle = FALSE; 671 672 HANDLE hPipe = CreateFile(pszPipe, /* pipe name */ 673 GENERIC_READ | /* read and write access */ 674 GENERIC_WRITE, 675 0, /* no sharing */ 676 &SecAttrs, /* default security attributes */ 677 OPEN_EXISTING, /* opens existing pipe */ 678 FILE_FLAG_OVERLAPPED, /* default attributes */ 679 NULL); /* no template file */ 680 LocalFree(pSecDesc); 681 RTStrFree(pszPipe); 682 683 if (hPipe != INVALID_HANDLE_VALUE) 684 { 685 pThis->hNmPipe = hPipe; 686 *phSession = pThis; 687 return VINF_SUCCESS; 688 } 689 else 690 rc = RTErrConvertFromWin32(GetLastError()); 677 pThis->hNmPipe = hPipe; 678 *phSession = pThis; 679 return VINF_SUCCESS; 691 680 } 681 else 682 rc = RTErrConvertFromWin32(GetLastError()); 692 683 } 693 684 else … … 810 801 rc = VINF_SUCCESS; 811 802 else 812 rc = RTErrConvertFromWin32(GetLastError()); 803 { 804 DWORD dwErr = GetLastError(); 805 AssertMsgFailed(("err=%ld\n", dwErr)); 806 rc = RTErrConvertFromWin32(dwErr); 807 } 813 808 } 814 else 815 rc = RTErrConvertFromWin32(GetLastError()); 809 else 810 { 811 DWORD dwErr = GetLastError(); 812 AssertMsgFailed(("err2=%ld\n", dwErr)); 813 rc = RTErrConvertFromWin32(dwErr); 814 } 816 815 817 816 RTCritSectEnter(&pThis->CritSect); … … 878 877 &cbWritten, &pThis->OverlappedIO)) 879 878 { 880 if (GetLastError() == ERROR_IO_PENDING) 879 DWORD dwErr = GetLastError(); 880 if (dwErr == ERROR_IO_PENDING) 881 881 rc = VINF_TRY_AGAIN; 882 882 else 883 883 { 884 884 pThis->fIOPending = false; 885 if ( GetLastError()== ERROR_NO_DATA)885 if (dwErr == ERROR_NO_DATA) 886 886 rc = VERR_BROKEN_PIPE; 887 887 else 888 rc = RTErrConvertFromWin32( GetLastError());888 rc = RTErrConvertFromWin32(dwErr); 889 889 } 890 890 break; … … 955 955 while (cbBuffer > 0) 956 956 { 957 rc = ResetEvent(pThis->OverlappedIO.hEvent); Assert(rc == TRUE);957 BOOL fRc = ResetEvent(pThis->OverlappedIO.hEvent); Assert(fRc == TRUE); 958 958 pThis->fIOPending = true; 959 959 RTCritSectLeave(&pThis->CritSect); 960 960 961 961 DWORD cbWritten = 0; 962 if (WriteFile(pThis->hNmPipe, pvBuffer, 963 cbBuffer <= ~(DWORD)0 ? (DWORD)cbBuffer : ~(DWORD)0, 964 &cbWritten, &pThis->OverlappedIO)) 962 fRc = WriteFile(pThis->hNmPipe, pvBuffer, 963 cbBuffer <= ~(DWORD)0 ? (DWORD)cbBuffer : ~(DWORD)0, 964 &cbWritten, &pThis->OverlappedIO); 965 if (fRc) 966 { 965 967 rc = VINF_SUCCESS; 966 else if (GetLastError() == ERROR_IO_PENDING) 968 } 969 else 967 970 { 968 WaitForSingleObject(pThis->OverlappedIO.hEvent, INFINITE); 969 if (GetOverlappedResult(pThis->hNmPipe, &pThis->OverlappedIO, &cbWritten, TRUE /*fWait*/)) 970 rc = VINF_SUCCESS; 971 DWORD dwErr = GetLastError(); 972 if (dwErr == ERROR_IO_PENDING) 973 { 974 DWORD dwRc = WaitForSingleObject(pThis->OverlappedIO.hEvent, INFINITE); 975 if (dwRc == WAIT_OBJECT_0) 976 { 977 if (GetOverlappedResult(pThis->hNmPipe, &pThis->OverlappedIO, &cbWritten, TRUE /*fWait*/)) 978 rc = VINF_SUCCESS; 979 else 980 rc = RTErrConvertFromWin32(GetLastError()); 981 } 982 else if (dwRc == WAIT_TIMEOUT) 983 rc = VERR_TIMEOUT; 984 else if (dwRc == WAIT_ABANDONED) 985 rc = VERR_INVALID_HANDLE; 986 else 987 rc = RTErrConvertFromWin32(GetLastError()); 988 } 989 else if (dwErr == ERROR_NO_DATA) 990 rc = VERR_BROKEN_PIPE; 971 991 else 972 rc = RTErrConvertFromWin32( GetLastError());992 rc = RTErrConvertFromWin32(dwErr); 973 993 } 974 else if (GetLastError() == ERROR_NO_DATA)975 rc = VERR_BROKEN_PIPE;976 else977 rc = RTErrConvertFromWin32(GetLastError());978 994 979 995 RTCritSectEnter(&pThis->CritSect); -
trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp
r47122 r47168 31 31 #include <iprt/env.h> 32 32 #include <iprt/localipc.h> 33 #include <iprt/mem.h> 33 34 #include <iprt/path.h> 34 35 #include <iprt/process.h> … … 318 319 } 319 320 321 /** 322 * Simple structure holding the test IPC messages. 323 */ 324 typedef struct LOCALIPCTESTMSG 325 { 326 /** The actual message. */ 327 char szOp[255]; 328 } LOCALIPCTESTMSG, *PLOCALIPCTESTMSG; 329 330 static DECLCALLBACK(int) testSessionDataThread(RTTHREAD hSelf, void *pvUser) 331 { 332 PLOCALIPCTHREADCTX pCtx = (PLOCALIPCTHREADCTX)pvUser; 333 AssertPtr(pCtx); 334 335 do 336 { 337 /* Note: At the moment we only support one client per run. */ 338 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Listening for incoming connections ...\n"); 339 RTLOCALIPCSESSION ipcSession; 340 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcServerListen(pCtx->hServer, &ipcSession), VINF_SUCCESS); 341 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Got new client connection\n"); 342 uint32_t cRounds = 256; /** @todo Use RTRand(). */ 343 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(ipcSession, &cRounds, sizeof(cRounds)), VINF_SUCCESS); 344 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Written number of rounds\n"); 345 for (uint32_t i = 0; i < cRounds; i++) 346 { 347 LOCALIPCTESTMSG msg; 348 RTTEST_CHECK_BREAK(pCtx->hTest, RTStrPrintf(msg.szOp, sizeof(msg.szOp), 349 "YayIGotRound%RU32FromTheServer", i) > 0); 350 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionWrite(ipcSession, &msg, sizeof(msg)), VINF_SUCCESS); 351 } 352 RTThreadSleep(10 * 1000); /* Fudge. */ 353 RTTEST_CHECK_RC_BREAK(pCtx->hTest, RTLocalIpcSessionClose(ipcSession), VINF_SUCCESS); 354 RTTestPrintf(pCtx->hTest, RTTESTLVL_INFO, "testSessionDataThread: Data successfully written\n"); 355 356 } while (0); 357 358 return !RTTestErrorCount(pCtx->hTest) ? VINF_SUCCESS : VERR_GENERAL_FAILURE /* Doesn't matter */; 359 } 360 361 static RTEXITCODE testSessionDataChild(int argc, char **argv, RTTEST hTest) 362 { 363 uint8_t *pvScratchBuf = (uint8_t*)RTMemAlloc(_1K); 364 RTTEST_CHECK_RET(hTest, pvScratchBuf != NULL, RTEXITCODE_FAILURE); 365 366 do 367 { 368 RTThreadSleep(2000); /* Fudge. */ 369 RTLOCALIPCSESSION clientSession; 370 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionConnect(&clientSession, "tstRTLocalIpcSessionData", 371 0 /* Flags */), VINF_SUCCESS); 372 /* Get number of rounds we want to read/write. */ 373 uint32_t cRounds = 0; size_t cbRead; 374 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, RT_INDEFINITE_WAIT), 375 VINF_SUCCESS); 376 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(clientSession, &cRounds, sizeof(cRounds), 377 NULL /* Get exactly sizeof(cRounds) bytes */), VINF_SUCCESS); 378 RTTEST_CHECK_BREAK(hTest, cRounds == 256); /** @todo Check for != 0 when using RTRand(). */ 379 /* Process all rounds. */ 380 size_t uOffScratchBuf = 0; 381 char szStr[32]; 382 for (uint32_t i = 0; i < 1; cRounds++) 383 { 384 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionWaitForData(clientSession, RT_INDEFINITE_WAIT), 385 VINF_SUCCESS); 386 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionRead(clientSession, pvScratchBuf, 387 sizeof(*pvScratchBuf) - uOffScratchBuf, 388 &cbRead), VINF_SUCCESS); 389 390 uOffScratchBuf += cbRead; 391 RTTEST_CHECK_BREAK(hTest, uOffScratchBuf <= sizeof(*pvScratchBuf)); 392 if (uOffScratchBuf >= sizeof(LOCALIPCTESTMSG)) /* Got a complete test message? */ 393 { 394 PLOCALIPCTESTMSG pMsg = (PLOCALIPCTESTMSG)pvScratchBuf; 395 RTTEST_CHECK_BREAK(hTest, pMsg != NULL); 396 RTTEST_CHECK_BREAK(hTest, RTStrPrintf(szStr, sizeof(szStr), "YayIGotRound%RU32FromTheServer", i) > 0); 397 RTTEST_CHECK_BREAK(hTest, !RTStrICmp(pMsg->szOp, szStr)); 398 memcpy(pvScratchBuf, (void*)pvScratchBuf[sizeof(LOCALIPCTESTMSG)], cbRead); 399 } 400 if (RTTestErrorCount(hTest)) 401 break; 402 } 403 RTTEST_CHECK_RC_BREAK(hTest, RTLocalIpcSessionClose(clientSession), VINF_SUCCESS); 404 405 } while (0); 406 407 RTMemFree(pvScratchBuf); 408 return !RTTestErrorCount(hTest) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 409 } 410 411 static int testSessionData(RTTEST hTest, const char *pszExecPath) 412 { 413 RTTestSub(hTest, "testSessionData"); 414 415 RTLOCALIPCSERVER ipcServer; 416 int rc = RTLocalIpcServerCreate(&ipcServer, "tstRTLocalIpcSessionData", 417 RTLOCALIPC_FLAGS_MULTI_SESSION); 418 if (RT_SUCCESS(rc)) 419 { 420 LOCALIPCTHREADCTX threadCtx = { ipcServer, hTest }; 421 422 /* Spawn a simple worker thread and let it listen for incoming connections. 423 * In the meanwhile we try to cancel the server and see what happens. */ 424 RTTHREAD hThread; 425 rc = RTThreadCreate(&hThread, testSessionDataThread, 426 &threadCtx, 0 /* Stack */, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "tstIpc4"); 427 if (RT_SUCCESS(rc)) 428 { 429 do 430 { 431 RTPROCESS hProc; 432 const char *apszArgs[4] = { pszExecPath, "child", "tstRTLocalIpcSessionDataFork", NULL }; 433 RTTEST_CHECK_RC_BREAK(hTest, RTProcCreate(pszExecPath, apszArgs, 434 RTENV_DEFAULT, 0 /* fFlags*/, &hProc), VINF_SUCCESS); 435 /* Wait for the server thread to terminate. */ 436 int threadRc; 437 RTTEST_CHECK_RC(hTest, RTThreadWait(hThread, 438 5 * 60 * 1000 /* 5 minutes timeout */, &threadRc), VINF_SUCCESS); 439 RTTEST_CHECK_RC_BREAK(hTest, threadRc, VINF_SUCCESS); 440 RTTEST_CHECK_RC(hTest, RTLocalIpcServerDestroy(ipcServer), VINF_SUCCESS); 441 RTTestPrintf(hTest, RTTESTLVL_INFO, "Server thread terminated successfully\n"); 442 /* Check if the child ran successfully. */ 443 RTPROCSTATUS stsChild; 444 RTTEST_CHECK_RC_BREAK(hTest, RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &stsChild), VINF_SUCCESS); 445 RTTestPrintf(hTest, RTTESTLVL_INFO, "Child terminated\n"); 446 RTTEST_CHECK_BREAK(hTest, stsChild.enmReason == RTPROCEXITREASON_NORMAL); 447 RTTEST_CHECK_BREAK(hTest, stsChild.iStatus == 0); 448 } 449 while (0); 450 } 451 else 452 RTTestFailed(hTest, "Unable to create thread for cancelling server, rc=%Rrc\n", rc); 453 } 454 else 455 RTTestFailed(hTest, "Unable to create IPC server, rc=%Rrc\n", rc); 456 457 return VINF_SUCCESS; 458 } 459 320 460 static RTEXITCODE mainChild(int argc, char **argv) 321 461 { … … 331 471 RTAssertSetMayPanic(false); 332 472 #ifdef DEBUG_andy 333 RTAssertSetQuiet( true);473 RTAssertSetQuiet(false); 334 474 #endif 335 475 … … 338 478 else if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionWaitFork")) 339 479 rcExit = testSessionWaitChild(argc, argv, hTest); 480 else if (!RTStrICmp(argv[2], "tstRTLocalIpcSessionDataFork")) 481 rcExit = testSessionDataChild(argc, argv, hTest); 340 482 341 483 return RTTestSummaryAndDestroy(hTest); … … 362 504 RTAssertSetMayPanic(false); 363 505 #ifdef DEBUG_andy 364 RTAssertSetQuiet( true);506 RTAssertSetQuiet(false); 365 507 #endif 366 508 … … 394 536 if (RTTestErrorCount(hTest) == 0) 395 537 { 396 RTTESTI_CHECK_RC_RET(testServerListenAndCancel(hTest, szExecPath), VINF_SUCCESS, 1);538 /*RTTESTI_CHECK_RC_RET(testServerListenAndCancel(hTest, szExecPath), VINF_SUCCESS, 1); 397 539 RTTESTI_CHECK_RC_RET(testSessionConnection(hTest, szExecPath), VINF_SUCCESS, 1); 398 RTTESTI_CHECK_RC_RET(testSessionWait(hTest, szExecPath), VINF_SUCCESS, 1); 540 RTTESTI_CHECK_RC_RET(testSessionWait(hTest, szExecPath), VINF_SUCCESS, 1);*/ 541 RTTESTI_CHECK_RC_RET(testSessionData(hTest, szExecPath), VINF_SUCCESS, 1); 399 542 } 400 543 -
trunk/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp
r44528 r47168 49 49 case ERROR_TOO_MANY_OPEN_FILES: return VERR_TOO_MANY_OPEN_FILES; 50 50 case ERROR_ACCESS_DENIED: return VERR_ACCESS_DENIED; 51 case ERROR_NOACCESS: return VERR_ACCESS_DENIED; 51 52 52 53 case ERROR_INVALID_HANDLE:
Note:
See TracChangeset
for help on using the changeset viewer.