Changeset 28557 in vbox for trunk/src/VBox/Additions/common/VBoxService
- Timestamp:
- Apr 21, 2010 11:18:32 AM (15 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r28446 r28557 100 100 101 101 102 static int VBoxServiceControlHandleCmd Exec(uint32_t u32ClientId, uint32_t uNumParms)102 static int VBoxServiceControlHandleCmdStartProcess(uint32_t u32ClientId, uint32_t uNumParms) 103 103 { 104 104 uint32_t uContextID; … … 142 142 if (RT_FAILURE(rc)) 143 143 { 144 VBoxServiceError("Control: Failed to retrieve exec utioncommand! Error: %Rrc\n", rc);144 VBoxServiceError("Control: Failed to retrieve exec start command! Error: %Rrc\n", rc); 145 145 } 146 146 else … … 150 150 szStdIn, szStdOut, szStdErr, 151 151 szUser, szPassword, uTimeLimitMS); 152 } 153 return rc; 154 } 155 156 157 static int VBoxServiceControlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms) 158 { 159 uint32_t uContextID; 160 uint32_t uPID; 161 uint32_t uHandleID; 162 uint32_t uFlags; 163 164 int rc = VbglR3GuestCtrlExecGetHostCmdOutput(u32ClientId, uNumParms, 165 &uContextID, &uPID, &uHandleID, &uFlags); 166 if (RT_FAILURE(rc)) 167 { 168 VBoxServiceError("Control: Failed to retrieve exec output command! Error: %Rrc\n", rc); 169 } 170 else 171 { 172 /* Let's have a look if we have a running process with PID = uPID ... */ 173 PVBOXSERVICECTRLTHREAD pNode; 174 bool bFound = false; 175 RTListForEach(&g_GuestControlExecThreads, pNode, VBOXSERVICECTRLTHREAD, Node) 176 { 177 if ( pNode->fStarted 178 && pNode->enmType == VBoxServiceCtrlThreadDataExec) 179 { 180 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData; 181 if (pData && pData->uPID == uPID) 182 { 183 bFound = true; 184 break; 185 } 186 } 187 } 188 189 if (bFound) 190 { 191 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData; 192 AssertPtr(pData); 193 194 uint32_t cbRead = _4K; /* Try reading 4k. */ 195 BYTE *pBuf = (BYTE*)RTMemAlloc(cbRead); 196 if (pBuf) 197 { 198 rc = VBoxServiceControlExecReadPipeBufferContent(&pData->stdOut, pBuf, cbRead, &cbRead); 199 if (RT_SUCCESS(rc)) 200 { 201 AssertPtr(pBuf); 202 /* cbRead now contains actual size. */ 203 rc = VbglR3GuestCtrlExecSendOut(u32ClientId, uContextID, uPID, 0 /* handle ID */, 0 /* flags */, 204 pBuf, cbRead); 205 } 206 RTMemFree(pBuf); 207 } 208 else 209 rc = VERR_NO_MEMORY; 210 } 211 else 212 rc = VERR_NOT_FOUND; /* PID not found! */ 152 213 } 153 214 return rc; … … 176 237 uint32_t uMsg; 177 238 uint32_t uNumParms; 178 VBoxServiceVerbose( 3, "Control: Waiting for host msg ...\n");239 VBoxServiceVerbose(4, "Control: Waiting for host msg ...\n"); 179 240 rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms, 1000 /* 1s timeout */); 180 241 if (rc == VERR_TOO_MUCH_DATA) … … 190 251 if (RT_SUCCESS(rc)) 191 252 { 253 VBoxServiceVerbose(3, "Control: Msg=%u (%u parms) retrieved\n", uMsg, uNumParms); 192 254 switch(uMsg) 193 255 { 194 case GETHOSTMSG_EXEC_ CMD:195 rc = VBoxServiceControlHandleCmd Exec(g_GuestControlSvcClientID, uNumParms);256 case GETHOSTMSG_EXEC_START_PROCESS: 257 rc = VBoxServiceControlHandleCmdStartProcess(g_GuestControlSvcClientID, uNumParms); 196 258 break; 197 259 260 case GETHOSTMSG_EXEC_GET_OUTPUT: 261 rc = VBoxServiceControlHandleCmdGetOutput(g_GuestControlSvcClientID, uNumParms); 262 break; 263 198 264 default: 199 VBoxServiceVerbose(3, "Control: Unsupported message from host! Msg=% ld\n", uMsg);265 VBoxServiceVerbose(3, "Control: Unsupported message from host! Msg=%u\n", uMsg); 200 266 /* Don't terminate here; just wait for the next message. */ 201 267 break; 202 268 } 269 270 if (RT_FAILURE(rc)) 271 VBoxServiceVerbose(3, "Control: Message was processed with rc=%Rrc\n", rc); 203 272 } 204 273 … … 252 321 int rc2 = RTThreadWait(pNode->Thread, 30 * 1000 /* Wait 30 seconds max. */, NULL); 253 322 if (RT_FAILURE(rc2)) 254 VBoxServiceError("Control: Thread (PID: %u) failed to stop; rc2=%Rrc\n", pNode->uPID, rc2); 255 } 256 VBoxServiceControlExecDestroyThreadData(pNode); 323 VBoxServiceError("Control: Thread failed to stop; rc2=%Rrc\n", rc2); 324 } 325 326 /* Destroy thread specific data. */ 327 switch (pNode->enmType) 328 { 329 case VBoxServiceCtrlThreadDataExec: 330 VBoxServiceControlExecDestroyThreadData((PVBOXSERVICECTRLTHREADDATAEXEC)pNode->pvData); 331 break; 332 333 default: 334 break; 335 } 257 336 } 258 337 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
r28463 r28557 145 145 * 146 146 * @returns IPRT status code from client send. 147 * @param pThread The thread specific data. 147 148 * @param hPollSet The polling set. 148 149 * @param fPollEvt The event mask returned by RTPollNoResume. … … 154 155 * @todo Put the last 4 parameters into a struct! 155 156 */ 156 static int VBoxServiceControlExecProcHandleOutputEvent(RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR, 157 static int VBoxServiceControlExecProcHandleOutputEvent(PVBOXSERVICECTRLTHREAD pThread, 158 RTPOLLSET hPollSet, uint32_t fPollEvt, PRTPIPE phPipeR, 157 159 uint32_t *puCrc32 , uint32_t uHandleId) 158 160 { … … 163 165 */ 164 166 int rc = VINF_SUCCESS; 165 166 char abBuf[_64K];167 167 size_t cbRead; 168 int rc2 = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead); 168 BYTE abBuf[_64K]; 169 170 AssertPtr(pThread); 171 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData; 172 AssertPtr(pData); 173 174 int rc2 = RTPipeRead(*phPipeR, abBuf, sizeof(abBuf), &cbRead); 169 175 if (RT_SUCCESS(rc2) && cbRead) 170 176 { 171 Log(("Crc32=%#x ", *puCrc32)); 172 173 #if 1 174 abBuf[cbRead] = '\0';175 RTPrintf("%s: %s\n", uHandleId == 1 ? "StdOut: " : "StdErr: ", abBuf);177 #if 0 178 /* Only used for "real-time" stdout/stderr data; gets sent immediately (later)! */ 179 rc = VbglR3GuestCtrlExecSendOut(pThread->uClientID, pThread->uContextID, 180 pData->uPID, uHandleId, 0 /* u32Flags */, 181 abBuf, cbRead); 176 182 #endif 177 178 /**puCrc32 = RTCrc32Process(*puCrc32, abBuf, cbRead); 179 Log(("cbRead=%#x Crc32=%#x \n", cbRead, *puCrc32)); 180 Pkt.uCrc32 = RTCrc32Finish(*puCrc32);*/ 181 /* if (g_fDisplayOutput) 182 { 183 if (enmHndId == TXSEXECHNDID_STDOUT) 184 RTStrmPrintf(g_pStdErr, "%.*s", cbRead, Pkt.abBuf); 185 else if (enmHndId == TXSEXECHNDID_STDERR) 186 RTStrmPrintf(g_pStdErr, "%.*s", cbRead, Pkt.abBuf); 187 } 188 189 rc = txsReplyInternal(&Pkt.Hdr, pszOpcode, cbRead + sizeof(uint32_t));*/ 190 191 /* Make sure we go another poll round in case there was too much data 192 for the buffer to hold. */ 193 fPollEvt &= RTPOLL_EVT_ERROR; 183 rc = VBoxServiceControlExecWritePipeBuffer(&pData->stdOut, abBuf, cbRead); 184 if (RT_SUCCESS(rc)) 185 { 186 /* Make sure we go another poll round in case there was too much data 187 for the buffer to hold. */ 188 fPollEvt &= RTPOLL_EVT_ERROR; 189 } 194 190 } 195 191 else if (RT_FAILURE(rc2)) … … 254 250 || hStdOutR != NIL_RTPIPE 255 251 || hStdErrR != NIL_RTPIPE; 256 RTMSINTERVAL const cMsPollBase= hStdInW != NIL_RTPIPE252 RTMSINTERVAL const cMsPollBase = hStdInW != NIL_RTPIPE 257 253 ? 100 /* need to poll for input */ 258 254 : 1000; /* need only poll for process exit and aborts */ 259 RTMSINTERVAL cMsPollCur = 0; 255 RTMSINTERVAL cMsPollCur = 0; 256 257 AssertPtr(pThread); 258 259 AssertPtr(pThread); 260 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData; 261 AssertPtr(pData); 260 262 261 263 /* Assign PID to thread data. */ 262 p Thread->uPID = hProcess;264 pData->uPID = hProcess; 263 265 264 266 /* … … 266 268 * and that it's now OK to send input to the process. 267 269 */ 268 AssertPtr(pThread);269 270 VBoxServiceVerbose(3, "Control: Process started: PID=%u, CID=%u\n", 270 p Thread->uPID, pThread->uContextID);271 pData->uPID, pThread->uContextID); 271 272 rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, 272 p Thread->uPID, PROC_STS_STARTED, 0 /* u32Flags */,273 pData->uPID, PROC_STS_STARTED, 0 /* u32Flags */, 273 274 NULL /* pvData */, 0 /* cbData */); 274 275 … … 299 300 300 301 case 1 /* TXSEXECHNDID_STDOUT */: 301 rc = VBoxServiceControlExecProcHandleOutputEvent( hPollSet, fPollEvt, &hStdOutR, &uStdOutCrc32, 1 /* TXSEXECHNDID_STDOUT */);302 rc = VBoxServiceControlExecProcHandleOutputEvent(pThread, hPollSet, fPollEvt, &hStdOutR, &uStdOutCrc32, 1 /* TXSEXECHNDID_STDOUT */); 302 303 break; 303 304 304 305 case 2 /*TXSEXECHNDID_STDERR */: 305 rc = VBoxServiceControlExecProcHandleOutputEvent( hPollSet, fPollEvt, &hStdErrR, &uStdErrCrc32, 2 /*TXSEXECHNDID_STDERR */);306 rc = VBoxServiceControlExecProcHandleOutputEvent(pThread, hPollSet, fPollEvt, &hStdErrR, &uStdErrCrc32, 2 /*TXSEXECHNDID_STDERR */); 306 307 break; 307 308 … … 467 468 468 469 VBoxServiceVerbose(3, "Control: Process ended: PID=%u, CID=%u, Status=%u, Flags=%u\n", 469 p Thread->uPID, pThread->uContextID, uStatus, uFlags);470 pData->uPID, pThread->uContextID, uStatus, uFlags); 470 471 rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, 471 p Thread->uPID, uStatus, uFlags,472 pData->uPID, uStatus, uFlags, 472 473 NULL /* pvData */, 0 /* cbData */); 473 474 } 474 475 RTMemFree(StdInBuf.pch); 475 476 476 VBoxServiceVerbose(3, "Control: Process loop ended with rc=%Rrc\n", rc); 477 477 return rc; … … 529 529 } 530 530 531 int VBoxServiceControlExecReadPipeBufferContent(PVBOXSERVICECTRLEXECPIPEBUF pBuf, 532 BYTE *pbBuffer, uint32_t cbBuffer, uint32_t *pcbToRead) 533 { 534 AssertPtr(pcbToRead); 535 536 // LOCKING 537 538 Assert(pBuf->cbOffset >= pBuf->cbRead); 539 if (*pcbToRead > pBuf->cbOffset - pBuf->cbRead) 540 *pcbToRead = pBuf->cbOffset - pBuf->cbRead; 541 542 if (*pcbToRead > cbBuffer) 543 *pcbToRead = cbBuffer; 544 545 if (*pcbToRead > 0) 546 { 547 memcpy(pbBuffer, pBuf->pbData + pBuf->cbRead, *pcbToRead); 548 pBuf->cbRead += *pcbToRead; 549 } 550 else 551 pbBuffer = NULL; 552 return VINF_SUCCESS; 553 } 554 555 int VBoxServiceControlExecWritePipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf, 556 BYTE *pbData, uint32_t cbData) 557 { 558 AssertPtr(pBuf); 559 560 // LOCKING 561 562 /** @todo Use RTMemCache or RTMemObj here? */ 563 BYTE *pNewBuf; 564 while (pBuf->cbSize - pBuf->cbOffset < cbData) 565 { 566 pNewBuf = (BYTE*)RTMemRealloc(pBuf->pbData, pBuf->cbSize + _4K); 567 if (pNewBuf == NULL) 568 break; 569 pBuf->cbSize += _4K; 570 pBuf->pbData = pNewBuf; 571 } 572 573 int rc = VINF_SUCCESS; 574 if (pBuf->pbData) 575 { 576 memcpy(pBuf->pbData + pBuf->cbOffset, pbData, cbData); 577 pBuf->cbOffset += cbData; 578 /** @todo Add offset clamping! */ 579 } 580 else 581 rc = VERR_NO_MEMORY; 582 return rc; 583 } 584 531 585 /** Allocates and gives back a thread data struct which then can be used by the worker thread. */ 532 586 int VBoxServiceControlExecAllocateThreadData(PVBOXSERVICECTRLTHREAD pThread, … … 540 594 AssertPtr(pThread); 541 595 596 /* General stuff. */ 542 597 pThread->Node.pPrev = NULL; 543 598 pThread->Node.pNext = NULL; … … 547 602 pThread->fStopped = false; 548 603 604 pThread->uContextID = u32ContextID; 549 605 /* ClientID will be assigned when thread is started! */ 550 pThread->uContextID = u32ContextID; 551 pThread->uPID = 0; /* Don't have a PID yet. */ 552 pThread->pszCmd = RTStrDup(pszCmd); 553 pThread->uFlags = uFlags; 554 pThread->uNumEnvVars = 0; 555 pThread->uNumArgs = 0; /* Initialize in case of RTGetOptArgvFromString() is failing ... */ 606 607 /* Specific stuff. */ 608 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)RTMemAlloc(sizeof(VBOXSERVICECTRLTHREADDATAEXEC)); 609 if (pData == NULL) 610 return VERR_NO_MEMORY; 611 612 pData->uPID = 0; /* Don't have a PID yet. */ 613 pData->pszCmd = RTStrDup(pszCmd); 614 pData->uFlags = uFlags; 615 pData->uNumEnvVars = 0; 616 pData->uNumArgs = 0; /* Initialize in case of RTGetOptArgvFromString() is failing ... */ 556 617 557 618 /* Prepare argument list. */ 558 int rc = RTGetOptArgvFromString(&p Thread->papszArgs, (int*)&pThread->uNumArgs,619 int rc = RTGetOptArgvFromString(&pData->papszArgs, (int*)&pData->uNumArgs, 559 620 (uNumArgs > 0) ? pszArgs : "", NULL); 560 621 /* Did we get the same result? */ 561 Assert(uNumArgs == p Thread->uNumArgs);622 Assert(uNumArgs == pData->uNumArgs); 562 623 563 624 if (RT_SUCCESS(rc)) … … 566 627 if (uNumEnvVars) 567 628 { 568 p Thread->papszEnv = (char**)RTMemAlloc(uNumEnvVars * sizeof(char*));569 AssertPtr(p Thread->papszEnv);570 p Thread->uNumEnvVars = uNumEnvVars;629 pData->papszEnv = (char**)RTMemAlloc(uNumEnvVars * sizeof(char*)); 630 AssertPtr(pData->papszEnv); 631 pData->uNumEnvVars = uNumEnvVars; 571 632 572 633 const char *pcCur = pszEnv; … … 575 636 while (cbLen < cbEnv) 576 637 { 577 if (RTStrAPrintf(& pThread->papszEnv[i++], "%s", pcCur) < 0)638 if (RTStrAPrintf(&pData->papszEnv[i++], "%s", pcCur) < 0) 578 639 { 579 640 rc = VERR_NO_MEMORY; … … 585 646 } 586 647 587 pThread->pszStdIn = RTStrDup(pszStdIn); 588 pThread->pszStdOut = RTStrDup(pszStdOut); 589 pThread->pszStdErr = RTStrDup(pszStdErr); 590 pThread->pszUser = RTStrDup(pszUser); 591 pThread->pszPassword = RTStrDup(pszPassword); 592 pThread->uTimeLimitMS = uTimeLimitMS; 593 } 594 595 /* Adjust time limit value. */ 596 pThread->uTimeLimitMS = ( (uTimeLimitMS == UINT32_MAX) 597 || (uTimeLimitMS == 0)) ? 598 RT_INDEFINITE_WAIT : uTimeLimitMS; 648 pData->pszStdIn = RTStrDup(pszStdIn); 649 pData->pszStdOut = RTStrDup(pszStdOut); 650 pData->pszStdErr = RTStrDup(pszStdErr); 651 pData->pszUser = RTStrDup(pszUser); 652 pData->pszPassword = RTStrDup(pszPassword); 653 pData->uTimeLimitMS = uTimeLimitMS; 654 655 /* Adjust time limit value. */ 656 pData->uTimeLimitMS = ( (uTimeLimitMS == UINT32_MAX) 657 || (uTimeLimitMS == 0)) ? 658 RT_INDEFINITE_WAIT : uTimeLimitMS; 659 660 /* Init buffers. */ 661 pData->stdOut.pbData = NULL; 662 pData->stdOut.cbSize = 0; 663 pData->stdOut.cbOffset = 0; 664 pData->stdOut.cbRead = 0; 665 666 pData->stdErr.pbData = NULL; 667 pData->stdErr.cbSize = 0; 668 pData->stdErr.cbOffset = 0; 669 pData->stdErr.cbRead = 0; 670 } 671 672 if (RT_FAILURE(rc)) 673 { 674 VBoxServiceControlExecDestroyThreadData(pData); 675 } 676 else 677 { 678 pThread->enmType = VBoxServiceCtrlThreadDataExec; 679 pThread->pvData = pData; 680 } 599 681 return rc; 600 682 } 601 683 684 void VBoxServiceControlExecDestroyPipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf) 685 { 686 if (pBuf) 687 { 688 if (pBuf->pbData) 689 RTMemFree(pBuf->pbData); 690 pBuf->pbData = NULL; 691 pBuf->cbSize = 0; 692 pBuf->cbOffset = 0; 693 pBuf->cbRead = 0; 694 } 695 } 696 602 697 /** Frees an allocated thread data structure along with all its allocated parameters. */ 603 void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREAD pThread) 698 void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREADDATAEXEC pData) 699 { 700 if (pData) 701 { 702 RTStrFree(pData->pszCmd); 703 if (pData->uNumEnvVars) 704 { 705 for (uint32_t i = 0; i < pData->uNumEnvVars; i++) 706 RTStrFree(pData->papszEnv[i]); 707 RTMemFree(pData->papszEnv); 708 } 709 RTGetOptArgvFree(pData->papszArgs); 710 RTStrFree(pData->pszStdIn); 711 RTStrFree(pData->pszStdOut); 712 RTStrFree(pData->pszStdErr); 713 RTStrFree(pData->pszUser); 714 RTStrFree(pData->pszPassword); 715 716 VBoxServiceControlExecDestroyPipeBuffer(&pData->stdOut); 717 VBoxServiceControlExecDestroyPipeBuffer(&pData->stdErr); 718 719 RTMemFree(pData); 720 pData = NULL; 721 } 722 } 723 724 DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREAD pThread) 604 725 { 605 726 AssertPtr(pThread); 606 RTStrFree(pThread->pszCmd); 607 if (pThread->uNumEnvVars) 608 { 609 for (uint32_t i = 0; i < pThread->uNumEnvVars; i++) 610 RTStrFree(pThread->papszEnv[i]); 611 RTMemFree(pThread->papszEnv); 612 } 613 RTGetOptArgvFree(pThread->papszArgs); 614 RTStrFree(pThread->pszStdIn); 615 RTStrFree(pThread->pszStdOut); 616 RTStrFree(pThread->pszStdErr); 617 RTStrFree(pThread->pszUser); 618 RTStrFree(pThread->pszPassword); 619 } 620 621 DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREAD pThread) 622 { 623 AssertPtr(pThread); 624 625 AssertPtr(pThread); 626 AssertPtr(pThread->papszArgs); 627 AssertPtr(pThread->papszEnv); 727 PVBOXSERVICECTRLTHREADDATAEXEC pData = (PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData; 728 AssertPtr(pData); 628 729 629 730 /* … … 632 733 */ 633 734 RTThreadUserSignal(RTThreadSelf()); 634 VBoxServiceVerbose(3, "Control: Thread of process \"%s\" started\n", p Thread->pszCmd);735 VBoxServiceVerbose(3, "Control: Thread of process \"%s\" started\n", pData->pszCmd); 635 736 636 737 int rc = VbglR3GuestCtrlConnect(&pThread->uClientID); … … 649 750 { 650 751 size_t i; 651 for (i = 0; i < p Thread->uNumEnvVars; i++)652 { 653 rc = RTEnvPutEx(hEnv, p Thread->papszEnv[i]);752 for (i = 0; i < pData->uNumEnvVars && pData->papszEnv; i++) 753 { 754 rc = RTEnvPutEx(hEnv, pData->papszEnv[i]); 654 755 if (RT_FAILURE(rc)) 655 756 break; … … 695 796 { 696 797 RTPROCESS hProcess; 697 rc = RTProcCreateEx(p Thread->pszCmd, pThread->papszArgs, hEnv, pThread->uFlags,798 rc = RTProcCreateEx(pData->pszCmd, pData->papszArgs, hEnv, pData->uFlags, 698 799 phStdIn, phStdOut, phStdErr, 699 strlen(p Thread->pszUser) ? pThread->pszUser : NULL,700 strlen(p Thread->pszUser) && strlen(pThread->pszPassword) ? pThread->pszPassword : NULL,800 strlen(pData->pszUser) ? pData->pszUser : NULL, 801 strlen(pData->pszUser) && strlen(pData->pszPassword) ? pData->pszPassword : NULL, 701 802 &hProcess); 702 803 if (RT_SUCCESS(rc)) … … 714 815 /* Enter the process loop. */ 715 816 rc = VBoxServiceControlExecProcLoop(pThread, 716 hProcess, p Thread->uTimeLimitMS, hPollSet,817 hProcess, pData->uTimeLimitMS, hPollSet, 717 818 hStdInW, hStdOutR, hStdErrR); 718 819 … … 732 833 else /* Something went wrong; report error! */ 733 834 { 734 int rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, p Thread->uPID,835 int rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, pData->uPID, 735 836 PROC_STS_ERROR, rc, 736 837 NULL /* pvData */, 0 /* cbData */); … … 756 857 VbglR3GuestCtrlDisconnect(pThread->uClientID); 757 858 VBoxServiceVerbose(3, "Control: Thread of process \"%s\" (PID: %u) ended with rc=%Rrc\n", 758 p Thread->pszCmd, pThread->uPID, rc);859 pData->pszCmd, pData->uPID, rc); 759 860 return rc; 760 861 } … … 807 908 else 808 909 { 910 pThread->fStarted = true; 809 911 /*rc =*/ RTListAppend(&g_GuestControlExecThreads, &pThread->Node); 810 912 } … … 812 914 813 915 if (RT_FAILURE(rc)) 814 VBoxServiceControlExecDestroyThreadData( pThread);916 VBoxServiceControlExecDestroyThreadData((PVBOXSERVICECTRLTHREADDATAEXEC)pThread->pvData); 815 917 } 816 918 if (RT_FAILURE(rc)) -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r28434 r28557 130 130 131 131 #ifdef VBOX_WITH_GUEST_CONTROL 132 /* Structure for holding thread relevant data. */ 133 typedef struct 134 { 135 /** Node. */ 136 RTLISTNODE Node; 137 /** The worker thread. */ 138 RTTHREAD Thread; 139 /** Shutdown indicator. */ 140 bool volatile fShutdown; 141 /** Indicator set by the service thread exiting. */ 142 bool volatile fStopped; 143 /** Whether the service was started or not. */ 144 bool fStarted; 145 /** @todo */ 146 uint32_t uClientID; 147 uint32_t uContextID; 132 enum VBOXSERVICECTRLTHREADDATATYPE 133 { 134 VBoxServiceCtrlThreadDataUnknown = 0, 135 VBoxServiceCtrlThreadDataExec = 1 136 }; 137 138 typedef struct 139 { 140 BYTE *pbData; 141 uint32_t cbSize; 142 uint32_t cbOffset; 143 uint32_t cbRead; 144 } VBOXSERVICECTRLEXECPIPEBUF; 145 /** Pointer to thread data. */ 146 typedef VBOXSERVICECTRLEXECPIPEBUF *PVBOXSERVICECTRLEXECPIPEBUF; 147 148 /* Structure for holding guest exection relevant data. */ 149 typedef struct 150 { 148 151 uint32_t uPID; 149 152 char *pszCmd; … … 159 162 char *pszPassword; 160 163 uint32_t uTimeLimitMS; 164 165 VBOXSERVICECTRLEXECPIPEBUF stdOut; 166 VBOXSERVICECTRLEXECPIPEBUF stdErr; 167 168 } VBOXSERVICECTRLTHREADDATAEXEC; 169 /** Pointer to thread data. */ 170 typedef VBOXSERVICECTRLTHREADDATAEXEC *PVBOXSERVICECTRLTHREADDATAEXEC; 171 172 /* Structure for holding thread relevant data. */ 173 typedef struct 174 { 175 /** Node. */ 176 RTLISTNODE Node; 177 /** The worker thread. */ 178 RTTHREAD Thread; 179 /** Shutdown indicator. */ 180 bool volatile fShutdown; 181 /** Indicator set by the service thread exiting. */ 182 bool volatile fStopped; 183 /** Whether the service was started or not. */ 184 bool fStarted; 185 /** Client ID. */ 186 uint32_t uClientID; 187 /** Context ID. */ 188 uint32_t uContextID; 189 /** Type of thread. See VBOXSERVICECTRLTHREADDATATYPE for more info. */ 190 VBOXSERVICECTRLTHREADDATATYPE enmType; 191 /** Pointer to actual thread data, depending on enmType. */ 192 void *pvData; 161 193 } VBOXSERVICECTRLTHREAD; 162 194 /** Pointer to thread data. */ … … 236 268 const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, 237 269 const char *pszUser, const char *pszPassword, uint32_t uTimeLimitMS); 238 extern void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREAD pThread); 270 extern void VBoxServiceControlExecDestroyThreadData(PVBOXSERVICECTRLTHREADDATAEXEC pThread); 271 extern int VBoxServiceControlExecReadPipeBufferContent(PVBOXSERVICECTRLEXECPIPEBUF pBuf, 272 BYTE *pbBuffer, uint32_t cbBuffer, uint32_t *pcbToRead); 273 extern int VBoxServiceControlExecWritePipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf, 274 BYTE *pbData, uint32_t cbData); 239 275 #endif 240 276
Note:
See TracChangeset
for help on using the changeset viewer.