Changeset 28006 in vbox
- Timestamp:
- Apr 6, 2010 1:54:06 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 59713
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/GuestControl/service.cpp
r27976 r28006 51 51 52 52 namespace guestControl { 53 54 struct Client 55 { 56 VBOXGUESTCTRPARAMBUFFER parmBuf; 57 VBOXHGCMCALLHANDLE callHandle; 58 uint32_t uClientID; 59 }; 60 61 struct HostCmd 62 { 63 VBOXGUESTCTRPARAMBUFFER parmBuf; 64 uint32_t uAssignedToClientID; 65 }; 66 67 /** The client list list type */ 68 typedef std::list <Client> ClientList; 69 /** The host cmd list type */ 70 typedef std::list <HostCmd> HostCmdList; 53 71 54 72 /** … … 76 94 /** User data pointer to be supplied to the host callback function */ 77 95 void *mpvHostData; 78 /** The execution data to hold (atm only one buffer!) */ 79 VBOXGUESTCTRPARAMBUFFER mExec; 96 /** The client list */ 97 ClientList mClients; 98 /** The host command list */ 99 HostCmdList mHostCmds; 80 100 RTCRITSECT critsect; 81 101 … … 95 115 "GuestCtrlReq"); 96 116 #endif 97 mExec.uParmCount = 0;98 mExec.pParms = NULL;99 100 117 if (RT_SUCCESS(rc)) 101 118 rc = RTCritSectInit(&critsect); … … 124 141 * Stub implementation of pfnConnect and pfnDisconnect. 125 142 */ 126 static DECLCALLBACK(int) svcConnectDisconnect (void * /* pvService */, 127 uint32_t /* u32ClientID */, 128 void * /* pvClient */) 129 { 130 return VINF_SUCCESS; 143 static DECLCALLBACK(int) svcConnect (void *pvService, 144 uint32_t u32ClientID, 145 void *pvClient) 146 { 147 AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 148 LogFlowFunc (("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient)); 149 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 150 int rc = pSelf->clientConnect(u32ClientID, pvClient); 151 LogFlowFunc (("rc=%Rrc\n", rc)); 152 return rc; 153 } 154 155 /** 156 * @copydoc VBOXHGCMSVCHELPERS::pfnConnect 157 * Stub implementation of pfnConnect and pfnDisconnect. 158 */ 159 static DECLCALLBACK(int) svcDisconnect (void *pvService, 160 uint32_t u32ClientID, 161 void *pvClient) 162 { 163 AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 164 LogFlowFunc (("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient)); 165 SELF *pSelf = reinterpret_cast<SELF *>(pvService); 166 int rc = pSelf->clientDisconnect(u32ClientID, pvClient); 167 LogFlowFunc (("rc=%Rrc\n", rc)); 168 return rc; 131 169 } 132 170 … … 187 225 int prepareExecute(uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 188 226 static DECLCALLBACK(int) reqThreadFn(RTTHREAD ThreadSelf, void *pvUser); 189 void call (VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, 190 void *pvClient, uint32_t eFunction, uint32_t cParms, 191 VBOXHGCMSVCPARM paParms[]); 192 int hostCall (uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 193 int uninit (); 227 int clientConnect(uint32_t u32ClientID, void *pvClient); 228 int clientDisconnect(uint32_t u32ClientID, void *pvClient); 229 void call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, 230 void *pvClient, uint32_t eFunction, uint32_t cParms, 231 VBOXHGCMSVCPARM paParms[]); 232 int hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 233 int uninit(); 194 234 }; 195 235 … … 341 381 } 342 382 383 int Service::clientConnect(uint32_t u32ClientID, void *pvClient) 384 { 385 ASMBreakpoint(); 386 387 bool bFound = false; 388 for (ClientList::const_iterator it = mClients.begin(); 389 !bFound && it != mClients.end(); ++it) 390 { 391 if (it->uClientID == u32ClientID) 392 bFound = true; 393 } 394 395 if (!bFound) 396 { 397 Client newClient; 398 399 /** @todo Use a constructor here! */ 400 newClient.uClientID = u32ClientID; 401 newClient.parmBuf.uParmCount = 0; 402 newClient.parmBuf.pParms = NULL; 403 404 mClients.push_back(newClient); 405 LogFlowFunc(("New client = %ld connected\n", u32ClientID)); 406 } 407 else 408 { 409 LogFlowFunc(("Exising client (%ld) connected another instance\n", u32ClientID)); 410 } 411 return VINF_SUCCESS; 412 } 413 414 int Service::clientDisconnect(uint32_t u32ClientID, void *pvClient) 415 { 416 ASMBreakpoint(); 417 418 bool bFound = false; 419 for (ClientList::iterator it = mClients.begin(); 420 !bFound && it != mClients.end(); ++it) 421 { 422 if (it->uClientID == u32ClientID) 423 { 424 mClients.erase(it); 425 bFound = true; 426 } 427 } 428 Assert(bFound); 429 430 LogFlowFunc(("Client (%ld) disconnected\n", u32ClientID)); 431 return VINF_SUCCESS; 432 } 433 343 434 /** 344 435 * Handle an HGCM service call. … … 366 457 /* The guest asks the host for the next messsage to process. */ 367 458 case GUEST_GET_HOST_MSG: 368 LogFlowFunc(("GUEST_GET_HOST_MSG\n")); 369 paParms[0].setUInt32(HOST_EXEC_CMD); /* msg id */ 370 paParms[1].setUInt32(12); /* parms count */ 459 LogFlowFunc(("GUEST_GET_HOST_MSG\n")); 460 461 /** @todo !!!!! LOCKING !!!!!!!!! */ 462 463 if (cParms < 2) 464 { 465 LogFlowFunc(("Parameter buffer is too small!\n")); 466 rc = VERR_INVALID_PARAMETER; 467 } 468 else 469 { 470 /* 471 * If host command list is empty (nothing to do right now) just 472 * defer the call until we got something to do (makes the client 473 * wait, depending on the flags set). 474 */ 475 if (mHostCmds.empty()) 476 rc = VINF_HGCM_ASYNC_EXECUTE; 477 478 if (RT_SUCCESS(rc)) 479 { 480 /* 481 * Get the next unassigned host command in the list. 482 */ 483 bool bFound = false; 484 HostCmdList::iterator it; 485 for (it = mHostCmds.begin(); 486 !bFound && it != mHostCmds.end(); ++it) 487 { 488 if (it->uAssignedToClientID == 0) 489 bFound = true; 490 } 491 if (!bFound) /* No new command found, defer ... */ 492 rc = VINF_HGCM_ASYNC_EXECUTE; 493 494 /* 495 * Okay we got a host command which is unassigned at the moment. 496 */ 497 if (RT_SUCCESS(rc)) 498 { 499 /* 500 * Do *not* pop the most recent (front) command here yet, because 501 * the client could fail in retrieving the GUEST_GET_HOST_MSG_DATA message 502 * below. 503 */ 504 uint32_t uCmd = 0; 505 if (it->parmBuf.uParmCount) 506 it->parmBuf.pParms[0].getUInt32(&uCmd); 507 paParms[0].setUInt32(uCmd); /* msg id */ 508 paParms[1].setUInt32(it->parmBuf.uParmCount); /* parms count */ 509 510 /* Assign this command to the specific client ID. */ 511 it->uAssignedToClientID = u32ClientID; 512 } 513 } 514 } 371 515 break; 372 516 373 517 case GUEST_GET_HOST_MSG_DATA: 374 LogFlowFunc(("GUEST_GET_HOST_MSG_DATA\n")); 375 rc = execBufferAssign(&mExec, cParms, paParms); 518 { 519 LogFlowFunc(("GUEST_GET_HOST_MSG_DATA\n")); 520 521 /** @todo !!!!! LOCKING !!!!!!!!! */ 522 523 /* 524 * Get host command assigned to incoming client ID. 525 */ 526 bool bFound = false; 527 HostCmdList::iterator it; 528 for (it = mHostCmds.begin(); 529 !bFound && it != mHostCmds.end(); ++it) 530 { 531 if (it->uAssignedToClientID == u32ClientID) 532 bFound = true; 533 } 534 Assert(bFound); 535 536 /* 537 * Assign buffered data to client HGCM parms. 538 */ 539 rc = execBufferAssign(&it->parmBuf, cParms, paParms); 540 541 /* 542 * Finally remove the command from the list. 543 */ 544 mHostCmds.erase(it); 545 } 376 546 break; 377 547 … … 402 572 if (rc != VINF_HGCM_ASYNC_EXECUTE) 403 573 { 404 mpHelpers->pfnCallComplete 574 mpHelpers->pfnCallComplete(callHandle, rc); 405 575 } 406 576 } … … 424 594 case HOST_EXEC_CMD: 425 595 LogFlowFunc(("HOST_EXEC_CMD\n")); 426 rc = execBufferAllocate(&mExec, cParms, paParms); 596 597 /** @todo !!!!! LOCKING !!!!!!!!! */ 598 599 HostCmd newCmd; 600 execBufferAllocate(&newCmd.parmBuf, cParms, paParms); 601 newCmd.uAssignedToClientID = 0; 602 mHostCmds.push_back(newCmd); 427 603 break; 428 604 … … 504 680 /* Register functions. */ 505 681 ptable->pfnUnload = Service::svcUnload; 506 ptable->pfnConnect = Service::svcConnect Disconnect;507 ptable->pfnDisconnect = Service::svc ConnectDisconnect;682 ptable->pfnConnect = Service::svcConnect; 683 ptable->pfnDisconnect = Service::svcDisconnect; 508 684 ptable->pfnCall = Service::svcCall; 509 685 ptable->pfnHostCall = Service::svcHostCall;
Note:
See TracChangeset
for help on using the changeset viewer.