Changeset 44863 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Feb 28, 2013 12:18:17 PM (12 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/VBox-3.0/src/VBox 58652,70973 /branches/VBox-3.2/src/VBox 66309,66318 /branches/VBox-4.0/src/VBox 70873 /branches/VBox-4.1/src/VBox 74233,78414,78691,81841,82127 /branches/andy/guestctrl20/src/VBox 78916,78930 /branches/dsen/gui/src/VBox 79076-79078,79089,79109-79110,79112-79113,79127-79130,79134,79141,79151,79155,79157-79159,79193,79197 /branches/dsen/gui2/src/VBox 79224,79228,79233,79235,79258,79262-79263,79273,79341,79345,79354,79357,79387-79388,79559-79569,79572-79573,79578,79581-79582,79590-79591,79598-79599,79602-79603,79605-79606,79632,79635,79637,79644 /branches/dsen/gui3/src/VBox 79645-79692
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp
r44528 r44863 5 5 6 6 /* 7 * Copyright (C) 2010-201 2Oracle Corporation7 * Copyright (C) 2010-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 50 50 * 51 51 * @returns VBox status code 52 * @param pu 32ClientId Where to put the client id on success. The client id53 * 54 */ 55 VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pu 32ClientId)52 * @param puClientId Where to put the client id on success. The client id 53 * must be passed to all the other calls to the service. 54 */ 55 VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *puClientId) 56 56 { 57 57 VBoxGuestHGCMConnectInfo Info; … … 67 67 rc = Info.result; 68 68 if (RT_SUCCESS(rc)) 69 *pu 32ClientId = Info.u32ClientID;69 *puClientId = Info.u32ClientID; 70 70 } 71 71 return rc; … … 77 77 * 78 78 * @returns VBox status code. 79 * @param u 32ClientId The client id returned by VbglR3GuestCtrlConnect().80 */ 81 VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u 32ClientId)79 * @param uClientId The client id returned by VbglR3GuestCtrlConnect(). 80 */ 81 VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t uClientId) 82 82 { 83 83 VBoxGuestHGCMDisconnectInfo Info; 84 84 Info.result = VERR_WRONG_ORDER; 85 Info.u32ClientID = u 32ClientId;85 Info.u32ClientID = uClientId; 86 86 87 87 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info)); … … 97 97 * 98 98 * @returns VBox status code. 99 * @param u 32ClientIdThe client id returned by VbglR3GuestCtrlConnect().99 * @param uClientId The client id returned by VbglR3GuestCtrlConnect(). 100 100 * @param puMsg Where to store the message id. 101 101 * @param puNumParms Where to store the number of parameters which will be received 102 102 * in a second call to the host. 103 103 */ 104 VBGLR3DECL(int) VbglR3GuestCtrl WaitForHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms)104 VBGLR3DECL(int) VbglR3GuestCtrlMsgWaitFor(uint32_t uClientId, uint32_t *puMsg, uint32_t *puNumParms) 105 105 { 106 106 AssertPtrReturn(puMsg, VERR_INVALID_POINTER); 107 107 AssertPtrReturn(puNumParms, VERR_INVALID_POINTER); 108 108 109 VBoxGuestCtrlHGCMMsgTypeMsg;110 111 Msg.hdr.result = VERR_WRONG_ORDER; 112 Msg.hdr.u32ClientID = u 32ClientId;113 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG; /* Tell the host we want our next command. */114 Msg.hdr.cParms = 2; 109 HGCMMsgCmdWaitFor Msg; 110 111 Msg.hdr.result = VERR_WRONG_ORDER; 112 Msg.hdr.u32ClientID = uClientId; 113 Msg.hdr.u32Function = GUEST_MSG_WAIT; /* Tell the host we want our next command. */ 114 Msg.hdr.cParms = 2; /* Just peek for the next message! */ 115 115 116 116 VbglHGCMParmUInt32Set(&Msg.msg, 0); … … 132 132 133 133 /** 134 * Asks the host guest control service to set a command filter to this 135 * client so that it only will receive certain commands in the future. 136 * 137 * @return IPRT status code. 138 * @param uClientId The client id returned by VbglR3GuestCtrlConnect(). 139 * @param uFilterAdd Filter mask to add. 140 * @param uFilterRemove Filter mask to remove. 141 */ 142 VBGLR3DECL(int) VbglR3GuestCtrlMsgSetFilter(uint32_t uClientId, 143 uint32_t uFilterAdd, uint32_t uFilterRemove) 144 { 145 HGCMMsgCmdSetFilter Msg; 146 147 Msg.hdr.result = VERR_WRONG_ORDER; 148 Msg.hdr.u32ClientID = uClientId; 149 Msg.hdr.u32Function = GUEST_MSG_FILTER; /* Tell the host we want to set a filter. */ 150 Msg.hdr.cParms = 2; 151 152 VbglHGCMParmUInt32Set(&Msg.add, uFilterAdd); 153 VbglHGCMParmUInt32Set(&Msg.remove, uFilterRemove); 154 155 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 156 if (RT_SUCCESS(rc)) 157 rc = Msg.hdr.result; 158 return rc; 159 } 160 161 162 /** 134 163 * Asks the host to cancel (release) all pending waits which were deferred. 135 164 * 136 165 * @returns VBox status code. 137 * @param u 32ClientId The client id returned by VbglR3GuestCtrlConnect().138 */ 139 VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u 32ClientId)140 { 141 VBoxGuestCtrlHGCMMsgCancelPendingWaits Msg;142 143 Msg.hdr.result = VERR_WRONG_ORDER; 144 Msg.hdr.u32ClientID = u 32ClientId;166 * @param uClientId The client id returned by VbglR3GuestCtrlConnect(). 167 */ 168 VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t uClientId) 169 { 170 HGCMMsgCancelPendingWaits Msg; 171 172 Msg.hdr.result = VERR_WRONG_ORDER; 173 Msg.hdr.u32ClientID = uClientId; 145 174 Msg.hdr.u32Function = GUEST_CANCEL_PENDING_WAITS; 146 175 Msg.hdr.cParms = 0; … … 157 186 158 187 188 VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(uint32_t uClientId, uint32_t uContext, 189 uint32_t uType, uint32_t uResult) 190 { 191 HGCMMsgSessionNotify Msg; 192 193 Msg.hdr.result = VERR_WRONG_ORDER; 194 Msg.hdr.u32ClientID = uClientId; 195 Msg.hdr.u32Function = GUEST_SESSION_NOTIFY; 196 Msg.hdr.cParms = 3; 197 198 VbglHGCMParmUInt32Set(&Msg.context, uContext); 199 VbglHGCMParmUInt32Set(&Msg.type, uType); 200 VbglHGCMParmUInt32Set(&Msg.result, uResult); 201 202 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 203 if (RT_SUCCESS(rc)) 204 { 205 int rc2 = Msg.hdr.result; 206 if (RT_FAILURE(rc2)) 207 rc = rc2; 208 } 209 return rc; 210 } 211 212 213 /** 214 * Retrieves the request to create a new guest session. 215 * 216 * @return IPRT status code. 217 * @param pHostCtx Host context. 218 ** @todo Docs! 219 */ 220 VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 221 uint32_t *puProtocol, 222 char *pszUser, uint32_t cbUser, 223 char *pszPassword, uint32_t cbPassword, 224 char *pszDomain, uint32_t cbDomain, 225 uint32_t *puFlags, uint32_t *puSessionID) 226 { 227 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 228 AssertReturn(pHostCtx->uNumParms == 6, VERR_INVALID_PARAMETER); 229 230 AssertPtrReturn(puProtocol, VERR_INVALID_POINTER); 231 AssertPtrReturn(pszUser, VERR_INVALID_POINTER); 232 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER); 233 AssertPtrReturn(pszDomain, VERR_INVALID_POINTER); 234 AssertPtrReturn(puFlags, VERR_INVALID_POINTER); 235 236 HGCMMsgSessionOpen Msg; 237 238 Msg.hdr.result = VERR_WRONG_ORDER; 239 Msg.hdr.u32ClientID = pHostCtx->uClientID; 240 Msg.hdr.u32Function = GUEST_MSG_WAIT; 241 Msg.hdr.cParms = pHostCtx->uNumParms; 242 243 VbglHGCMParmUInt32Set(&Msg.context, 0); 244 VbglHGCMParmUInt32Set(&Msg.protocol, 0); 245 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser); 246 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword); 247 VbglHGCMParmPtrSet(&Msg.domain, pszDomain, cbDomain); 248 VbglHGCMParmUInt32Set(&Msg.flags, 0); 249 250 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 251 if (RT_SUCCESS(rc)) 252 { 253 int rc2 = Msg.hdr.result; 254 if (RT_FAILURE(rc2)) 255 { 256 rc = rc2; 257 } 258 else 259 { 260 Msg.context.GetUInt32(&pHostCtx->uContextID); 261 Msg.protocol.GetUInt32(puProtocol); 262 Msg.flags.GetUInt32(puFlags); 263 264 if (puSessionID) 265 *puSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHostCtx->uContextID); 266 } 267 } 268 269 return rc; 270 } 271 272 273 /** 274 * Retrieves the request to terminate an existing guest session. 275 * 276 * @return IPRT status code. 277 * @param pHostCtx Host context. 278 ** @todo Docs! 279 */ 280 VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puFlags, uint32_t *puSessionID) 281 { 282 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 283 AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER); 284 285 AssertPtrReturn(puFlags, VERR_INVALID_POINTER); 286 287 HGCMMsgSessionClose Msg; 288 289 Msg.hdr.result = VERR_WRONG_ORDER; 290 Msg.hdr.u32ClientID = pHostCtx->uClientID; 291 Msg.hdr.u32Function = GUEST_MSG_WAIT; 292 Msg.hdr.cParms = pHostCtx->uNumParms; 293 294 VbglHGCMParmUInt32Set(&Msg.context, 0); 295 VbglHGCMParmUInt32Set(&Msg.flags, 0); 296 297 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 298 if (RT_SUCCESS(rc)) 299 { 300 int rc2 = Msg.hdr.result; 301 if (RT_FAILURE(rc2)) 302 { 303 rc = rc2; 304 } 305 else 306 { 307 Msg.context.GetUInt32(&pHostCtx->uContextID); 308 Msg.flags.GetUInt32(puFlags); 309 310 if (puSessionID) 311 *puSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHostCtx->uContextID); 312 } 313 } 314 315 return rc; 316 } 317 318 159 319 /** 160 320 * Allocates and gets host data, based on the message id. … … 163 323 * 164 324 * @returns VBox status code. 165 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().166 * @param uNumParms167 325 ** @todo Docs! 168 */ 169 VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdExec(uint32_t u32ClientId, uint32_t cParms, 170 uint32_t *puContext, 171 char *pszCmd, uint32_t cbCmd, 172 uint32_t *puFlags, 173 char *pszArgs, uint32_t cbArgs, uint32_t *pcArgs, 174 char *pszEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars, 175 char *pszUser, uint32_t cbUser, 176 char *pszPassword, uint32_t cbPassword, 177 uint32_t *pcMsTimeLimit) 178 { 179 AssertReturn(cParms == 11, VERR_INVALID_PARAMETER); 180 181 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 326 ** @todo Move the parameters in an own struct! 327 */ 328 VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 329 char *pszCmd, uint32_t cbCmd, 330 uint32_t *puFlags, 331 char *pszArgs, uint32_t cbArgs, uint32_t *pcArgs, 332 char *pszEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars, 333 char *pszUser, uint32_t cbUser, 334 char *pszPassword, uint32_t cbPassword, 335 uint32_t *puTimeoutMS, 336 uint32_t *puPriority, 337 uint64_t *puAffinity, uint32_t cbAffinity, uint32_t *pcAffinity) 338 { 339 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 340 182 341 AssertPtrReturn(pszCmd, VERR_INVALID_POINTER); 183 342 AssertPtrReturn(puFlags, VERR_INVALID_POINTER); … … 187 346 AssertPtrReturn(pcbEnv, VERR_INVALID_POINTER); 188 347 AssertPtrReturn(pcEnvVars, VERR_INVALID_POINTER); 189 AssertPtrReturn(pszUser, VERR_INVALID_POINTER); 190 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER); 191 AssertPtrReturn(pcMsTimeLimit, VERR_INVALID_POINTER); 192 193 VBoxGuestCtrlHGCMMsgExecCmd Msg; 194 195 Msg.hdr.result = VERR_WRONG_ORDER; 196 Msg.hdr.u32ClientID = u32ClientId; 197 Msg.hdr.u32Function = GUEST_GET_HOST_MSG; 198 Msg.hdr.cParms = 11; 348 AssertPtrReturn(puTimeoutMS, VERR_INVALID_POINTER); 349 350 HGCMMsgProcExec Msg; 351 352 Msg.hdr.result = VERR_WRONG_ORDER; 353 Msg.hdr.u32ClientID = pHostCtx->uClientID; 354 Msg.hdr.u32Function = GUEST_MSG_WAIT; 355 Msg.hdr.cParms = pHostCtx->uNumParms; 199 356 200 357 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 206 363 VbglHGCMParmUInt32Set(&Msg.cb_env, 0); 207 364 VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv); 208 VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser); 209 VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword); 210 VbglHGCMParmUInt32Set(&Msg.timeout, 0); 211 212 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 213 if (RT_SUCCESS(rc)) 214 { 215 int rc2 = Msg.hdr.result; 216 if (RT_FAILURE(rc2)) 217 { 218 rc = rc2; 219 } 220 else 221 { 222 Msg.context.GetUInt32(puContext); 365 if (pHostCtx->uProtocol < 2) 366 { 367 AssertPtrReturn(pszUser, VERR_INVALID_POINTER); 368 AssertReturn(cbUser, VERR_INVALID_PARAMETER); 369 AssertPtrReturn(pszPassword, VERR_INVALID_POINTER); 370 AssertReturn(pszPassword, VERR_INVALID_PARAMETER); 371 372 VbglHGCMParmPtrSet(&Msg.u.v1.username, pszUser, cbUser); 373 VbglHGCMParmPtrSet(&Msg.u.v1.password, pszPassword, cbPassword); 374 VbglHGCMParmUInt32Set(&Msg.u.v1.timeout, 0); 375 } 376 else 377 { 378 AssertPtrReturn(puAffinity, VERR_INVALID_POINTER); 379 AssertReturn(cbAffinity, VERR_INVALID_PARAMETER); 380 381 VbglHGCMParmUInt32Set(&Msg.u.v2.timeout, 0); 382 VbglHGCMParmUInt32Set(&Msg.u.v2.priority, 0); 383 VbglHGCMParmUInt32Set(&Msg.u.v2.num_affinity, 0); 384 VbglHGCMParmPtrSet(&Msg.u.v2.affinity, puAffinity, cbAffinity); 385 } 386 387 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 388 if (RT_SUCCESS(rc)) 389 { 390 int rc2 = Msg.hdr.result; 391 if (RT_FAILURE(rc2)) 392 { 393 rc = rc2; 394 } 395 else 396 { 397 Msg.context.GetUInt32(&pHostCtx->uContextID); 223 398 Msg.flags.GetUInt32(puFlags); 224 399 Msg.num_args.GetUInt32(pcArgs); 225 400 Msg.num_env.GetUInt32(pcEnvVars); 226 401 Msg.cb_env.GetUInt32(pcbEnv); 227 Msg.timeout.GetUInt32(pcMsTimeLimit); 402 if (pHostCtx->uProtocol < 2) 403 { 404 Msg.u.v1.timeout.GetUInt32(puTimeoutMS); 405 } 406 else 407 { 408 Msg.u.v2.timeout.GetUInt32(puTimeoutMS); 409 Msg.u.v2.priority.GetUInt32(puPriority); 410 Msg.u.v2.num_affinity.GetUInt32(pcAffinity); 411 } 228 412 } 229 413 } … … 238 422 * 239 423 * @returns VBox status code. 240 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().241 * @param cParms242 424 ** @todo Docs! 243 425 */ 244 VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t cParms, 245 uint32_t *puContext, uint32_t *puPID, 246 uint32_t *puHandle, uint32_t *puFlags) 247 { 248 AssertReturn(cParms == 4, VERR_INVALID_PARAMETER); 249 250 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 426 VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 427 uint32_t *puPID, uint32_t *puHandle, uint32_t *puFlags) 428 { 429 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 430 AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER); 431 251 432 AssertPtrReturn(puPID, VERR_INVALID_POINTER); 252 433 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 253 434 AssertPtrReturn(puFlags, VERR_INVALID_POINTER); 254 435 255 VBoxGuestCtrlHGCMMsgExecOut Msg;436 HGCMMsgProcOutput Msg; 256 437 257 438 Msg.hdr.result = VERR_WRONG_ORDER; 258 Msg.hdr.u32ClientID = u32ClientId;259 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;260 Msg.hdr.cParms = 4;439 Msg.hdr.u32ClientID = pHostCtx->uClientID; 440 Msg.hdr.u32Function = GUEST_MSG_WAIT; 441 Msg.hdr.cParms = pHostCtx->uNumParms; 261 442 262 443 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 275 456 else 276 457 { 277 Msg.context.GetUInt32( puContext);458 Msg.context.GetUInt32(&pHostCtx->uContextID); 278 459 Msg.pid.GetUInt32(puPID); 279 460 Msg.handle.GetUInt32(puHandle); … … 292 473 * 293 474 * @returns VBox status code. 294 * @param u32ClientId The client id returned by VbglR3GuestCtrlConnect().295 * @param cParms296 475 ** @todo Docs! 297 476 */ 298 VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uint32_t cParms, 299 uint32_t *puContext, uint32_t *puPID, 300 uint32_t *puFlags, 301 void *pvData, uint32_t cbData, 302 uint32_t *pcbSize) 303 { 304 AssertReturn(cParms == 5, VERR_INVALID_PARAMETER); 305 306 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 477 VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 478 uint32_t *puPID, uint32_t *puFlags, 479 void *pvData, uint32_t cbData, 480 uint32_t *pcbSize) 481 { 482 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 483 AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER); 484 307 485 AssertPtrReturn(puPID, VERR_INVALID_POINTER); 308 486 AssertPtrReturn(puFlags, VERR_INVALID_POINTER); … … 310 488 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER); 311 489 312 VBoxGuestCtrlHGCMMsgExecInMsg;313 314 Msg.hdr.result = VERR_WRONG_ORDER; 315 Msg.hdr.u32ClientID = u32ClientId;316 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;317 Msg.hdr.cParms = 5;490 HGCMMsgProcInput Msg; 491 492 Msg.hdr.result = VERR_WRONG_ORDER; 493 Msg.hdr.u32ClientID = pHostCtx->uClientID; 494 Msg.hdr.u32Function = GUEST_MSG_WAIT; 495 Msg.hdr.cParms = pHostCtx->uNumParms; 318 496 319 497 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 333 511 else 334 512 { 335 Msg.context.GetUInt32( puContext);513 Msg.context.GetUInt32(&pHostCtx->uContextID); 336 514 Msg.pid.GetUInt32(puPID); 337 515 Msg.flags.GetUInt32(puFlags); … … 343 521 344 522 345 /** 346 * Reports the process status (along with some other stuff) to the host. 347 * 348 * @returns VBox status code. 349 ** @todo Docs! 350 */ 351 VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatus(uint32_t u32ClientId, 352 uint32_t u32Context, 353 uint32_t u32PID, 354 uint32_t u32Status, 355 uint32_t u32Flags, 356 void *pvData, 357 uint32_t cbData) 358 { 359 VBoxGuestCtrlHGCMMsgExecStatus Msg; 360 361 Msg.hdr.result = VERR_WRONG_ORDER; 362 Msg.hdr.u32ClientID = u32ClientId; 363 Msg.hdr.u32Function = GUEST_EXEC_SEND_STATUS; 364 Msg.hdr.cParms = 5; 365 366 VbglHGCMParmUInt32Set(&Msg.context, u32Context); 367 VbglHGCMParmUInt32Set(&Msg.pid, u32PID); 368 VbglHGCMParmUInt32Set(&Msg.status, u32Status); 369 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); 370 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData); 371 372 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 373 if (RT_SUCCESS(rc)) 374 { 375 int rc2 = Msg.hdr.result; 376 if (RT_FAILURE(rc2)) 377 rc = rc2; 378 } 379 return rc; 380 } 381 382 383 /** 384 * Sends output (from stdout/stderr) from a running process. 385 * 386 * @returns VBox status code. 387 ** @todo Docs! 388 */ 389 VBGLR3DECL(int) VbglR3GuestCtrlExecSendOut(uint32_t u32ClientId, 390 uint32_t u32Context, 391 uint32_t u32PID, 392 uint32_t u32Handle, 393 uint32_t u32Flags, 394 void *pvData, 395 uint32_t cbData) 396 { 397 VBoxGuestCtrlHGCMMsgExecOut Msg; 398 399 Msg.hdr.result = VERR_WRONG_ORDER; 400 Msg.hdr.u32ClientID = u32ClientId; 401 Msg.hdr.u32Function = GUEST_EXEC_SEND_OUTPUT; 402 Msg.hdr.cParms = 5; 403 404 VbglHGCMParmUInt32Set(&Msg.context, u32Context); 405 VbglHGCMParmUInt32Set(&Msg.pid, u32PID); 406 VbglHGCMParmUInt32Set(&Msg.handle, u32Handle); 407 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); 408 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData); 409 410 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 411 if (RT_SUCCESS(rc)) 412 { 413 int rc2 = Msg.hdr.result; 414 if (RT_FAILURE(rc2)) 415 rc = rc2; 416 } 417 return rc; 418 } 419 420 421 /** 422 * Reports back the input status to the host. 423 * 424 * @returns VBox status code. 425 ** @todo Docs! 426 */ 427 VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatusIn(uint32_t u32ClientId, 428 uint32_t u32Context, 429 uint32_t u32PID, 430 uint32_t u32Status, 431 uint32_t u32Flags, 432 uint32_t cbWritten) 433 { 434 VBoxGuestCtrlHGCMMsgExecStatusIn Msg; 435 436 Msg.hdr.result = VERR_WRONG_ORDER; 437 Msg.hdr.u32ClientID = u32ClientId; 438 Msg.hdr.u32Function = GUEST_EXEC_SEND_INPUT_STATUS; 439 Msg.hdr.cParms = 5; 440 441 VbglHGCMParmUInt32Set(&Msg.context, u32Context); 442 VbglHGCMParmUInt32Set(&Msg.pid, u32PID); 443 VbglHGCMParmUInt32Set(&Msg.status, u32Status); 444 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); 445 VbglHGCMParmUInt32Set(&Msg.written, cbWritten); 446 447 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 448 if (RT_SUCCESS(rc)) 449 { 450 int rc2 = Msg.hdr.result; 451 if (RT_FAILURE(rc2)) 452 rc = rc2; 453 } 454 return rc; 455 } 456 457 458 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdOpen(uint32_t uClientId, uint32_t cParms, 459 uint32_t *puContext, 460 char *pszFileName, uint32_t cbFileName, 461 char *pszOpenMode, uint32_t cbOpenMode, 462 char *pszDisposition, uint32_t cbDisposition, 463 uint32_t *puCreationMode, 464 uint64_t *puOffset) 465 { 466 AssertReturn(cParms == 6, VERR_INVALID_PARAMETER); 467 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 523 VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 524 char *pszFileName, uint32_t cbFileName, 525 char *pszOpenMode, uint32_t cbOpenMode, 526 char *pszDisposition, uint32_t cbDisposition, 527 uint32_t *puCreationMode, 528 uint64_t *puOffset) 529 { 530 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 531 AssertReturn(pHostCtx->uNumParms == 6, VERR_INVALID_PARAMETER); 532 468 533 AssertPtrReturn(pszFileName, VERR_INVALID_POINTER); 469 534 AssertReturn(cbFileName, VERR_INVALID_PARAMETER); … … 475 540 AssertPtrReturn(puOffset, VERR_INVALID_POINTER); 476 541 477 VBoxGuestCtrlHGCMMsgFileOpen Msg;478 479 Msg.hdr.result = VERR_WRONG_ORDER; 480 Msg.hdr.u32ClientID = uClientId;481 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;482 Msg.hdr.cParms = 6;542 HGCMMsgFileOpen Msg; 543 544 Msg.hdr.result = VERR_WRONG_ORDER; 545 Msg.hdr.u32ClientID = pHostCtx->uClientID; 546 Msg.hdr.u32Function = GUEST_MSG_WAIT; 547 Msg.hdr.cParms = pHostCtx->uNumParms; 483 548 484 549 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 499 564 else 500 565 { 501 Msg.context.GetUInt32( puContext);566 Msg.context.GetUInt32(&pHostCtx->uContextID); 502 567 Msg.creationmode.GetUInt32(puCreationMode); 503 568 Msg.offset.GetUInt64(puOffset); … … 508 573 509 574 510 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdClose(uint32_t uClientId, uint32_t cParms, 511 uint32_t *puContext, 512 uint32_t *puHandle) 513 { 514 AssertReturn(cParms == 2, VERR_INVALID_PARAMETER); 515 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 575 VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle) 576 { 577 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 578 579 AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER); 516 580 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 517 581 518 VBoxGuestCtrlHGCMMsgFileClose Msg;519 520 Msg.hdr.result = VERR_WRONG_ORDER; 521 Msg.hdr.u32ClientID = uClientId;522 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;523 Msg.hdr.cParms = 2;582 HGCMMsgFileClose Msg; 583 584 Msg.hdr.result = VERR_WRONG_ORDER; 585 Msg.hdr.u32ClientID = pHostCtx->uClientID; 586 Msg.hdr.u32Function = GUEST_MSG_WAIT; 587 Msg.hdr.cParms = pHostCtx->uNumParms; 524 588 525 589 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 536 600 else 537 601 { 538 Msg.context.GetUInt32( puContext);602 Msg.context.GetUInt32(&pHostCtx->uContextID); 539 603 Msg.handle.GetUInt32(puHandle); 540 604 } … … 544 608 545 609 546 VBGLR3DECL(int) VbglR3GuestCtrlFileGet HostCmdRead(uint32_t uClientId, uint32_t cParms,547 uint32_t *puContext,548 uint32_t *puHandle, uint32_t *puToRead) 549 { 550 AssertReturn(cParms == 4, VERR_INVALID_PARAMETER); 551 Assert PtrReturn(puContext, VERR_INVALID_POINTER);610 VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 611 uint32_t *puHandle, uint32_t *puToRead) 612 { 613 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 614 615 AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER); 552 616 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 553 617 AssertPtrReturn(puToRead, VERR_INVALID_POINTER); 554 618 555 VBoxGuestCtrlHGCMMsgFileRead Msg;556 557 Msg.hdr.result = VERR_WRONG_ORDER; 558 Msg.hdr.u32ClientID = uClientId;559 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;560 Msg.hdr.cParms = 4;619 HGCMMsgFileRead Msg; 620 621 Msg.hdr.result = VERR_WRONG_ORDER; 622 Msg.hdr.u32ClientID = pHostCtx->uClientID; 623 Msg.hdr.u32Function = GUEST_MSG_WAIT; 624 Msg.hdr.cParms = pHostCtx->uNumParms; 561 625 562 626 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 574 638 else 575 639 { 576 Msg.context.GetUInt32( puContext);640 Msg.context.GetUInt32(&pHostCtx->uContextID); 577 641 Msg.handle.GetUInt32(puHandle); 578 642 Msg.size.GetUInt32(puToRead); … … 582 646 } 583 647 584 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdWrite(uint32_t uClientId, uint32_t cParms, 585 uint32_t *puContext, 586 uint32_t *puHandle, 587 void *pvData, uint32_t cbData, 588 uint32_t *pcbSize) 589 { 590 AssertReturn(cParms == 4, VERR_INVALID_PARAMETER); 591 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 648 649 VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 650 uint32_t *puHandle, uint32_t *puToRead, uint64_t *puOffset) 651 { 652 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 653 654 AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER); 655 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 656 AssertPtrReturn(puToRead, VERR_INVALID_POINTER); 657 658 HGCMMsgFileRead Msg; 659 660 Msg.hdr.result = VERR_WRONG_ORDER; 661 Msg.hdr.u32ClientID = pHostCtx->uClientID; 662 Msg.hdr.u32Function = GUEST_MSG_WAIT; 663 Msg.hdr.cParms = pHostCtx->uNumParms; 664 665 VbglHGCMParmUInt32Set(&Msg.context, 0); 666 VbglHGCMParmUInt32Set(&Msg.handle, 0); 667 VbglHGCMParmUInt32Set(&Msg.size, 0); 668 669 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 670 if (RT_SUCCESS(rc)) 671 { 672 int rc2 = Msg.hdr.result; 673 if (RT_FAILURE(rc2)) 674 { 675 rc = rc2; 676 } 677 else 678 { 679 Msg.context.GetUInt32(&pHostCtx->uContextID); 680 Msg.handle.GetUInt32(puHandle); 681 Msg.size.GetUInt32(puToRead); 682 } 683 } 684 return rc; 685 } 686 687 688 VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle, 689 void *pvData, uint32_t cbData, uint32_t *pcbSize) 690 { 691 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 692 693 AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER); 592 694 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 593 695 AssertPtrReturn(pvData, VERR_INVALID_POINTER); … … 595 697 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER); 596 698 597 VBoxGuestCtrlHGCMMsgFileWrite Msg;598 599 Msg.hdr.result = VERR_WRONG_ORDER; 600 Msg.hdr.u32ClientID = uClientId;601 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;602 Msg.hdr.cParms = 4;699 HGCMMsgFileWrite Msg; 700 701 Msg.hdr.result = VERR_WRONG_ORDER; 702 Msg.hdr.u32ClientID = pHostCtx->uClientID; 703 Msg.hdr.u32Function = GUEST_MSG_WAIT; 704 Msg.hdr.cParms = pHostCtx->uNumParms; 603 705 604 706 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 617 719 else 618 720 { 619 Msg.context.GetUInt32( puContext);721 Msg.context.GetUInt32(&pHostCtx->uContextID); 620 722 Msg.handle.GetUInt32(puHandle); 621 723 Msg.size.GetUInt32(pcbSize); … … 626 728 627 729 628 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdSeek(uint32_t uClientId, uint32_t cParms, 629 uint32_t *puContext, 630 uint32_t *puHandle, 631 uint32_t *puSeekMethod, uint64_t *puOffset) 632 { 633 AssertReturn(cParms == 4, VERR_INVALID_PARAMETER); 634 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 730 VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle, 731 void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *puOffset) 732 { 733 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 734 735 AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER); 736 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 737 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 738 AssertReturn(cbData, VERR_INVALID_PARAMETER); 739 AssertPtrReturn(pcbSize, VERR_INVALID_POINTER); 740 741 HGCMMsgFileWriteAt Msg; 742 743 Msg.hdr.result = VERR_WRONG_ORDER; 744 Msg.hdr.u32ClientID = pHostCtx->uClientID; 745 Msg.hdr.u32Function = GUEST_MSG_WAIT; 746 Msg.hdr.cParms = pHostCtx->uNumParms; 747 748 VbglHGCMParmUInt32Set(&Msg.context, 0); 749 VbglHGCMParmUInt32Set(&Msg.handle, 0); 750 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData); 751 VbglHGCMParmUInt32Set(&Msg.size, 0); 752 VbglHGCMParmUInt32Set(&Msg.offset, 0); 753 754 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 755 if (RT_SUCCESS(rc)) 756 { 757 int rc2 = Msg.hdr.result; 758 if (RT_FAILURE(rc2)) 759 { 760 rc = rc2; 761 } 762 else 763 { 764 Msg.context.GetUInt32(&pHostCtx->uContextID); 765 Msg.handle.GetUInt32(puHandle); 766 Msg.size.GetUInt32(pcbSize); 767 } 768 } 769 return rc; 770 } 771 772 773 VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 774 uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *puOffset) 775 { 776 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 777 778 AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER); 635 779 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 636 780 AssertPtrReturn(puSeekMethod, VERR_INVALID_POINTER); 637 781 AssertPtrReturn(puOffset, VERR_INVALID_POINTER); 638 782 639 VBoxGuestCtrlHGCMMsgFileSeek Msg;640 641 Msg.hdr.result = VERR_WRONG_ORDER; 642 Msg.hdr.u32ClientID = uClientId;643 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;644 Msg.hdr.cParms = 4;783 HGCMMsgFileSeek Msg; 784 785 Msg.hdr.result = VERR_WRONG_ORDER; 786 Msg.hdr.u32ClientID = pHostCtx->uClientID; 787 Msg.hdr.u32Function = GUEST_MSG_WAIT; 788 Msg.hdr.cParms = pHostCtx->uNumParms; 645 789 646 790 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 659 803 else 660 804 { 661 Msg.context.GetUInt32( puContext);805 Msg.context.GetUInt32(&pHostCtx->uContextID); 662 806 Msg.handle.GetUInt32(puHandle); 663 807 Msg.method.GetUInt32(puSeekMethod); … … 669 813 670 814 671 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdTell(uint32_t uClientId, uint32_t cParms, 672 uint32_t *puContext, 673 uint32_t *puHandle) 674 { 675 AssertReturn(cParms == 2, VERR_INVALID_PARAMETER); 676 AssertPtrReturn(puContext, VERR_INVALID_POINTER); 815 VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle) 816 { 817 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 818 819 AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER); 677 820 AssertPtrReturn(puHandle, VERR_INVALID_POINTER); 678 821 679 VBoxGuestCtrlHGCMMsgFileTell Msg;680 681 Msg.hdr.result = VERR_WRONG_ORDER; 682 Msg.hdr.u32ClientID = uClientId;683 Msg.hdr.u32Function = GUEST_ GET_HOST_MSG;684 Msg.hdr.cParms = 2;822 HGCMMsgFileTell Msg; 823 824 Msg.hdr.result = VERR_WRONG_ORDER; 825 Msg.hdr.u32ClientID = pHostCtx->uClientID; 826 Msg.hdr.u32Function = GUEST_MSG_WAIT; 827 Msg.hdr.cParms = pHostCtx->uNumParms; 685 828 686 829 VbglHGCMParmUInt32Set(&Msg.context, 0); … … 697 840 else 698 841 { 699 Msg.context.GetUInt32( puContext);842 Msg.context.GetUInt32(&pHostCtx->uContextID); 700 843 Msg.handle.GetUInt32(puHandle); 701 844 } … … 705 848 706 849 707 VBGLR3DECL(int) VbglR3GuestCtrlFileNotify(uint32_t uClientId, 708 uint32_t uContext, uint32_t uHandle, 850 VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puPID) 851 { 852 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 853 854 AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER); 855 AssertPtrReturn(puPID, VERR_INVALID_POINTER); 856 857 HGCMMsgProcTerminate Msg; 858 859 Msg.hdr.result = VERR_WRONG_ORDER; 860 Msg.hdr.u32ClientID = pHostCtx->uClientID; 861 Msg.hdr.u32Function = GUEST_MSG_WAIT; 862 Msg.hdr.cParms = pHostCtx->uNumParms; 863 864 VbglHGCMParmUInt32Set(&Msg.context, 0); 865 VbglHGCMParmUInt32Set(&Msg.pid, 0); 866 867 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 868 if (RT_SUCCESS(rc)) 869 { 870 int rc2 = Msg.hdr.result; 871 if (RT_FAILURE(rc2)) 872 { 873 rc = rc2; 874 } 875 else 876 { 877 Msg.context.GetUInt32(&pHostCtx->uContextID); 878 Msg.pid.GetUInt32(puPID); 879 } 880 } 881 return rc; 882 } 883 884 885 VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS) 886 { 887 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 888 889 AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER); 890 AssertPtrReturn(puPID, VERR_INVALID_POINTER); 891 892 HGCMMsgProcWaitFor Msg; 893 894 Msg.hdr.result = VERR_WRONG_ORDER; 895 Msg.hdr.u32ClientID = pHostCtx->uClientID; 896 Msg.hdr.u32Function = GUEST_MSG_WAIT; 897 Msg.hdr.cParms = pHostCtx->uNumParms; 898 899 VbglHGCMParmUInt32Set(&Msg.context, 0); 900 VbglHGCMParmUInt32Set(&Msg.pid, 0); 901 VbglHGCMParmUInt32Set(&Msg.flags, 0); 902 VbglHGCMParmUInt32Set(&Msg.timeout, 0); 903 904 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 905 if (RT_SUCCESS(rc)) 906 { 907 int rc2 = Msg.hdr.result; 908 if (RT_FAILURE(rc2)) 909 { 910 rc = rc2; 911 } 912 else 913 { 914 Msg.context.GetUInt32(&pHostCtx->uContextID); 915 Msg.pid.GetUInt32(puPID); 916 Msg.flags.GetUInt32(puWaitFlags); 917 Msg.timeout.GetUInt32(puTimeoutMS); 918 } 919 } 920 return rc; 921 } 922 923 924 VBGLR3DECL(int) VbglR3GuestCtrlFileNotify(uint32_t uClientId, uint32_t uContext, 709 925 uint32_t uType, 710 void *pvPayload, uint32_tcbPayload)926 void *pvPayload, uint32_t cbPayload) 711 927 { 712 928 AssertPtrReturn(uContext, VERR_INVALID_POINTER); 713 AssertPtrReturn(uHandle, VERR_INVALID_POINTER);714 929 AssertPtrReturn(pvPayload, VERR_INVALID_POINTER); 715 930 AssertReturn(cbPayload, VERR_INVALID_PARAMETER); 716 931 717 VBoxGuestCtrlHGCMMsgFileNotify Msg;932 HGCMMsgFileNotify Msg; 718 933 719 934 Msg.hdr.result = VERR_WRONG_ORDER; 720 935 Msg.hdr.u32ClientID = uClientId; 721 Msg.hdr.u32Function = GUEST_FILE_NOTIFY;722 Msg.hdr.cParms = 4;936 //Msg.hdr.u32Function = GUEST_FILE_NOTIFY; 937 Msg.hdr.cParms = 3; 723 938 724 939 VbglHGCMParmUInt32Set(&Msg.context, uContext); 725 VbglHGCMParmUInt32Set(&Msg.handle, uHandle);726 940 VbglHGCMParmUInt32Set(&Msg.type, uType); 727 941 VbglHGCMParmPtrSet(&Msg.payload, pvPayload, cbPayload); … … 737 951 } 738 952 953 954 /** 955 * Callback for reporting a guest process status (along with some other stuff) to the host. 956 * 957 * @returns VBox status code. 958 ** @todo Docs! 959 */ 960 VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(uint32_t u32ClientID, 961 uint32_t u32Context, 962 uint32_t u32PID, 963 uint32_t u32Status, 964 uint32_t u32Flags, 965 void *pvData, 966 uint32_t cbData) 967 { 968 HGCMMsgProcStatus Msg; 969 970 Msg.hdr.result = VERR_WRONG_ORDER; 971 Msg.hdr.u32ClientID = u32ClientID; 972 Msg.hdr.u32Function = GUEST_EXEC_STATUS; 973 Msg.hdr.cParms = 5; 974 975 VbglHGCMParmUInt32Set(&Msg.context, u32Context); 976 VbglHGCMParmUInt32Set(&Msg.pid, u32PID); 977 VbglHGCMParmUInt32Set(&Msg.status, u32Status); 978 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); 979 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData); 980 981 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 982 if (RT_SUCCESS(rc)) 983 { 984 int rc2 = Msg.hdr.result; 985 if (RT_FAILURE(rc2)) 986 rc = rc2; 987 } 988 return rc; 989 } 990 991 992 /** 993 * Sends output (from stdout/stderr) from a running process. 994 * 995 * @returns VBox status code. 996 ** @todo Docs! 997 */ 998 VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(uint32_t u32ClientID, 999 uint32_t u32Context, 1000 uint32_t u32PID, 1001 uint32_t u32Handle, 1002 uint32_t u32Flags, 1003 void *pvData, 1004 uint32_t cbData) 1005 { 1006 HGCMMsgProcOutput Msg; 1007 1008 Msg.hdr.result = VERR_WRONG_ORDER; 1009 Msg.hdr.u32ClientID = u32ClientID; 1010 Msg.hdr.u32Function = GUEST_EXEC_OUTPUT; 1011 Msg.hdr.cParms = 5; 1012 1013 VbglHGCMParmUInt32Set(&Msg.context, u32Context); 1014 VbglHGCMParmUInt32Set(&Msg.pid, u32PID); 1015 VbglHGCMParmUInt32Set(&Msg.handle, u32Handle); 1016 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); 1017 VbglHGCMParmPtrSet(&Msg.data, pvData, cbData); 1018 1019 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 1020 if (RT_SUCCESS(rc)) 1021 { 1022 int rc2 = Msg.hdr.result; 1023 if (RT_FAILURE(rc2)) 1024 rc = rc2; 1025 } 1026 return rc; 1027 } 1028 1029 1030 /** 1031 * Callback for reporting back the input status of a guest process to the host. 1032 * 1033 * @returns VBox status code. 1034 ** @todo Docs! 1035 */ 1036 VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(uint32_t u32ClientID, 1037 uint32_t u32Context, 1038 uint32_t u32PID, 1039 uint32_t u32Status, 1040 uint32_t u32Flags, 1041 uint32_t cbWritten) 1042 { 1043 HGCMMsgProcStatusInput Msg; 1044 1045 Msg.hdr.result = VERR_WRONG_ORDER; 1046 Msg.hdr.u32ClientID = u32ClientID; 1047 Msg.hdr.u32Function = GUEST_EXEC_INPUT_STATUS; 1048 Msg.hdr.cParms = 5; 1049 1050 VbglHGCMParmUInt32Set(&Msg.context, u32Context); 1051 VbglHGCMParmUInt32Set(&Msg.pid, u32PID); 1052 VbglHGCMParmUInt32Set(&Msg.status, u32Status); 1053 VbglHGCMParmUInt32Set(&Msg.flags, u32Flags); 1054 VbglHGCMParmUInt32Set(&Msg.written, cbWritten); 1055 1056 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg)); 1057 if (RT_SUCCESS(rc)) 1058 { 1059 int rc2 = Msg.hdr.result; 1060 if (RT_FAILURE(rc2)) 1061 rc = rc2; 1062 } 1063 return rc; 1064 } 1065 -
trunk/src/VBox/Additions/common/VBoxService
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/VBox-3.0/src/VBox/Additions/common/VBoxService 58652,70973 /branches/VBox-3.2/src/VBox/Additions/common/VBoxService 66309,66318 /branches/VBox-4.0/src/VBox/Additions/common/VBoxService 70873 /branches/VBox-4.1/src/VBox/Additions/common/VBoxService 74233,78414,78691 /branches/VBox-4.2/src/VBox/Additions/common/VBoxService 82653,83625-83626,83665,83678 /branches/dsen/gui/src/VBox/Additions/common/VBoxService 79076-79078,79089,79109-79110,79112-79113,79127-79130,79134,79141,79151,79155,79157-79159,79193,79197 /branches/dsen/gui2/src/VBox/Additions/common/VBoxService 79224,79228,79233,79235,79258,79262-79263,79273,79341,79345,79354,79357,79387-79388,79559-79569,79572-79573,79578,79581-79582,79590-79591,79598-79599,79602-79603,79605-79606,79632,79635,79637,79644 /branches/dsen/gui3/src/VBox/Additions/common/VBoxService 79645-79692
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk
r43791 r44863 5 5 6 6 # 7 # Copyright (C) 2007-201 2Oracle Corporation7 # Copyright (C) 2007-2013 Oracle Corporation 8 8 # 9 9 # This file is part of VirtualBox Open Source Edition (OSE), as … … 74 74 VBoxService_SOURCES += \ 75 75 VBoxServiceControl.cpp \ 76 VBoxServiceControlThread.cpp 76 VBoxServiceControlThread.cpp \ 77 VBoxServiceControlSession.cpp 77 78 endif 78 79 -
trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp
r44528 r44863 57 57 58 58 #include "VBoxServiceInternal.h" 59 #ifdef VBOX_WITH_GUEST_CONTROL 60 # include "VBoxServiceControl.h" 61 #endif 59 62 60 63 … … 66 69 /** The current verbosity level. */ 67 70 int g_cVerbosity = 0; 71 char g_szLogFile[RTPATH_MAX + 128] = ""; 68 72 /** Logging parameters. */ 69 73 /** @todo Make this configurable later. */ … … 216 220 * @param pszLogFile Filename for log output. Optional. 217 221 */ 218 staticint VBoxServiceLogCreate(const char *pszLogFile)222 int VBoxServiceLogCreate(const char *pszLogFile) 219 223 { 220 224 /* Create release logger (stdout + file). */ … … 242 246 } 243 247 244 static void VBoxServiceLogDestroy(void) 248 249 void VBoxServiceLogDestroy(void) 245 250 { 246 251 RTLogDestroy(RTLogRelSetDefaultInstance(NULL)); … … 634 639 } 635 640 641 VBoxServiceVerbose(3, "All stop functions for services called\n"); 642 636 643 /* 637 644 * Wait for all the service threads to complete. … … 792 799 */ 793 800 if ( argc == 2 794 && ! strcmp(argv[1], "--pagefusionfork"))801 && !RTStrICmp(argv[1], "pagefusion")) 795 802 return VBoxServicePageSharingInitFork(); 796 803 #endif 797 804 798 char szLogFile[RTPATH_MAX + 128] = ""; 805 /* 806 * Check if we're the specially spawned VBoxService.exe process that 807 * handles a guest control session. 808 */ 809 if ( argc >= 2 810 && !RTStrICmp(argv[1], "guestsession")) 811 return VBoxServiceControlSessionForkInit(argc, argv); 799 812 800 813 /* … … 926 939 { 927 940 rc = VBoxServiceArgString(argc, argv, psz + 1, &i, 928 szLogFile, sizeof(szLogFile));941 g_szLogFile, sizeof(g_szLogFile)); 929 942 if (rc) 930 943 return rc; … … 961 974 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "At least one service must be enabled\n"); 962 975 963 rc = VBoxServiceLogCreate(strlen( szLogFile) ?szLogFile : NULL);976 rc = VBoxServiceLogCreate(strlen(g_szLogFile) ? g_szLogFile : NULL); 964 977 if (RT_FAILURE(rc)) 965 978 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log (%s, %Rrc)", 966 strlen( szLogFile) ?szLogFile : "<None>", rc);979 strlen(g_szLogFile) ? g_szLogFile : "<None>", rc); 967 980 968 981 /* Call pre-init if we didn't do it already. */ -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
r44248 r44863 22 22 #include <iprt/asm.h> 23 23 #include <iprt/assert.h> 24 #include <iprt/env.h> 24 25 #include <iprt/file.h> 25 26 #include <iprt/getopt.h> 26 27 #include <iprt/mem.h> 27 28 #include <iprt/path.h> 29 #include <iprt/process.h> 28 30 #include <iprt/semaphore.h> 29 31 #include <iprt/thread.h> … … 31 33 #include <VBox/HostServices/GuestControlSvc.h> 32 34 #include "VBoxServiceInternal.h" 35 #include "VBoxServiceControl.h" 33 36 #include "VBoxServiceUtils.h" 34 37 … … 42 45 /** The semaphore we're blocking our main control thread on. */ 43 46 static RTSEMEVENTMULTI g_hControlEvent = NIL_RTSEMEVENTMULTI; 47 /** The VM session ID. Changes whenever the VM is restored or reset. */ 48 static uint64_t g_idControlSession; 44 49 /** The guest control service client ID. */ 45 50 static uint32_t g_uControlSvcClientID = 0; … … 58 63 /** Critical section protecting g_GuestControlExecThreads. */ 59 64 static RTCRITSECT g_csControlThreads; 60 /** List of guest control files (VBOXSERVICECTRLFILE). 61 **@todo Use a map (later). */ 62 static RTLISTANCHOR g_lstControlFiles; 63 /** The internal file count for building our internal file handles. 64 * Should be enough for now. */ 65 static uint32_t g_uControlFileCount = 0; 66 65 /** List of guest control sessions (VBOXSERVICECTRLSESSION). */ 66 RTLISTANCHOR g_lstControlSessions; 67 67 68 68 /******************************************************************************* 69 69 * Internal Functions * 70 70 *******************************************************************************/ 71 /** @todo Shorten "VBoxServiceControl" to "gstsvcCntl". */ 72 static int gstcntlReapThreads(void); 73 static int gstcntlStartAllowed(bool *pbAllowed); 74 static int gstcntlHandleCmdStartProc(uint32_t u32ClientId, uint32_t uNumParms); 75 static int gstcntlHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms, void *pvScratchBuf, size_t cbScratchBuf); 76 static int gstcntlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms); 77 static int gstcntlHandleFileOpen(uint32_t idClient, uint32_t cParms); 78 static int gstcntlHandleFileClose(uint32_t idClient, uint32_t cParms); 79 static int gstcntlHandleFileRead(uint32_t idClient, uint32_t cParms); 80 static int gstcntlHandleFileWrite(uint32_t idClient, uint32_t cParms, void *pvScratchBuf, size_t cbScratchBuf); 81 static int gstcntlHandleFileSeek(uint32_t idClient, uint32_t cParms); 82 static int gstcntlHandleFileTell(uint32_t idClient, uint32_t cParms); 71 static int gstcntlHandleSessionOpen(PVBGLR3GUESTCTRLHOSTCTX pHostCtx); 72 static int gstcntlHandleSessionClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx); 73 static int gstcntlHandleProcExec(PVBGLR3GUESTCTRLHOSTCTX pHostCtx); 74 static int gstcntlHandleProcInput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf); 75 static int gstcntlHandleProcOutput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx); 76 static int gstcntlHandleProcTerminate(PVBGLR3GUESTCTRLHOSTCTX pHostCtx); 77 static int gstcntlHandleProcWaitFor(PVBGLR3GUESTCTRLHOSTCTX pHostCtx); 78 static int gstcntlReapThreads(void); 79 static void VBoxServiceControlShutdown(void); 80 static int vboxServiceControlProcessCloseAll(void); 81 static int gstcntlStartAllowed(bool *pbAllowed); 83 82 84 83 #ifdef DEBUG … … 137 136 else 138 137 { 139 rc = VBoxServiceReadPropUInt32(uGuestPropSvcClientID, "/VirtualBox/GuestAdd/VBoxService/--control-procs-max-kept",140 &g_uControlProcsMaxKept, 0, UINT32_MAX - 1);141 142 138 VbglR3GuestPropDisconnect(uGuestPropSvcClientID); 143 139 } … … 162 158 rc = VBoxServiceArgUInt32(argc, argv, "", pi, 163 159 &g_uControlIntervalMS, 1, UINT32_MAX - 1); 164 else if (!strcmp(argv[*pi], "--control-procs-max-kept"))165 rc = VBoxServiceArgUInt32(argc, argv, "", pi,166 &g_uControlProcsMaxKept, 0, UINT32_MAX - 1);167 160 #ifdef DEBUG 168 161 else if (!strcmp(argv[*pi], "--control-dump-stderr")) … … 194 187 AssertRCReturn(rc, rc); 195 188 189 VbglR3GetSessionId(&g_idControlSession); 190 /* The status code is ignored as this information is not available with VBox < 3.2.10. */ 191 196 192 rc = VbglR3GuestCtrlConnect(&g_uControlSvcClientID); 197 193 if (RT_SUCCESS(rc)) … … 202 198 RTListInit(&g_lstControlThreadsActive); 203 199 RTListInit(&g_lstControlThreadsInactive); 204 RTListInit(&g_lstControl Files);200 RTListInit(&g_lstControlSessions); 205 201 206 202 /* Init critical section for protecting the thread lists. */ … … 245 241 AssertPtrReturn(pvScratchBuf, VERR_NO_MEMORY); 246 242 247 /* 248 * Execution loop. 249 * 250 * @todo 251 */ 243 VBGLR3GUESTCTRLHOSTCTX ctxHost = { g_uControlSvcClientID, 244 1 /* Default protocol version */ }; 252 245 for (;;) 253 246 { … … 255 248 uint32_t uMsg = 0; 256 249 uint32_t cParms = 0; 257 rc = VbglR3GuestCtrl WaitForHostMsg(g_uControlSvcClientID, &uMsg, &cParms);250 rc = VbglR3GuestCtrlMsgWaitFor(g_uControlSvcClientID, &uMsg, &cParms); 258 251 if (rc == VERR_TOO_MUCH_DATA) 259 252 { … … 266 259 { 267 260 VBoxServiceVerbose(3, "Msg=%u (%u parms) retrieved\n", uMsg, cParms); 261 262 /* Set number of parameters for current host context. */ 263 ctxHost.uNumParms = cParms; 264 265 /* Check for VM session change. */ 266 uint64_t idNewSession = g_idControlSession; 267 int rc2 = VbglR3GetSessionId(&idNewSession); 268 if ( RT_SUCCESS(rc2) 269 && (idNewSession != g_idControlSession)) 270 { 271 VBoxServiceVerbose(1, "The VM session ID changed\n"); 272 g_idControlSession = idNewSession; 273 274 /* Close all opened guest sessions -- all context IDs, sessions etc. 275 * are now invalid. */ 276 rc2 = vboxServiceControlProcessCloseAll(); 277 AssertRC(rc2); 278 } 279 268 280 switch (uMsg) 269 281 { 270 282 case HOST_CANCEL_PENDING_WAITS: 271 VBoxServiceVerbose( 3, "Host asked usto quit ...\n");283 VBoxServiceVerbose(1, "We were asked to quit ...\n"); 272 284 break; 273 285 286 case HOST_SESSION_CREATE: 287 rc = gstcntlHandleSessionOpen(&ctxHost); 288 break; 289 290 case HOST_SESSION_CLOSE: 291 rc = gstcntlHandleSessionClose(&ctxHost); 292 break; 293 274 294 case HOST_EXEC_CMD: 275 rc = gstcntlHandle CmdStartProc(g_uControlSvcClientID, cParms);295 rc = gstcntlHandleProcExec(&ctxHost); 276 296 break; 277 297 278 298 case HOST_EXEC_SET_INPUT: 279 rc = gstcntlHandle CmdSetInput(g_uControlSvcClientID, cParms,280 299 rc = gstcntlHandleProcInput(&ctxHost, 300 pvScratchBuf, cbScratchBuf); 281 301 break; 282 302 283 303 case HOST_EXEC_GET_OUTPUT: 284 rc = gstcntlHandle CmdGetOutput(g_uControlSvcClientID, cParms);304 rc = gstcntlHandleProcOutput(&ctxHost); 285 305 break; 286 306 287 case HOST_FILE_OPEN:288 rc = gstcntlHandle FileOpen(g_uControlSvcClientID, cParms);307 case HOST_EXEC_TERMINATE: 308 rc = gstcntlHandleProcTerminate(&ctxHost); 289 309 break; 290 310 291 case HOST_FILE_CLOSE: 292 rc = gstcntlHandleFileClose(g_uControlSvcClientID, cParms); 293 break; 294 295 case HOST_FILE_READ: 296 rc = gstcntlHandleFileRead(g_uControlSvcClientID, cParms); 297 break; 298 299 case HOST_FILE_WRITE: 300 rc = gstcntlHandleFileWrite(g_uControlSvcClientID, cParms, 301 pvScratchBuf, cbScratchBuf); 302 break; 303 304 case HOST_FILE_SEEK: 305 rc = gstcntlHandleFileSeek(g_uControlSvcClientID, cParms); 306 break; 307 308 case HOST_FILE_TELL: 309 rc = gstcntlHandleFileTell(g_uControlSvcClientID, cParms); 311 case HOST_EXEC_WAIT_FOR: 312 rc = gstcntlHandleProcWaitFor(&ctxHost); 310 313 break; 311 314 … … 321 324 || (RT_SUCCESS(rc) && uMsg == HOST_CANCEL_PENDING_WAITS)) 322 325 { 323 rc = VINF_SUCCESS;324 326 break; 325 327 } … … 328 330 RTThreadYield(); 329 331 } 332 333 VBoxServiceVerbose(0, "Guest control service stopped\n"); 330 334 331 335 /* Delete scratch buffer. */ … … 333 337 RTMemFree(pvScratchBuf); 334 338 339 VBoxServiceVerbose(0, "Guest control worker returned with rc=%Rrc\n", rc); 335 340 return rc; 336 341 } … … 344 349 * @param cParms The number of parameters the host is offering. 345 350 */ 346 static int gstcntlHandle CmdStartProc(uint32_t uClientID, uint32_t cParms)347 { 348 uint32_t uContextID = 0;351 static int gstcntlHandleProcExec(PVBGLR3GUESTCTRLHOSTCTX pHostCtx) 352 { 353 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 349 354 350 355 int rc; 351 356 bool fStartAllowed = false; /* Flag indicating whether starting a process is allowed or not. */ 352 if (cParms == 11) 353 { 354 VBOXSERVICECTRLPROCESS proc; 357 358 if ( (pHostCtx->uProtocol < 2 && pHostCtx->uNumParms == 11) 359 || (pHostCtx->uProtocol >= 2 && pHostCtx->uNumParms == 12) 360 ) 361 { 362 VBOXSERVICECTRLPROCSTARTUPINFO proc; 355 363 RT_ZERO(proc); 356 364 … … 360 368 proc.cbEnv = sizeof(proc.szEnv); 361 369 362 rc = VbglR3GuestCtrlExecGetHostCmdExec(uClientID, 363 cParms, 364 &uContextID, 365 /* Command */ 366 proc.szCmd, sizeof(proc.szCmd), 367 /* Flags */ 368 &proc.uFlags, 369 /* Arguments */ 370 proc.szArgs, sizeof(proc.szArgs), &proc.uNumArgs, 371 /* Environment */ 372 proc.szEnv, &proc.cbEnv, &proc.uNumEnvVars, 373 /* Credentials */ 374 proc.szUser, sizeof(proc.szUser), 375 proc.szPassword, sizeof(proc.szPassword), 376 /* Timelimit */ 377 &proc.uTimeLimitMS); 378 if (RT_SUCCESS(rc)) 379 { 380 VBoxServiceVerbose(3, "Request to start process szCmd=%s, uFlags=0x%x, szArgs=%s, szEnv=%s, szUser=%s, szPassword=%s, uTimeout=%u\n", 370 rc = VbglR3GuestCtrlProcGetStart(pHostCtx, 371 /* Command */ 372 proc.szCmd, sizeof(proc.szCmd), 373 /* Flags */ 374 &proc.uFlags, 375 /* Arguments */ 376 proc.szArgs, sizeof(proc.szArgs), &proc.uNumArgs, 377 /* Environment */ 378 proc.szEnv, &proc.cbEnv, &proc.uNumEnvVars, 379 /* Credentials; for hosts with VBox < 4.3. */ 380 proc.szUser, sizeof(proc.szUser), 381 proc.szPassword, sizeof(proc.szPassword), 382 /* Timelimit */ 383 &proc.uTimeLimitMS, 384 /* Process priority */ 385 &proc.uPriority, 386 /* Process affinity */ 387 proc.uAffinity, sizeof(proc.uAffinity), &proc.uNumAffinity); 388 if (RT_SUCCESS(rc)) 389 { 390 VBoxServiceVerbose(3, "Request to start process szCmd=%s, uFlags=0x%x, szArgs=%s, szEnv=%s, szUser=%s, szPassword=%s, uTimeout=%RU32\n", 381 391 proc.szCmd, proc.uFlags, 382 392 proc.uNumArgs ? proc.szArgs : "<None>", … … 400 410 if (fStartAllowed) 401 411 { 402 rc = GstCntlProcessStart( uContextID, &proc);412 rc = GstCntlProcessStart(pHostCtx->uContextID, &proc); 403 413 } 404 414 else … … 408 418 } 409 419 else 410 rc = VERR_ INVALID_PARAMETER; /* Incorrectnumber of parameters. */420 rc = VERR_NOT_SUPPORTED; /* Unsupported number of parameters. */ 411 421 412 422 /* In case of an error we need to notify the host to not wait forever for our response. */ … … 419 429 * from the host. The host in case has to deal with that! 420 430 */ 421 int rc2 = VbglR3GuestCtrlExecReportStatus(uClientID, uContextID /* Might be 0 */, 0 /* PID, invalid */, 422 PROC_STS_ERROR, rc, 423 NULL /* pvData */, 0 /* cbData */); 431 int rc2 = VbglR3GuestCtrlProcCbStatus(pHostCtx->uClientID, pHostCtx->uContextID, 432 0 /* PID, invalid */, 433 PROC_STS_ERROR, rc, 434 NULL /* pvData */, 0 /* cbData */); 424 435 if (RT_FAILURE(rc2)) 425 436 { … … 427 438 if (RT_SUCCESS(rc)) 428 439 rc = rc2; 440 } 441 } 442 443 return rc; 444 } 445 446 447 static int gstcntlHandleProcTerminate(PVBGLR3GUESTCTRLHOSTCTX pHostCtx) 448 { 449 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 450 451 uint32_t uPID; 452 int rc = VbglR3GuestCtrlProcGetTerminate(pHostCtx, &uPID); 453 if (RT_SUCCESS(rc)) 454 { 455 PVBOXSERVICECTRLREQUEST pRequest; 456 rc = GstCntlProcessRequestAllocEx(&pRequest, VBOXSERVICECTRLREQUEST_PROC_TERM, 457 NULL /* pvBuf */, NULL /* cbBuf */, pHostCtx->uContextID); 458 if (RT_SUCCESS(rc)) 459 { 460 rc = GstCntlProcessPerform(uPID, pRequest); 461 GstCntlProcessRequestFree(pRequest); 462 } 463 } 464 465 return rc; 466 } 467 468 469 static int gstcntlHandleProcWaitFor(PVBGLR3GUESTCTRLHOSTCTX pHostCtx) 470 { 471 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 472 473 uint32_t uPID; 474 uint32_t uWaitFlags; uint32_t uTimeoutMS; 475 476 int rc = VbglR3GuestCtrlProcGetWaitFor(pHostCtx, &uPID, &uWaitFlags, &uTimeoutMS); 477 if (RT_SUCCESS(rc)) 478 { 479 PVBOXSERVICECTRLREQUEST pRequest; 480 VBOXSERVICECTRLREQDATA_WAIT_FOR reqData = { uWaitFlags, uTimeoutMS }; 481 rc = GstCntlProcessRequestAllocEx(&pRequest, VBOXSERVICECTRLREQUEST_WAIT_FOR, 482 &reqData, sizeof(reqData), pHostCtx->uContextID); 483 if (RT_SUCCESS(rc)) 484 { 485 rc = GstCntlProcessPerform(uPID, pRequest); 486 GstCntlProcessRequestFree(pRequest); 429 487 } 430 488 } … … 439 497 * @return IPRT status code. 440 498 * @param uPID PID of process to retrieve the output from. 499 * @param uCID Context ID. 441 500 * @param uHandleId Stream ID (stdout = 0, stderr = 2) to get the output from. 442 501 * @param cMsTimeout Timeout (in ms) to wait for output becoming … … 459 518 { 460 519 case OUTPUT_HANDLE_ID_STDERR: 461 reqType = VBOXSERVICECTRLREQUEST_ STDERR_READ;520 reqType = VBOXSERVICECTRLREQUEST_PROC_STDERR; 462 521 break; 463 522 464 523 case OUTPUT_HANDLE_ID_STDOUT: 465 524 case OUTPUT_HANDLE_ID_STDOUT_DEPRECATED: 466 reqType = VBOXSERVICECTRLREQUEST_ STDOUT_READ;525 reqType = VBOXSERVICECTRLREQUEST_PROC_STDOUT; 467 526 break; 468 527 … … 505 564 if (RT_SUCCESS(rc)) 506 565 { 507 VBoxServiceVerbose(3, "Setting thread (PID % u) to list %d\n",566 VBoxServiceVerbose(3, "Setting thread (PID %RU32) to list %d\n", 508 567 pThread->uPID, enmList); 509 568 … … 572 631 int rc = GstCntlProcessRequestAllocEx(&pRequest, 573 632 fPendingClose 574 ? VBOXSERVICECTRLREQUEST_ STDIN_WRITE_EOF575 : VBOXSERVICECTRLREQUEST_ STDIN_WRITE,633 ? VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF 634 : VBOXSERVICECTRLREQUEST_PROC_STDIN, 576 635 pvBuf, cbBuf, uCID); 577 636 if (RT_SUCCESS(rc)) … … 596 655 * 597 656 * @returns IPRT status code. 598 * @param idClient The HGCM client session ID.599 * @param cParms The number of parameters the host is600 * offering.601 657 * @param pvScratchBuf The scratch buffer. 602 658 * @param cbScratchBuf The scratch buffer size for retrieving the input data. 603 659 */ 604 static int gstcntlHandleCmdSetInput(uint32_t idClient, uint32_t cParms, 605 void *pvScratchBuf, size_t cbScratchBuf) 606 { 660 static int gstcntlHandleProcInput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, 661 void *pvScratchBuf, size_t cbScratchBuf) 662 { 663 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 607 664 AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER); 608 665 AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER); 609 666 610 uint32_t uContextID;611 667 uint32_t uPID; 612 668 uint32_t uFlags; … … 619 675 * Ask the host for the input data. 620 676 */ 621 int rc = VbglR3GuestCtrlExecGetHostCmdInput(idClient, cParms, 622 &uContextID, &uPID, &uFlags, 623 pvScratchBuf, cbScratchBuf, &cbSize); 677 int rc = VbglR3GuestCtrlProcGetInput(pHostCtx, &uPID, &uFlags, 678 pvScratchBuf, cbScratchBuf, &cbSize); 624 679 if (RT_FAILURE(rc)) 625 680 { 626 VBoxServiceError("[PID % u]: Failed to retrieve exec input command! Error: %Rrc\n",681 VBoxServiceError("[PID %RU32]: Failed to retrieve exec input command! Error: %Rrc\n", 627 682 uPID, rc); 628 683 } 629 684 else if (cbSize > cbScratchBuf) 630 685 { 631 VBoxServiceError("[PID % u]: Too much input received! cbSize=%u, cbScratchBuf=%u\n",686 VBoxServiceError("[PID %RU32]: Too much input received! cbSize=%u, cbScratchBuf=%u\n", 632 687 uPID, cbSize, cbScratchBuf); 633 688 rc = VERR_INVALID_PARAMETER; … … 642 697 { 643 698 fPendingClose = true; 644 VBoxServiceVerbose(4, "[PID % u]: Got last input block of size %u ...\n",699 VBoxServiceVerbose(4, "[PID %RU32]: Got last input block of size %u ...\n", 645 700 uPID, cbSize); 646 701 } 647 702 648 rc = VBoxServiceControlSetInput(uPID, uContextID, fPendingClose, pvScratchBuf,703 rc = VBoxServiceControlSetInput(uPID, pHostCtx->uContextID, fPendingClose, pvScratchBuf, 649 704 cbSize, &cbWritten); 650 VBoxServiceVerbose(4, "[PID % u]: Written input, CID=%u, rc=%Rrc, uFlags=0x%x, fPendingClose=%d, cbSize=%u, cbWritten=%u\n",651 uPID, uContextID, rc, uFlags, fPendingClose, cbSize, cbWritten);705 VBoxServiceVerbose(4, "[PID %RU32]: Written input, CID=%u, rc=%Rrc, uFlags=0x%x, fPendingClose=%d, cbSize=%u, cbWritten=%u\n", 706 uPID, pHostCtx->uContextID, rc, uFlags, fPendingClose, cbSize, cbWritten); 652 707 if (RT_SUCCESS(rc)) 653 708 { … … 676 731 Assert(uStatus > INPUT_STS_UNDEFINED); 677 732 678 VBoxServiceVerbose(3, "[PID % u]: Input processed, CID=%u, uStatus=%u, uFlags=0x%x, cbWritten=%u\n",679 uPID, uContextID, uStatus, uFlags, cbWritten);733 VBoxServiceVerbose(3, "[PID %RU32]: Input processed, CID=%u, uStatus=%u, uFlags=0x%x, cbWritten=%u\n", 734 uPID, pHostCtx->uContextID, uStatus, uFlags, cbWritten); 680 735 681 736 /* Note: Since the context ID is unique the request *has* to be completed here, 682 737 * regardless whether we got data or not! Otherwise the progress object 683 738 * on the host never will get completed! */ 684 rc = VbglR3GuestCtrl ExecReportStatusIn(idClient,uContextID, uPID,685 739 rc = VbglR3GuestCtrlProcCbStatusInput(pHostCtx->uClientID, pHostCtx->uContextID, uPID, 740 uStatus, uFlags, (uint32_t)cbWritten); 686 741 687 742 if (RT_FAILURE(rc)) 688 VBoxServiceError("[PID % u]: Failed to report input status! Error: %Rrc\n",743 VBoxServiceError("[PID %RU32]: Failed to report input status! Error: %Rrc\n", 689 744 uPID, rc); 690 return rc;691 }692 693 694 static PVBOXSERVICECTRLFILE gstcntlGetFile(uint32_t uHandle)695 {696 PVBOXSERVICECTRLFILE pFileCur = NULL;697 /** @todo Use a map later! */698 RTListForEach(&g_lstControlFiles, pFileCur, VBOXSERVICECTRLFILE, Node)699 {700 if (pFileCur->uHandle == uHandle)701 return pFileCur;702 }703 704 return NULL;705 }706 707 708 static int gstcntlHandleFileOpen(uint32_t idClient, uint32_t cParms)709 {710 uint32_t uContextID;711 712 char szFile[RTPATH_MAX];713 char szOpenMode[64];714 char szDisposition[64];715 uint32_t uCreationMode;716 uint64_t uOffset;717 718 int rc = VbglR3GuestCtrlFileGetHostCmdOpen(idClient, cParms, &uContextID,719 /* File to open. */720 szFile, sizeof(szFile),721 /* Open mode. */722 szOpenMode, sizeof(szOpenMode),723 /* Disposition. */724 szDisposition, sizeof(szDisposition),725 /* Creation mode. */726 &uCreationMode,727 /* Offset. */728 &uOffset);729 if (RT_SUCCESS(rc))730 {731 PVBOXSERVICECTRLFILE pFile = (PVBOXSERVICECTRLFILE)RTMemAlloc(sizeof(VBOXSERVICECTRLFILE));732 if (!pFile)733 return VERR_NO_MEMORY;734 735 if (!RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile))736 rc = VERR_BUFFER_UNDERFLOW;737 738 if (RT_SUCCESS(rc))739 {740 uint64_t fFlags = RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE; /** @todo Modes! */741 rc = RTFileOpen(&pFile->hFile, pFile->szName, fFlags);742 if ( RT_SUCCESS(rc)743 && uOffset)744 {745 /* Seeking is optional. */746 int rc2 = RTFileSeek(pFile->hFile, (int64_t)uOffset, RTFILE_SEEK_BEGIN, NULL /* Current offset */);747 if (RT_FAILURE(rc2))748 VBoxServiceVerbose(3, "[File %s]: Seeking to offset %RU64 failed; rc=%Rrc\n",749 pFile->szName, uOffset, rc);750 }751 else752 VBoxServiceVerbose(3, "[File %s]: Opening failed; rc=%Rrc\n",753 pFile->szName, rc);754 }755 756 uint32_t uHandle = 0;757 if (RT_SUCCESS(rc))758 {759 VBoxServiceVerbose(3, "[File %s]: Opened.\n", pFile->szName);760 761 uHandle = g_uControlFileCount++;762 pFile->uHandle = uHandle;763 /* rc = */ RTListAppend(&g_lstControlFiles, &pFile->Node);764 }765 766 if (RT_FAILURE(rc))767 RTMemFree(pFile);768 769 /* Report back in any case. */770 int rc2 = VbglR3GuestCtrlFileNotify(idClient, uContextID, uHandle,771 GUESTFILENOTIFYTYPE_OPEN, &rc, sizeof(rc));772 if (RT_FAILURE(rc2))773 VBoxServiceError("[File %s]: Failed to report open status, rc=%Rrc\n",774 szFile, rc2);775 if (RT_SUCCESS(rc))776 rc = rc2;777 }778 return rc;779 }780 781 782 static int gstcntlHandleFileClose(uint32_t idClient, uint32_t cParms)783 {784 uint32_t uContextID;785 uint32_t uHandle;786 787 int rc = VbglR3GuestCtrlFileGetHostCmdClose(idClient, cParms, &uContextID,788 /* File handle to close. */789 &uHandle);790 if (RT_SUCCESS(rc))791 {792 PVBOXSERVICECTRLFILE pFile = gstcntlGetFile(uHandle);793 if (pFile)794 {795 rc = RTFileClose(pFile->hFile);796 }797 else798 rc = VERR_NOT_FOUND;799 800 /* Report back in any case. */801 int rc2 = VbglR3GuestCtrlFileNotify(idClient, uContextID, uHandle,802 GUESTFILENOTIFYTYPE_CLOSE, &rc, sizeof(rc));803 if (RT_FAILURE(rc2))804 VBoxServiceError("Failed to report close status, rc=%Rrc\n", rc2);805 if (RT_SUCCESS(rc))806 rc = rc2;807 }808 return rc;809 }810 811 812 static int gstcntlHandleFileRead(uint32_t idClient, uint32_t cParms)813 {814 uint32_t uContextID;815 uint32_t uHandle;816 uint32_t cbToRead;817 818 int rc = VbglR3GuestCtrlFileGetHostCmdRead(idClient, cParms, &uContextID,819 &uHandle, &cbToRead);820 if (RT_SUCCESS(rc))821 {822 823 }824 return rc;825 }826 827 828 static int gstcntlHandleFileWrite(uint32_t idClient, uint32_t cParms,829 void *pvScratchBuf, size_t cbScratchBuf)830 {831 AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);832 AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);833 834 uint32_t uContextID;835 uint32_t uHandle;836 uint32_t cbToWrite;837 838 int rc = VbglR3GuestCtrlFileGetHostCmdWrite(idClient, cParms, &uContextID,839 &uHandle, pvScratchBuf, cbScratchBuf,840 &cbToWrite);841 if (RT_SUCCESS(rc))842 {843 844 }845 return rc;846 }847 848 849 static int gstcntlHandleFileSeek(uint32_t idClient, uint32_t cParms)850 {851 uint32_t uContextID;852 uint32_t uHandle;853 uint32_t uSeekMethod;854 uint64_t uOffset; /* Will be converted to int64_t. */855 856 int rc = VbglR3GuestCtrlFileGetHostCmdSeek(idClient, cParms, &uContextID,857 &uHandle, &uSeekMethod, &uOffset);858 if (RT_SUCCESS(rc))859 {860 861 }862 return rc;863 }864 865 866 static int gstcntlHandleFileTell(uint32_t idClient, uint32_t cParms)867 {868 uint32_t uContextID;869 uint32_t uHandle;870 871 int rc = VbglR3GuestCtrlFileGetHostCmdTell(idClient, cParms, &uContextID,872 &uHandle);873 if (RT_SUCCESS(rc))874 {875 876 }877 745 return rc; 878 746 } … … 883 751 * 884 752 * @return IPRT status code. 885 * @param idClient The HGCM client session ID. 886 * @param cParms The number of parameters the host is offering. 887 */ 888 static int gstcntlHandleCmdGetOutput(uint32_t idClient, uint32_t cParms) 889 { 890 uint32_t uContextID; 753 */ 754 static int gstcntlHandleProcOutput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx) 755 { 756 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 757 891 758 uint32_t uPID; 892 759 uint32_t uHandleID; 893 760 uint32_t uFlags; 894 761 895 int rc = VbglR3GuestCtrlExecGetHostCmdOutput(idClient, cParms, 896 &uContextID, &uPID, &uHandleID, &uFlags); 762 int rc = VbglR3GuestCtrlProcGetOutput(pHostCtx, &uPID, &uHandleID, &uFlags); 897 763 if (RT_SUCCESS(rc)) 898 764 { … … 901 767 { 902 768 uint32_t cbRead = 0; 903 rc = VBoxServiceControlExecGetOutput(uPID, uContextID, uHandleID, RT_INDEFINITE_WAIT /* Timeout */,769 rc = VBoxServiceControlExecGetOutput(uPID, pHostCtx->uContextID, uHandleID, RT_INDEFINITE_WAIT /* Timeout */, 904 770 pBuf, _64K /* cbSize */, &cbRead); 905 VBoxServiceVerbose(3, "[PID % u]: Got output, rc=%Rrc, CID=%u, cbRead=%u, uHandle=%u, uFlags=%u\n",906 uPID, rc, uContextID, cbRead, uHandleID, uFlags);771 VBoxServiceVerbose(3, "[PID %RU32]: Got output, rc=%Rrc, CID=%u, cbRead=%u, uHandle=%u, uFlags=%u\n", 772 uPID, rc, pHostCtx->uContextID, cbRead, uHandleID, uFlags); 907 773 908 774 #ifdef DEBUG … … 934 800 * regardless whether we got data or not! Otherwise the progress object 935 801 * on the host never will get completed! */ 936 int rc2 = VbglR3GuestCtrl ExecSendOut(idClient,uContextID, uPID, uHandleID, uFlags,937 pBuf, cbRead);802 int rc2 = VbglR3GuestCtrlProcCbOutput(pHostCtx->uClientID, pHostCtx->uContextID, uPID, uHandleID, uFlags, 803 pBuf, cbRead); 938 804 if (RT_SUCCESS(rc)) 939 805 rc = rc2; … … 948 814 949 815 if (RT_FAILURE(rc)) 950 VBoxServiceError("[PID % u]: Error handling output command! Error: %Rrc\n",816 VBoxServiceError("[PID %RU32]: Error handling output command! Error: %Rrc\n", 951 817 uPID, rc); 818 return rc; 819 } 820 821 822 static int gstcntlHandleSessionOpen(PVBGLR3GUESTCTRLHOSTCTX pHostCtx) 823 { 824 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 825 826 VBOXSERVICECTRLSESSIONSTARTUPINFO ssInfo = { 0 }; 827 int rc = VbglR3GuestCtrlSessionGetOpen(pHostCtx, 828 &ssInfo.uProtocol, 829 ssInfo.szUser, sizeof(ssInfo.szUser), 830 ssInfo.szPassword, sizeof(ssInfo.szPassword), 831 ssInfo.szDomain, sizeof(ssInfo.szDomain), 832 &ssInfo.uFlags, &ssInfo.uSessionID); 833 if (RT_SUCCESS(rc)) 834 { 835 /* The session open call has the protocol version the host 836 * wants to use. Store it in the host context for later calls. */ 837 pHostCtx->uProtocol = ssInfo.uProtocol; 838 839 rc = GstCntlSessionOpen(&ssInfo, NULL /* Node */); 840 } 841 842 /* Report back session opening status in any case. */ 843 int rc2 = VbglR3GuestCtrlSessionNotify(pHostCtx->uClientID, pHostCtx->uContextID, 844 GUEST_SESSION_NOTIFYTYPE_OPEN, rc /* uint32_t vs. int */); 845 if (RT_FAILURE(rc2)) 846 { 847 VBoxServiceError("Reporting session opening status failed with rc=%Rrc\n", rc2); 848 if (RT_SUCCESS(rc)) 849 rc = rc2; 850 } 851 852 VBoxServiceVerbose(3, "Opening a new guest session returned rc=%Rrc\n", rc); 853 return rc; 854 } 855 856 857 static int gstcntlHandleSessionClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx) 858 { 859 AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER); 860 861 uint32_t uSessionID, uFlags; 862 863 int rc = VbglR3GuestCtrlSessionGetClose(pHostCtx, &uFlags, &uSessionID); 864 if (RT_SUCCESS(rc)) 865 { 866 rc = VERR_NOT_FOUND; 867 868 PVBOXSERVICECTRLSESSION pSession; 869 RTListForEach(&g_lstControlSessions, pSession, VBOXSERVICECTRLSESSION, Node) 870 { 871 if (pSession->StartupInfo.uSessionID == uSessionID) 872 { 873 rc = GstCntlSessionClose(pSession, uFlags); 874 break; 875 } 876 } 877 } 878 879 /* Report back session closing status in any case. */ 880 int rc2 = VbglR3GuestCtrlSessionNotify(pHostCtx->uClientID, pHostCtx->uContextID, 881 GUEST_SESSION_NOTIFYTYPE_CLOSE, rc /* uint32_t vs. int */); 882 if (RT_FAILURE(rc2)) 883 { 884 VBoxServiceError("Reporting session closing status failed with rc=%Rrc\n", rc2); 885 if (RT_SUCCESS(rc)) 886 rc = rc2; 887 } 888 889 VBoxServiceVerbose(2, "Closing guest session %RU32 returned rc=%Rrc\n", 890 uSessionID, rc); 952 891 return rc; 953 892 } … … 1030 969 1031 970 1032 /** 1033 * Destroys all guest process threads which are still active. 1034 */ 1035 static void VBoxServiceControlShutdown(void) 1036 { 1037 VBoxServiceVerbose(2, "Shutting down ...\n"); 971 static int vboxServiceControlProcessClose() 972 { 973 /** Note: This will be a guest tsession task later. */ 1038 974 1039 975 /* Signal all threads in the active list that we want to shutdown. */ … … 1053 989 NULL /* rc */); 1054 990 if (RT_FAILURE(rc2)) 991 { 1055 992 VBoxServiceError("Guest process thread failed to stop; rc=%Rrc\n", rc2); 993 /* Keep going. */ 994 } 1056 995 1057 996 if (fLast) … … 1061 1000 } 1062 1001 1063 int rc 2= gstcntlReapThreads();1064 if (RT_FAILURE(rc 2))1065 VBoxServiceError("Reaping inactive threads failed with rc=%Rrc\n", rc 2);1002 int rc = gstcntlReapThreads(); 1003 if (RT_FAILURE(rc)) 1004 VBoxServiceError("Reaping inactive threads failed with rc=%Rrc\n", rc); 1066 1005 1067 1006 AssertMsg(RTListIsEmpty(&g_lstControlThreadsActive), … … 1070 1009 ("Guest process inactive thread list still contains entries when it should not\n")); 1071 1010 1011 return rc; 1012 } 1013 1014 1015 static int vboxServiceControlProcessCloseAll(void) 1016 { 1017 return vboxServiceControlProcessClose(); 1018 } 1019 1020 1021 /** 1022 * Destroys all guest process threads which are still active. 1023 */ 1024 static void VBoxServiceControlShutdown(void) 1025 { 1026 VBoxServiceVerbose(2, "Shutting down ...\n"); 1027 1028 int rc2 = vboxServiceControlProcessCloseAll(); 1029 AssertRC(rc2); 1030 1072 1031 /* Destroy critical section. */ 1073 1032 RTCritSectDelete(&g_csControlThreads); 1074 1075 /* Close all left guest files. */1076 PVBOXSERVICECTRLFILE pFile;1077 pFile = RTListGetFirst(&g_lstControlFiles, VBOXSERVICECTRLFILE, Node);1078 while (pFile)1079 {1080 PVBOXSERVICECTRLFILE pNext = RTListNodeGetNext(&pFile->Node, VBOXSERVICECTRLFILE, Node);1081 bool fLast = RTListNodeIsLast(&g_lstControlFiles, &pFile->Node);1082 1083 rc2 = RTFileClose(pFile->hFile);1084 if (RT_FAILURE(rc2))1085 {1086 VBoxServiceError("Unable to close file \"%s\"; rc=%Rrc\n",1087 pFile->szName, rc2);1088 /* Keep going. */1089 }1090 1091 RTListNodeRemove(&pFile->Node);1092 1093 if (fLast)1094 break;1095 1096 pFile = pNext;1097 }1098 1099 AssertMsg(RTListIsEmpty(&g_lstControlFiles),1100 ("Guest file list still contains entries when it should not\n"));1101 1033 1102 1034 VBoxServiceVerbose(2, "Shutting down complete\n"); … … 1251 1183 uint32_t uTriedPID = uPID; 1252 1184 uPID += 391939; 1253 VBoxServiceVerbose(2, "PID % uwas used before, trying again with %u ...\n",1185 VBoxServiceVerbose(2, "PID %RU32 was used before, trying again with %u ...\n", 1254 1186 uTriedPID, uPID); 1255 1187 fTryAgain = true; … … 1283 1215 " [--control-dump-stderr] [--control-dump-stdout]\n" 1284 1216 #endif 1285 " [--control-interval <ms>] [--control-procs-max-kept <x>]\n"1217 " [--control-interval <ms>]\n" 1286 1218 " [--control-procs-mem-std[in|out|err] <KB>]" 1287 1219 , … … 1295 1227 " --control-interval Specifies the interval at which to check for\n" 1296 1228 " new control commands. The default is 1000 ms.\n" 1297 " --control-procs-max-kept\n"1298 " Specifies how many started guest processes are\n"1299 " kept into memory to work with. Default is 256.\n"1300 1229 , 1301 1230 /* methods */ -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp
r44248 r44863 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxServiceControl ExecThread - Thread for every started guest process.3 * VBoxServiceControlThread - Guest process handling. 4 4 */ 5 5 … … 39 39 40 40 #include "VBoxServiceInternal.h" 41 #include "VBoxServiceControl.h" 41 42 42 43 using namespace guestControl; … … 423 424 424 425 426 /** 427 * Signals the given request. 428 * 429 * @return IPRT status code. 430 * @param pRequest Pointer to request to signal. 431 * @param rc rc to set request result to. 432 */ 433 static int gstcntlProcessSignalRequest(PVBOXSERVICECTRLREQUEST pRequest, int rc) 434 { 435 AssertPtrReturn(pRequest, VERR_INVALID_POINTER); 436 437 /* Assign overall result. */ 438 pRequest->rc = rc; 439 440 #ifdef _DEBUG 441 VBoxServiceVerbose(4, "Handled req=%u, CID=%u, rc=%Rrc, cbData=%u, pvData=%p\n", 442 pRequest->enmType, pRequest->uCID, pRequest->rc, 443 pRequest->cbData, pRequest->pvData); 444 #endif 445 446 /* In any case, regardless of the result, we notify 447 * the main guest control to unblock it. */ 448 int rc2 = RTSemEventMultiSignal(pRequest->Event); 449 AssertRC(rc2); 450 451 return rc2; 452 } 453 454 425 455 static int gstcntlProcessHandleRequest(RTPOLLSET hPollSet, uint32_t fPollEvt, 426 456 PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR, 427 PVBOXSERVICECTRLTHREAD pThread) 428 { 429 AssertPtrReturn(pThread, VERR_INVALID_POINTER); 457 PVBOXSERVICECTRLTHREAD pThread, PVBOXSERVICECTRLREQUEST pRequest) 458 { 430 459 AssertPtrReturn(phStdInW, VERR_INVALID_POINTER); 431 460 AssertPtrReturn(phStdOutR, VERR_INVALID_POINTER); 432 461 AssertPtrReturn(phStdErrR, VERR_INVALID_POINTER); 462 AssertPtrReturn(pThread, VERR_INVALID_POINTER); 463 AssertPtrReturn(pRequest, VERR_INVALID_POINTER); 433 464 434 465 /* Drain the notification pipe. */ … … 439 470 VBoxServiceError("Draining IPC notification pipe failed with rc=%Rrc\n", rc); 440 471 472 bool fDefer = false; /* Whether the request completion should be deferred or not. */ 441 473 int rcReq = VINF_SUCCESS; /* Actual request result. */ 442 443 PVBOXSERVICECTRLREQUEST pRequest = pThread->pRequest;444 if (!pRequest)445 {446 VBoxServiceError("IPC request is invalid\n");447 return VERR_INVALID_POINTER;448 }449 474 450 475 switch (pRequest->enmType) … … 459 484 } 460 485 461 case VBOXSERVICECTRLREQUEST_ STDIN_WRITE:462 case VBOXSERVICECTRLREQUEST_ STDIN_WRITE_EOF:486 case VBOXSERVICECTRLREQUEST_PROC_STDIN: 487 case VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF: 463 488 { 464 489 size_t cbWritten = 0; … … 480 505 * the poll set. 481 506 */ 482 if ( pRequest->enmType == VBOXSERVICECTRLREQUEST_ STDIN_WRITE_EOF507 if ( pRequest->enmType == VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF 483 508 && pRequest->cbData == cbWritten) 484 509 { … … 491 516 } 492 517 493 case VBOXSERVICECTRLREQUEST_ STDOUT_READ:494 case VBOXSERVICECTRLREQUEST_ STDERR_READ:518 case VBOXSERVICECTRLREQUEST_PROC_STDOUT: 519 case VBOXSERVICECTRLREQUEST_PROC_STDERR: 495 520 { 496 521 AssertPtrReturn(pRequest->pvData, VERR_INVALID_POINTER); 497 522 AssertReturn(pRequest->cbData, VERR_INVALID_PARAMETER); 498 523 499 PRTPIPE pPipeR = pRequest->enmType == VBOXSERVICECTRLREQUEST_ STDERR_READ524 PRTPIPE pPipeR = pRequest->enmType == VBOXSERVICECTRLREQUEST_PROC_STDERR 500 525 ? phStdErrR : phStdOutR; 501 526 AssertPtr(pPipeR); … … 508 533 if (RT_FAILURE(rcReq)) 509 534 { 510 RTPollSetRemove(hPollSet, pRequest->enmType == VBOXSERVICECTRLREQUEST_ STDERR_READ535 RTPollSetRemove(hPollSet, pRequest->enmType == VBOXSERVICECTRLREQUEST_PROC_STDERR 511 536 ? VBOXSERVICECTRLPIPEID_STDERR : VBOXSERVICECTRLPIPEID_STDOUT); 512 537 RTPipeClose(*pPipeR); … … 524 549 } 525 550 551 case VBOXSERVICECTRLREQUEST_PROC_TERM: 552 ASMAtomicXchgBool(&pThread->fShutdown, true); 553 fDefer = true; 554 break; 555 526 556 default: 527 557 rcReq = VERR_NOT_IMPLEMENTED; … … 529 559 } 530 560 531 /* Assign overall result. */ 532 pRequest->rc = RT_SUCCESS(rc) 533 ? rcReq : rc; 534 535 VBoxServiceVerbose(2, "[PID %u]: Handled req=%u, CID=%u, rc=%Rrc, cbData=%u\n", 536 pThread->uPID, pRequest->enmType, pRequest->uCID, pRequest->rc, pRequest->cbData); 537 538 /* In any case, regardless of the result, we notify 539 * the main guest control to unblock it. */ 540 int rc2 = RTSemEventMultiSignal(pRequest->Event); 541 AssertRC(rc2); 542 543 /* No access to pRequest here anymore -- could be out of scope 544 * or modified already! */ 545 pThread->pRequest = pRequest = NULL; 561 if ( RT_FAILURE(rc) 562 || !fDefer) 563 { 564 rc = gstcntlProcessSignalRequest(pRequest, 565 RT_SUCCESS(rc) ? rcReq : rc); 566 567 /* No access to pRequest here anymore -- could be out of scope 568 * or modified already! */ 569 pThread->pRequest = pRequest = NULL; 570 } 571 else /* Completing the request defered. */ 572 rc = VINF_AIO_TASK_PENDING; /** @todo Find an own rc! */ 546 573 547 574 return rc; … … 601 628 VBoxServiceVerbose(2, "[PID %u]: Process \"%s\" started, CID=%u, User=%s\n", 602 629 pThread->uPID, pThread->pszCmd, pThread->uContextID, pThread->pszUser); 603 rc = VbglR3GuestCtrl ExecReportStatus(pThread->uClientID, pThread->uContextID,604 605 630 rc = VbglR3GuestCtrlProcCbStatus(pThread->uClientID, pThread->uContextID, 631 pThread->uPID, PROC_STS_STARTED, 0 /* u32Flags */, 632 NULL /* pvData */, 0 /* cbData */); 606 633 607 634 /* 608 635 * Process input, output, the test pipe and client requests. 609 636 */ 637 PVBOXSERVICECTRLREQUEST pReq = NULL; 610 638 while ( RT_SUCCESS(rc) 611 639 && RT_UNLIKELY(!pThread->fShutdown)) … … 642 670 643 671 case VBOXSERVICECTRLPIPEID_IPC_NOTIFY: 672 pReq = pThread->pRequest; /** @todo Implement request queue. */ 644 673 rc = gstcntlProcessHandleRequest(hPollSet, fPollEvt, 645 phStdInW, phStdOutR, phStdErrR, pThread); 674 phStdInW, phStdOutR, phStdErrR, 675 pThread, pReq); 676 if (rc != VINF_AIO_TASK_PENDING) 677 pReq = NULL; 646 678 break; 647 679 … … 707 739 if (cMsElapsed >= cMsTimeout) 708 740 { 709 VBoxServiceVerbose(3, "[PID %u]: Timed out (%ums elapsed > %ums timeout), killing ... ",741 VBoxServiceVerbose(3, "[PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...\n", 710 742 pThread->uPID, cMsElapsed, cMsTimeout); 711 743 … … 787 819 if (fProcessAlive) 788 820 VBoxServiceVerbose(3, "[PID %u]: Could not be killed\n", pThread->uPID); 821 822 if ( pReq /* Handle deferred termination request. */ 823 && pReq->enmType == VBOXSERVICECTRLREQUEST_PROC_TERM) 824 { 825 rc2 = gstcntlProcessSignalRequest(pReq, 826 fProcessAlive ? VINF_SUCCESS : VERR_PROCESS_RUNNING); 827 pReq = NULL; 828 } 829 else if (pReq) 830 AssertMsgFailed(("Unable to handle unknown deferred request (type: %RU32)\n", pReq->enmType)); 789 831 } 790 832 … … 861 903 if (!(pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_START)) 862 904 { 863 rc2 = VbglR3GuestCtrl ExecReportStatus(pThread->uClientID, pThread->uContextID,864 865 905 rc2 = VbglR3GuestCtrlProcCbStatus(pThread->uClientID, pThread->uContextID, 906 pThread->uPID, uStatus, uFlags, 907 NULL /* pvData */, 0 /* cbData */); 866 908 if (RT_FAILURE(rc2)) 867 909 VBoxServiceError("[PID %u]: Error reporting final status to host; rc=%Rrc\n", … … 1050 1092 * should service. 1051 1093 */ 1052 static int gstcntlProcessSetupPipe(const char *pszHowTo, int fd,1053 1094 int GstcntlProcessSetupPipe(const char *pszHowTo, int fd, 1095 PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe) 1054 1096 { 1055 1097 AssertPtrReturn(ph, VERR_INVALID_POINTER); … … 1486 1528 RTHANDLE hStdIn; 1487 1529 PRTHANDLE phStdIn; 1488 rc = gstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/,1530 rc = GstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/, 1489 1531 &hStdIn, &phStdIn, &pThread->pipeStdInW); 1490 1532 if (RT_SUCCESS(rc)) … … 1493 1535 PRTHANDLE phStdOut; 1494 1536 RTPIPE pipeStdOutR; 1495 rc = gstcntlProcessSetupPipe( (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT)1537 rc = GstcntlProcessSetupPipe( (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT) 1496 1538 ? "|" : "/dev/null", 1497 1539 1 /*STDOUT_FILENO*/, … … 1502 1544 PRTHANDLE phStdErr; 1503 1545 RTPIPE pipeStdErrR; 1504 rc = gstcntlProcessSetupPipe( (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR)1546 rc = GstcntlProcessSetupPipe( (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR) 1505 1547 ? "|" : "/dev/null", 1506 1548 2 /*STDERR_FILENO*/, … … 1627 1669 if (RT_FAILURE(rc)) 1628 1670 { 1629 rc2 = VbglR3GuestCtrl ExecReportStatus(pThread->uClientID, pThread->uContextID, pThread->uPID,1630 1631 1671 rc2 = VbglR3GuestCtrlProcCbStatus(pThread->uClientID, pThread->uContextID, pThread->uPID, 1672 PROC_STS_ERROR, rc, 1673 NULL /* pvData */, 0 /* cbData */); 1632 1674 if (RT_FAILURE(rc2)) 1633 1675 VBoxServiceError("Could not report process failure error; rc=%Rrc (process error %Rrc)\n", … … 1635 1677 } 1636 1678 1637 VBoxServiceVerbose(3, "[PID %u]: Cancelling pending host requests (client ID=%u)\n", 1638 pThread->uPID, pThread->uClientID); 1639 rc2 = VbglR3GuestCtrlCancelPendingWaits(pThread->uClientID); 1640 if (RT_FAILURE(rc2)) 1641 { 1642 VBoxServiceError("[PID %u]: Cancelling pending host requests failed; rc=%Rrc\n", 1643 pThread->uPID, rc2); 1644 if (RT_SUCCESS(rc)) 1645 rc = rc2; 1646 } 1647 1648 /* Disconnect from guest control service. */ 1679 /* Disconnect this client from the guest control service. This also cancels all 1680 * outstanding host requests. */ 1649 1681 VBoxServiceVerbose(3, "[PID %u]: Disconnecting (client ID=%u) ...\n", 1650 1682 pThread->uPID, pThread->uClientID); -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r44528 r44863 108 108 #endif /* RT_OS_WINDOWS */ 109 109 110 #ifdef VBOX_WITH_GUEST_CONTROL111 /**112 * Pipe IDs for handling the guest process poll set.113 */114 typedef enum VBOXSERVICECTRLPIPEID115 {116 VBOXSERVICECTRLPIPEID_UNKNOWN = 0,117 VBOXSERVICECTRLPIPEID_STDIN = 10,118 VBOXSERVICECTRLPIPEID_STDIN_WRITABLE = 11,119 /** Pipe for reading from guest process' stdout. */120 VBOXSERVICECTRLPIPEID_STDOUT = 40,121 /** Pipe for reading from guest process' stderr. */122 VBOXSERVICECTRLPIPEID_STDERR = 50,123 /** Notification pipe for waking up the guest process124 * control thread. */125 VBOXSERVICECTRLPIPEID_IPC_NOTIFY = 100126 } VBOXSERVICECTRLPIPEID;127 128 /**129 * Request types to perform on a started guest process.130 */131 typedef enum VBOXSERVICECTRLREQUESTTYPE132 {133 /** Unknown request. */134 VBOXSERVICECTRLREQUEST_UNKNOWN = 0,135 /** Main control thread asked used to quit. */136 VBOXSERVICECTRLREQUEST_QUIT = 1,137 /** Performs reading from stdout. */138 VBOXSERVICECTRLREQUEST_STDOUT_READ = 50,139 /** Performs reading from stderr. */140 VBOXSERVICECTRLREQUEST_STDERR_READ = 60,141 /** Performs writing to stdin. */142 VBOXSERVICECTRLREQUEST_STDIN_WRITE = 70,143 /** Same as VBOXSERVICECTRLREQUEST_STDIN_WRITE, but144 * marks the end of input. */145 VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF = 71,146 /** Kill/terminate process.147 * @todo Implement this! */148 VBOXSERVICECTRLREQUEST_KILL = 90,149 /** Gently ask process to terminate.150 * @todo Implement this! */151 VBOXSERVICECTRLREQUEST_HANGUP = 91,152 /** Ask the process in which status it153 * currently is.154 * @todo Implement this! */155 VBOXSERVICECTRLREQUEST_STATUS = 100156 } VBOXSERVICECTRLREQUESTTYPE;157 158 /**159 * Thread list types.160 */161 typedef enum VBOXSERVICECTRLTHREADLISTTYPE162 {163 /** Unknown list -- uncool to use. */164 VBOXSERVICECTRLTHREADLIST_UNKNOWN = 0,165 /** Stopped list: Here all guest threads end up166 * when they reached the stopped state and can167 * be shut down / free'd safely. */168 VBOXSERVICECTRLTHREADLIST_STOPPED = 1,169 /**170 * Started list: Here all threads are registered171 * when they're up and running (that is, accepting172 * commands).173 */174 VBOXSERVICECTRLTHREADLIST_RUNNING = 2175 } VBOXSERVICECTRLTHREADLISTTYPE;176 177 /**178 * Structure to perform a request on a started guest179 * process. Needed for letting the main guest control thread180 * to communicate (and wait) for a certain operation which181 * will be done in context of the started guest process thread.182 */183 typedef struct VBOXSERVICECTRLREQUEST184 {185 /** Event semaphore to serialize access. */186 RTSEMEVENTMULTI Event;187 /** The request type to handle. */188 VBOXSERVICECTRLREQUESTTYPE enmType;189 /** Payload size; on input, this contains the (maximum) amount190 * of data the caller wants to write or to read. On output,191 * this show the actual amount of data read/written. */192 size_t cbData;193 /** Payload data; a pre-allocated data buffer for input/output. */194 void *pvData;195 /** The context ID which is required to complete the196 * request. Not used at the moment. */197 uint32_t uCID;198 /** The overall result of the operation. */199 int rc;200 } VBOXSERVICECTRLREQUEST;201 /** Pointer to request. */202 typedef VBOXSERVICECTRLREQUEST *PVBOXSERVICECTRLREQUEST;203 204 /**205 * Structure holding information for starting a guest206 * process.207 */208 typedef struct VBOXSERVICECTRLPROCESS209 {210 /** Full qualified path of process to start (without arguments). */211 char szCmd[GUESTPROCESS_MAX_CMD_LEN];212 /** Process execution flags. @sa */213 uint32_t uFlags;214 /** Command line arguments. */215 char szArgs[GUESTPROCESS_MAX_ARGS_LEN];216 /** Number of arguments specified in pszArgs. */217 uint32_t uNumArgs;218 /** String of environment variables ("FOO=BAR") to pass to the process219 * to start. */220 char szEnv[GUESTPROCESS_MAX_ENV_LEN];221 /** Size (in bytes) of environment variables block. */222 uint32_t cbEnv;223 /** Number of environment variables specified in pszEnv. */224 uint32_t uNumEnvVars;225 /** User name (account) to start the process under. */226 char szUser[GUESTPROCESS_MAX_USER_LEN];227 /** Password of specified user name (account). */228 char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN];229 /** Time limit (in ms) of the process' life time. */230 uint32_t uTimeLimitMS;231 } VBOXSERVICECTRLPROCESS;232 /** Pointer to a guest process block. */233 typedef VBOXSERVICECTRLPROCESS *PVBOXSERVICECTRLPROCESS;234 235 /**236 * Structure for holding data for one (started) guest process.237 */238 typedef struct VBOXSERVICECTRLTHREAD239 {240 /** Pointer to list archor of following241 * list node.242 * @todo Would be nice to have a RTListGetAnchor(). */243 PRTLISTANCHOR pAnchor;244 /** Node. */245 RTLISTNODE Node;246 /** The worker thread. */247 RTTHREAD Thread;248 /** Shutdown indicator; will be set when the thread249 * needs (or is asked) to shutdown. */250 bool volatile fShutdown;251 /** Indicator set by the service thread exiting. */252 bool volatile fStopped;253 /** Whether the service was started or not. */254 bool fStarted;255 /** Client ID. */256 uint32_t uClientID;257 /** Context ID. */258 uint32_t uContextID;259 /** Critical section for thread-safe use. */260 RTCRITSECT CritSect;261 /** @todo Document me! */262 uint32_t uPID;263 char *pszCmd;264 uint32_t uFlags;265 char **papszArgs;266 uint32_t uNumArgs;267 char **papszEnv;268 uint32_t uNumEnvVars;269 /** Name of specified user account to run the270 * guest process under. */271 char *pszUser;272 /** Password of specified user account. */273 char *pszPassword;274 /** Overall time limit (in ms) that the guest process275 * is allowed to run. 0 for indefinite time. */276 uint32_t uTimeLimitMS;277 /** Pointer to the current IPC request being278 * processed. */279 PVBOXSERVICECTRLREQUEST pRequest;280 /** StdIn pipe for addressing writes to the281 * guest process' stdin.*/282 RTPIPE pipeStdInW;283 /** The notification pipe associated with this guest process.284 * This is NIL_RTPIPE for output pipes. */285 RTPIPE hNotificationPipeW;286 /** The other end of hNotificationPipeW. */287 RTPIPE hNotificationPipeR;288 } VBOXSERVICECTRLTHREAD;289 /** Pointer to thread data. */290 typedef VBOXSERVICECTRLTHREAD *PVBOXSERVICECTRLTHREAD;291 292 /**293 * Structure for one (opened) guest file.294 */295 typedef struct VBOXSERVICECTRLFILE296 {297 /** Pointer to list archor of following298 * list node.299 * @todo Would be nice to have a RTListGetAnchor(). */300 PRTLISTANCHOR pAnchor;301 /** Node. */302 RTLISTNODE Node;303 /** The file name. */304 char szName[RTPATH_MAX];305 /** The file handle on the guest. */306 RTFILE hFile;307 /** File handle to identify this file. */308 uint32_t uHandle;309 /** Context ID. */310 uint32_t uContextID;311 } VBOXSERVICECTRLFILE;312 /** Pointer to thread data. */313 typedef VBOXSERVICECTRLFILE *PVBOXSERVICECTRLFILE;314 #endif /* VBOX_WITH_GUEST_CONTROL */315 110 #ifdef VBOX_WITH_GUEST_PROPS 316 317 111 /** 318 112 * A guest property cache. … … 359 153 extern char *g_pszProgName; 360 154 extern int g_cVerbosity; 155 extern char g_szLogFile[RTPATH_MAX + 128]; 361 156 extern uint32_t g_DefaultInterval; 362 157 extern VBOXSERVICE g_TimeSync; … … 406 201 #endif /* RT_OS_WINDOWS */ 407 202 408 #ifdef VBOX_WITH_GUEST_CONTROL409 /* Guest control main thread functions. */410 extern int GstCntlAssignPID(PVBOXSERVICECTRLTHREAD pThread, uint32_t uPID);411 extern int GstCntlListSet(VBOXSERVICECTRLTHREADLISTTYPE enmList,412 PVBOXSERVICECTRLTHREAD pThread);413 extern PVBOXSERVICECTRLTHREAD GstCntlLockThread(uint32_t uPID);414 extern void GstCntlUnlockThread(const PVBOXSERVICECTRLTHREAD pThread);415 extern int GstCntlSetInactive(PVBOXSERVICECTRLTHREAD pThread);416 /* Per-thread guest process functions. */417 extern int GstCntlProcessStart(uint32_t uContext,418 PVBOXSERVICECTRLPROCESS pProcess);419 extern int GstCntlProcessPerform(uint32_t uPID, PVBOXSERVICECTRLREQUEST pRequest);420 extern int GstCntlProcessStop(const PVBOXSERVICECTRLTHREAD pThread);421 extern int GstCntlProcessWait(const PVBOXSERVICECTRLTHREAD pThread,422 RTMSINTERVAL msTimeout, int *prc);423 extern int GstCntlProcessFree(PVBOXSERVICECTRLTHREAD pThread);424 /* Request handling. */425 extern int GstCntlProcessRequestAlloc(PVBOXSERVICECTRLREQUEST *ppReq,426 VBOXSERVICECTRLREQUESTTYPE enmType);427 extern int GstCntlProcessRequestAllocEx(PVBOXSERVICECTRLREQUEST *ppReq,428 VBOXSERVICECTRLREQUESTTYPE enmType,429 void *pvData,430 size_t cbData,431 uint32_t uCID);432 extern void GstCntlProcessRequestFree(PVBOXSERVICECTRLREQUEST pReq);433 #endif /* VBOX_WITH_GUEST_CONTROL */434 435 203 #ifdef VBOXSERVICE_MANAGEMENT 436 204 extern uint32_t VBoxServiceBalloonQueryPages(uint32_t cbPage); -
trunk/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp
r44528 r44863 696 696 char const *papszArgs[3]; 697 697 papszArgs[0] = pszExeName; 698 papszArgs[1] = " --pagefusionfork";698 papszArgs[1] = "pagefusion"; 699 699 papszArgs[2] = NULL; 700 700 rc = RTProcCreate(pszExeName, papszArgs, RTENV_DEFAULT, 0 /* normal child */, &hProcess); -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
r43877 r44863 1526 1526 1527 1527 while ( (ch = RTGetOpt(&GetState, &ValueUnion)) 1528 1528 && RT_SUCCESS(rc)) 1529 1529 { 1530 1530 /* For options that require an argument, ValueUnion has received the value. */
Note:
See TracChangeset
for help on using the changeset viewer.