Changeset 28086 in vbox
- Timestamp:
- Apr 8, 2010 12:32:07 PM (15 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
r28029 r28086 109 109 VBGLR3DECL(int) VbglR3GuestCtrlGetHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms) 110 110 { 111 AssertPtr(puMsg); 112 AssertPtr(puNumParms); 113 111 114 VBoxGuestCtrlHGCMMsgType Msg; 112 115 … … 122 125 if (RT_SUCCESS(rc)) 123 126 { 124 rc = Msg.hdr.result;127 rc = VbglHGCMParmUInt32Get(&Msg.msg, puMsg); 125 128 if (RT_SUCCESS(rc)) 126 { 127 rc = VbglHGCMParmUInt32Get(&Msg.msg, puMsg); 129 rc = VbglHGCMParmUInt32Get(&Msg.num_parms, puNumParms); 128 130 if (RT_SUCCESS(rc)) 129 rc = VbglHGCMParmUInt32Get(&Msg.num_parms, puNumParms); 130 /* Ok, so now we know what message type and how much parameters there are. */ 131 } 131 rc = Msg.hdr.result; 132 /* Ok, so now we know what message type and how much parameters there are. */ 132 133 } 133 134 return rc; … … 176 177 Msg.hdr.result = VERR_WRONG_ORDER; 177 178 Msg.hdr.u32ClientID = u32ClientId; 178 Msg.hdr.u32Function = GUEST_GET_HOST_MSG _DATA; /* Tell the host we want the actual data of a command. */179 Msg.hdr.u32Function = GUEST_GET_HOST_MSG; 179 180 Msg.hdr.cParms = uNumParms; 180 181 … … 196 197 if (RT_SUCCESS(rc)) 197 198 { 198 rc = Msg.hdr.result; 199 200 Msg.flags.GetUInt32(puFlags); 201 Msg.num_args.GetUInt32(puNumArgs); 202 Msg.num_env.GetUInt32(puNumEnvVars); 203 Msg.cb_env.GetUInt32(pcbEnv); 204 Msg.timeout.GetUInt32(puTimeLimit); 199 int rc2 = Msg.hdr.result; 200 if (RT_FAILURE(rc2)) 201 { 202 rc = rc2; 203 } 204 else 205 { 206 Msg.flags.GetUInt32(puFlags); 207 Msg.num_args.GetUInt32(puNumArgs); 208 Msg.num_env.GetUInt32(puNumEnvVars); 209 Msg.cb_env.GetUInt32(pcbEnv); 210 Msg.timeout.GetUInt32(puTimeLimit); 211 } 205 212 } 206 213 return rc; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r28029 r28086 96 96 static int VBoxServiceControlHandleCmdExec(uint32_t u32ClientId, uint32_t uNumParms) 97 97 { 98 VBoxServiceVerbose(3, "VBoxServiceControlHandleCmdExec: Called uNumParms=%ld\n", uNumParms);99 100 98 VBOXSERVICECTRLPROCDATA execData; 101 99 execData.cbEnv = sizeof(execData.szEnv); … … 156 154 /* Do the actual execution. */ 157 155 rc = VBoxServiceControlExecProcess(&execData, ppaArg, ppaEnv); 156 if (RT_FAILURE(rc)) 157 VBoxServiceVerbose(3, "Control: Could not execute process \"%s\"! Error: %Rrc\n", 158 execData.szCmd, rc); 158 159 /* Cleanup. */ 159 160 if (execData.uNumEnvVars) … … 193 194 uint32_t uNumParms; 194 195 rc = VbglR3GuestCtrlGetHostMsg(g_GuestControlSvcClientID, &uMsg, &uNumParms); 196 if (rc == VERR_TOO_MUCH_DATA) 197 { 198 VBoxServiceVerbose(3, "Control: Message requires %ld parameters, but only 2 supplied.\n", uNumParms); 199 rc = VINF_SUCCESS; 200 } 195 201 if (RT_SUCCESS(rc)) 196 202 { … … 202 208 203 209 default: 204 VBoxServiceVerbose(3, " VBoxServiceControlWorker: Unsupported message from host! Msg=%ld\n", uMsg);210 VBoxServiceVerbose(3, "Control: Unsupported message from host! Msg=%ld\n", uMsg); 205 211 /* Don't terminate here; just wait for the next message. */ 206 212 break; … … 221 227 if (rc2 != VERR_TIMEOUT && RT_FAILURE(rc2)) 222 228 { 223 VBoxServiceError(" VBoxServiceControlWorker: RTSemEventMultiWait failed; rc2=%Rrc\n", rc2);229 VBoxServiceError("Control: RTSemEventMultiWait failed; rc2=%Rrc\n", rc2); 224 230 rc = rc2; 225 231 break; -
trunk/src/VBox/HostServices/GuestControl/service.cpp
r28013 r28086 52 52 namespace guestControl { 53 53 54 struct Client 55 { 54 /** 55 * Structure for holding a buffered host command 56 */ 57 struct HostCmd 58 { 59 /** Dynamic structure for holding the HGCM parms */ 56 60 VBOXGUESTCTRPARAMBUFFER parmBuf; 57 VBOXHGCMCALLHANDLE callHandle;58 uint32_t uClientID;59 61 }; 60 61 struct HostCmd62 {63 VBOXGUESTCTRPARAMBUFFER parmBuf;64 uint32_t uAssignedToClientID;65 };66 67 /** The client list list type */68 typedef std::list <Client> ClientList;69 62 /** The host cmd list type */ 70 63 typedef std::list <HostCmd> HostCmdList; 64 65 /** 66 * Structure for holding an uncompleted guest call 67 */ 68 struct GuestCall 69 { 70 /** The call handle */ 71 VBOXHGCMCALLHANDLE mHandle; 72 /** The function that was requested */ 73 uint32_t mFunction; 74 /** The call parameters */ 75 VBOXHGCMSVCPARM *mParms; 76 /** Number of parameters */ 77 uint32_t mNumParms; 78 /** The default return value, used for passing warnings */ 79 int mRc; 80 81 /** The standard constructor */ 82 GuestCall() : mFunction(0) {} 83 /** The normal contructor */ 84 GuestCall(VBOXHGCMCALLHANDLE aHandle, uint32_t aFunction, 85 VBOXHGCMSVCPARM aParms[], int cParms, int aRc) 86 : mHandle(aHandle), mFunction(aFunction), mParms(aParms), 87 mNumParms(cParms), mRc(aRc) {} 88 }; 89 /** The guest call list type */ 90 typedef std::list <GuestCall> CallList; 71 91 72 92 /** … … 94 114 /** User data pointer to be supplied to the host callback function */ 95 115 void *mpvHostData; 96 /** The clientlist */97 C lientList mClients;116 /** The deferred calls list */ 117 CallList mGuestWaiters; 98 118 /** The host command list */ 99 119 HostCmdList mHostCmds; … … 227 247 int clientConnect(uint32_t u32ClientID, void *pvClient); 228 248 int clientDisconnect(uint32_t u32ClientID, void *pvClient); 249 int guestGetHostMsg(VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 250 int hostNotifyGuest(GuestCall *pCall, uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 251 int hostProcessCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 229 252 void call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, 230 253 void *pvClient, uint32_t eFunction, uint32_t cParms, … … 381 404 int Service::clientConnect(uint32_t u32ClientID, void *pvClient) 382 405 { 383 ASMBreakpoint(); 384 385 bool bFound = false; 386 for (ClientList::const_iterator it = mClients.begin(); 387 !bFound && it != mClients.end(); ++it) 388 { 389 if (it->uClientID == u32ClientID) 390 bFound = true; 391 } 392 393 if (!bFound) 394 { 395 Client newClient; 396 397 /** @todo Use a constructor here! */ 398 newClient.uClientID = u32ClientID; 399 newClient.parmBuf.uParmCount = 0; 400 newClient.parmBuf.pParms = NULL; 401 402 mClients.push_back(newClient); 403 LogFlowFunc(("New client = %ld connected\n", u32ClientID)); 404 } 405 else 406 { 407 LogFlowFunc(("Exising client (%ld) connected another instance\n", u32ClientID)); 408 } 406 LogFlowFunc(("New client (%ld) connected\n", u32ClientID)); 409 407 return VINF_SUCCESS; 410 408 } … … 412 410 int Service::clientDisconnect(uint32_t u32ClientID, void *pvClient) 413 411 { 414 ASMBreakpoint();415 416 bool bFound = false;417 for (ClientList::iterator it = mClients.begin();418 !bFound && it != mClients.end(); ++it)419 {420 if (it->uClientID == u32ClientID)421 {422 mClients.erase(it);423 bFound = true;424 }425 }426 Assert(bFound);427 428 412 LogFlowFunc(("Client (%ld) disconnected\n", u32ClientID)); 429 413 return VINF_SUCCESS; 414 } 415 416 /* 417 * Either fills in parameters from a pending host command into our guest context or 418 * defer the guest call until we have something from the host. 419 */ 420 int Service::guestGetHostMsg(VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 421 { 422 int rc = VINF_SUCCESS; 423 424 /** @todo !!!!! LOCKING !!!!!!!!! */ 425 426 if (cParms < 2) 427 { 428 LogFlowFunc(("Parameter buffer is too small!\n")); 429 rc = VERR_INVALID_PARAMETER; 430 } 431 else 432 { 433 /* 434 * If host command list is empty (nothing to do right now) just 435 * defer the call until we got something to do (makes the client 436 * wait, depending on the flags set). 437 */ 438 if (mHostCmds.empty()) /* Command list is empty, defer ... */ 439 rc = VINF_HGCM_ASYNC_EXECUTE; 440 441 if (rc != VINF_HGCM_ASYNC_EXECUTE) 442 { 443 /* 444 * Get the next unassigned host command in the list. 445 */ 446 HostCmd curCmd = mHostCmds.front(); 447 uint32_t uParmCount = curCmd.parmBuf.uParmCount; 448 449 /* Sufficient parameter space? */ 450 if (uParmCount > cParms) 451 { 452 uint32_t uCmd = 0; 453 if (uParmCount) 454 curCmd.parmBuf.pParms[0].getUInt32(&uCmd); 455 456 paParms[0].setUInt32(/*uCmd*/ 1); /* Message ID */ 457 paParms[1].setUInt32(uParmCount); /* Required parameters for message */ 458 459 /* 460 * So this call apparently failed because the guest wanted to peek 461 * how much parameters it has to supply in order to successfully retrieve 462 * this command. Let's tell him so! 463 */ 464 rc = VERR_TOO_MUCH_DATA; 465 } 466 else 467 { 468 rc = execBufferAssign(&curCmd.parmBuf, cParms, paParms); 469 if (RT_SUCCESS(rc)) 470 mHostCmds.pop_front(); 471 } 472 } 473 else 474 { 475 /* Call is deferred because of reasons above. */ 476 mGuestWaiters.push_back(GuestCall(callHandle, GUEST_GET_HOST_MSG, 477 paParms, cParms, rc)); 478 } 479 } 480 return rc; 481 } 482 483 /* 484 * Sends a command notification to the first waiting (deferred) client/guest in line in 485 * order to wake up and do some work. 486 */ 487 int Service::hostNotifyGuest(GuestCall *pCall, uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 488 { 489 /** @todo !!!!! LOCKING !!!!!!!!! */ 490 491 AssertPtr(pCall); 492 int rc = VINF_SUCCESS; 493 494 int rc2 = guestGetHostMsg(pCall->mHandle, pCall->mNumParms, pCall->mParms); 495 if (RT_SUCCESS(rc2)) 496 rc2 = pCall->mRc; 497 AssertPtr(mpHelpers); 498 mpHelpers->pfnCallComplete(pCall->mHandle, rc2); 499 return rc; 500 } 501 502 int Service::hostProcessCmd(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 503 { 504 /** @todo !!!!! LOCKING !!!!!!!!! */ 505 506 int rc = VINF_SUCCESS; 507 508 HostCmd newCmd; 509 execBufferAllocate(&newCmd.parmBuf, cParms, paParms); 510 mHostCmds.push_back(newCmd); 511 512 /* Limit list size by deleting oldest element. */ 513 if (mHostCmds.size() > 256) /** @todo Use a define! */ 514 mHostCmds.pop_front(); 515 516 /* Some lazy guests to wake up? */ 517 if (!mGuestWaiters.empty()) 518 { 519 GuestCall curCall = mGuestWaiters.front(); 520 rc = hostNotifyGuest(&curCall, eFunction, cParms, paParms); 521 mGuestWaiters.pop_front(); 522 } 523 return rc; 430 524 } 431 525 … … 456 550 case GUEST_GET_HOST_MSG: 457 551 LogFlowFunc(("GUEST_GET_HOST_MSG\n")); 458 459 /** @todo !!!!! LOCKING !!!!!!!!! */ 460 461 if (cParms < 2) 462 { 463 LogFlowFunc(("Parameter buffer is too small!\n")); 464 rc = VERR_INVALID_PARAMETER; 465 } 466 else 467 { 468 /* 469 * If host command list is empty (nothing to do right now) just 470 * defer the call until we got something to do (makes the client 471 * wait, depending on the flags set). 472 */ 473 if (mHostCmds.empty()) 474 rc = VINF_HGCM_ASYNC_EXECUTE; 475 476 if ( RT_SUCCESS(rc) 477 && rc != VINF_HGCM_ASYNC_EXECUTE) 478 { 479 /* 480 * Get the next unassigned host command in the list. 481 */ 482 bool bFound = false; 483 HostCmdList::iterator it; 484 for (it = mHostCmds.begin(); 485 !bFound && it != mHostCmds.end(); ++it) 486 { 487 if (it->uAssignedToClientID == 0) 488 { 489 bFound = true; 490 break; 491 } 492 } 493 if (!bFound) /* No new command found, defer ... */ 494 rc = VINF_HGCM_ASYNC_EXECUTE; 495 496 /* 497 * Okay we got a host command which is unassigned at the moment. 498 */ 499 if ( RT_SUCCESS(rc) 500 && rc != VINF_HGCM_ASYNC_EXECUTE) 501 { 502 /* 503 * Do *not* remove the command from host cmds list here yet, because 504 * the client could fail in retrieving the GUEST_GET_HOST_MSG_DATA message 505 * below. Then we just could repeat this one here. 506 */ 507 uint32_t uCmd = 1; /** @todo HARDCODED FOR EXEC! */ 508 uint32_t uParmCount = it->parmBuf.uParmCount; 509 if (uParmCount) 510 it->parmBuf.pParms[0].getUInt32(&uCmd); 511 paParms[0].setUInt32(uCmd); /* msg id */ 512 paParms[1].setUInt32(uParmCount); /* parms count */ 513 514 /* Assign this command to the specific client ID. */ 515 it->uAssignedToClientID = u32ClientID; 516 } 517 } 518 } 519 break; 520 521 case GUEST_GET_HOST_MSG_DATA: 522 { 523 LogFlowFunc(("GUEST_GET_HOST_MSG_DATA\n")); 524 525 /** @todo !!!!! LOCKING !!!!!!!!! */ 526 527 /* 528 * Get host command assigned to incoming client ID. 529 */ 530 bool bFound = false; 531 HostCmdList::iterator it; 532 for (it = mHostCmds.begin(); 533 !bFound && it != mHostCmds.end(); ++it) 534 { 535 if (it->uAssignedToClientID == u32ClientID) 536 { 537 bFound = true; 538 break; 539 } 540 } 541 Assert(bFound); 542 543 /* 544 * Assign buffered data to client HGCM parms. 545 */ 546 rc = execBufferAssign(&it->parmBuf, cParms, paParms); 547 548 /* 549 * Finally remove the command from the list. 550 */ 551 execBufferFree(&it->parmBuf); 552 mHostCmds.erase(it); 553 } 552 rc = guestGetHostMsg(callHandle, cParms, paParms); 554 553 break; 555 554 … … 572 571 rc = VERR_NOT_IMPLEMENTED; 573 572 } 573 /* 574 * If current call is not deferred, call the completion function. 575 */ 576 if (rc != VINF_HGCM_ASYNC_EXECUTE) 577 { 578 mpHelpers->pfnCallComplete(callHandle, rc); 579 } 574 580 } 575 581 catch (std::bad_alloc) … … 578 584 } 579 585 LogFlowFunc(("rc = %Rrc\n", rc)); 580 if (rc != VINF_HGCM_ASYNC_EXECUTE)581 {582 mpHelpers->pfnCallComplete(callHandle, rc);583 }584 586 } 585 587 … … 604 606 case HOST_EXEC_CMD: 605 607 LogFlowFunc(("HOST_EXEC_CMD\n")); 606 607 /** @todo !!!!! LOCKING !!!!!!!!! */ 608 609 HostCmd newCmd; 610 execBufferAllocate(&newCmd.parmBuf, cParms, paParms); 611 newCmd.uAssignedToClientID = 0; 612 mHostCmds.push_back(newCmd); 608 rc = hostProcessCmd(eFunction, cParms, paParms); 613 609 break; 614 610
Note:
See TracChangeset
for help on using the changeset viewer.