Changeset 17899 in vbox for trunk/src/VBox/Additions/linux/module/vboxmod.c
- Timestamp:
- Mar 15, 2009 8:20:44 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/module/vboxmod.c
r17857 r17899 117 117 /* We just define a fixed number of these so far. This can be changed if it ever becomes 118 118 a problem. */ 119 static struct { 120 /** Open file structure that this connection handle is associated with */ 121 struct file *filp; 122 /** HGCM connection ID */ 123 uint32_t client_id; 124 } hgcm_connections[MAX_HGCM_CONNECTIONS] = { { 0 } }; 119 static struct 120 { 121 /** Open file structure that this connection handle is associated with */ 122 struct file *filp; 123 /** HGCM connection ID */ 124 uint32_t client_id; 125 } hgcm_connections[MAX_HGCM_CONNECTIONS] 126 = 127 { 128 { 0 } 129 }; 125 130 126 131 /** … … 134 139 static int vboxadd_register_hgcm_connection(uint32_t client_id, struct file *filp) 135 140 { 136 int i; 137 bool found = false; 138 139 for (i = 0; i < MAX_HGCM_CONNECTIONS; ++i) { 140 Assert(hgcm_connections[i].client_id != client_id); 141 } 142 for (i = 0; (i < MAX_HGCM_CONNECTIONS) && (false == found); ++i) { 143 if (ASMAtomicCmpXchgU32(&hgcm_connections[i].client_id, client_id, 0)) { 144 hgcm_connections[i].filp = filp; 145 found = true; 146 } 147 } 148 return found ? 0 : -ENFILE; /* Any ideas for a better error code? */ 141 int i; 142 bool found = false; 143 144 for (i = 0; i < MAX_HGCM_CONNECTIONS; ++i) 145 { 146 Assert(hgcm_connections[i].client_id != client_id); 147 } 148 for (i = 0; (i < MAX_HGCM_CONNECTIONS) && (false == found); ++i) 149 { 150 if (ASMAtomicCmpXchgU32(&hgcm_connections[i].client_id, client_id, 0)) 151 { 152 hgcm_connections[i].filp = filp; 153 found = true; 154 } 155 } 156 return found ? 0 : -ENFILE; /* Any ideas for a better error code? */ 149 157 } 150 158 … … 158 166 static int vboxadd_unregister_hgcm_connection_no_close(uint32_t client_id) 159 167 { 160 int i; 161 bool found = false; 162 163 for (i = 0; (i < MAX_HGCM_CONNECTIONS) && (false == found); ++i) { 164 if (hgcm_connections[i].client_id == client_id) { 165 hgcm_connections[i].filp = NULL; 166 hgcm_connections[i].client_id = 0; 167 found = true; 168 } 169 } 170 for (i = 0; i < MAX_HGCM_CONNECTIONS; ++i) { 171 Assert(hgcm_connections[i].client_id != client_id); 172 } 173 return found ? 0 : -ENOENT; 168 int i; 169 bool found = false; 170 171 for (i = 0; (i < MAX_HGCM_CONNECTIONS) && (false == found); ++i) 172 { 173 if (hgcm_connections[i].client_id == client_id) 174 { 175 hgcm_connections[i].filp = NULL; 176 hgcm_connections[i].client_id = 0; 177 found = true; 178 } 179 } 180 for (i = 0; i < MAX_HGCM_CONNECTIONS; ++i) 181 { 182 Assert(hgcm_connections[i].client_id != client_id); 183 } 184 return found ? 0 : -ENOENT; 174 185 } 175 186 … … 184 195 static int vboxadd_unregister_all_hgcm_connections(struct file *filp) 185 196 { 186 int i; 187 188 for (i = 0; i < MAX_HGCM_CONNECTIONS; ++i) { 189 if (hgcm_connections[i].filp == filp) { 190 VBoxGuestHGCMDisconnectInfo infoDisconnect; 191 infoDisconnect.u32ClientID = hgcm_connections[i].client_id; 192 vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT, 193 &infoDisconnect); 194 hgcm_connections[i].filp = NULL; 195 hgcm_connections[i].client_id = 0; 196 } 197 } 198 return 0; 197 int i; 198 199 for (i = 0; i < MAX_HGCM_CONNECTIONS; ++i) 200 { 201 if (hgcm_connections[i].filp == filp) 202 { 203 VBoxGuestHGCMDisconnectInfo infoDisconnect; 204 infoDisconnect.u32ClientID = hgcm_connections[i].client_id; 205 vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT, 206 &infoDisconnect); 207 hgcm_connections[i].filp = NULL; 208 hgcm_connections[i].client_id = 0; 209 } 210 } 211 return 0; 199 212 } 200 213 … … 217 230 218 231 info->u32Result = VBOXGUEST_WAITEVENT_OK; 219 if (RT_INDEFINITE_WAIT != info->u32TimeoutIn) { 220 timeleft = wait_event_interruptible_timeout 232 if (RT_INDEFINITE_WAIT != info->u32TimeoutIn) 233 { 234 timeleft = wait_event_interruptible_timeout 221 235 (vboxDev->eventq, 222 236 (vboxDev->u32Events & in_mask) … … 224 238 msecs_to_jiffies (info->u32TimeoutIn) 225 239 ); 226 if (vboxDev->u32GuestInterruptions != cInterruptions) { 227 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 228 } 229 if (timeleft < 0) { 230 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 231 } 232 if (timeleft == 0) { 233 info->u32Result = VBOXGUEST_WAITEVENT_TIMEOUT; 234 } 235 } 236 else { 237 if (wait_event_interruptible(vboxDev->eventq, 238 (vboxDev->u32Events & in_mask) 240 if (vboxDev->u32GuestInterruptions != cInterruptions) 241 { 242 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 243 } 244 if (timeleft < 0) 245 { 246 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 247 } 248 if (timeleft == 0) 249 { 250 info->u32Result = VBOXGUEST_WAITEVENT_TIMEOUT; 251 } 252 } 253 else 254 { 255 if (wait_event_interruptible(vboxDev->eventq, 256 (vboxDev->u32Events & in_mask) 239 257 || (vboxDev->u32GuestInterruptions != cInterruptions) 240 ) 241 ) { 242 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 243 } 258 ) 259 ) 260 { 261 info->u32Result = VBOXGUEST_WAITEVENT_INTERRUPTED; 262 } 244 263 } 245 264 info->u32EventFlagsOut = vboxDev->u32Events & in_mask; … … 255 274 static int vboxadd_wait_event(void *ptr) 256 275 { 257 int rc = 0; 258 VBoxGuestWaitEventInfo info; 259 260 if (copy_from_user (&info, ptr, sizeof (info))) { 261 LogRelFunc (("VBOXGUEST_IOCTL_WAITEVENT: can not get event info\n")); 262 rc = -EFAULT; 263 } 264 265 if (0 == rc) { 266 vboxadd_wait_for_event (&info); 267 268 if (copy_to_user (ptr, &info, sizeof (info))) { 269 LogRelFunc (("VBOXGUEST_IOCTL_WAITEVENT: can not put out_mask\n")); 270 rc = -EFAULT; 271 } 272 } 273 return 0; 276 int rc = 0; 277 VBoxGuestWaitEventInfo info; 278 279 if (copy_from_user (&info, ptr, sizeof (info))) 280 { 281 LogRelFunc (("VBOXGUEST_IOCTL_WAITEVENT: can not get event info\n")); 282 rc = -EFAULT; 283 } 284 285 if (0 == rc) 286 { 287 vboxadd_wait_for_event (&info); 288 289 if (copy_to_user (ptr, &info, sizeof (info))) 290 { 291 LogRelFunc (("VBOXGUEST_IOCTL_WAITEVENT: can not put out_mask\n")); 292 rc = -EFAULT; 293 } 294 } 295 return 0; 274 296 } 275 297 … … 287 309 static int vboxadd_hgcm_connect(struct file *filp, unsigned long userspace_info) 288 310 { 289 VBoxGuestHGCMConnectInfo info; 290 int rc = 0; 291 292 if (copy_from_user ((void *)&info, (void *)userspace_info, 293 sizeof (info)) != 0) { 294 LogFunc (("VBOXGUEST_IOCTL_HGCM_CONNECT: can not get connection info\n")); 295 rc = -EFAULT; 296 } 297 info.u32ClientID = 0; 298 if (rc >= 0) { 299 int vrc = vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_CONNECT, 300 &info); 301 rc = RT_FAILURE(vrc) ? -RTErrConvertToErrno(vrc) 302 : -RTErrConvertToErrno(info.result); 303 if (rc < 0) 304 LogFunc(("hgcm connection failed. internal ioctl result %Rrc, hgcm result %Rrc\n", 305 vrc, info.result)); 306 } 307 if (rc >= 0) { 308 /* Register that the connection is associated with this file pointer. */ 309 LogFunc(("Connected, client ID %u\n", info.u32ClientID)); 310 rc = vboxadd_register_hgcm_connection(info.u32ClientID, filp); 311 if (rc < 0) 312 LogFunc(("failed to register the HGCM connection\n")); 313 } 314 if ( rc >= 0 315 && copy_to_user ((void *)userspace_info, (void *)&info, 316 sizeof(info)) != 0) { 317 LogFunc (("failed to return the connection structure\n")); 318 rc = -EFAULT; 319 } 311 VBoxGuestHGCMConnectInfo info; 312 int rc = 0; 313 314 if (copy_from_user ((void *)&info, (void *)userspace_info, 315 sizeof (info)) != 0) 316 { 317 LogFunc (("VBOXGUEST_IOCTL_HGCM_CONNECT: can not get connection info\n")); 318 rc = -EFAULT; 319 } 320 info.u32ClientID = 0; 321 if (rc >= 0) 322 { 323 int vrc = vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_CONNECT, 324 &info); 325 rc = RT_FAILURE(vrc) ? -RTErrConvertToErrno(vrc) 326 : -RTErrConvertToErrno(info.result); 320 327 if (rc < 0) 321 /* Unregister again, as we didn't get as far as informing userspace. */ 322 vboxadd_unregister_hgcm_connection_no_close(info.u32ClientID); 323 if (rc < 0 && info.u32ClientID != 0) { 324 /* Disconnect the hgcm connection again, as we told userspace it failed. */ 325 VBoxGuestHGCMDisconnectInfo infoDisconnect; 326 infoDisconnect.u32ClientID = info.u32ClientID; 327 vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT, 328 &infoDisconnect); 329 } 330 return rc; 328 LogFunc(("hgcm connection failed. internal ioctl result %Rrc, hgcm result %Rrc\n", 329 vrc, info.result)); 330 } 331 if (rc >= 0) 332 { 333 /* Register that the connection is associated with this file pointer. */ 334 LogFunc(("Connected, client ID %u\n", info.u32ClientID)); 335 rc = vboxadd_register_hgcm_connection(info.u32ClientID, filp); 336 if (rc < 0) 337 LogFunc(("failed to register the HGCM connection\n")); 338 } 339 if ( rc >= 0 340 && copy_to_user ((void *)userspace_info, (void *)&info, 341 sizeof(info)) != 0) 342 { 343 LogFunc (("failed to return the connection structure\n")); 344 rc = -EFAULT; 345 } 346 if (rc < 0) 347 /* Unregister again, as we didn't get as far as informing userspace. */ 348 vboxadd_unregister_hgcm_connection_no_close(info.u32ClientID); 349 if (rc < 0 && info.u32ClientID != 0) 350 { 351 /* Disconnect the hgcm connection again, as we told userspace it failed. */ 352 VBoxGuestHGCMDisconnectInfo infoDisconnect; 353 infoDisconnect.u32ClientID = info.u32ClientID; 354 vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT, 355 &infoDisconnect); 356 } 357 return rc; 331 358 } 332 359 … … 342 369 static int vboxadd_hgcm_disconnect(struct file *filp, unsigned long userspace_info) 343 370 { 344 345 346 347 if (copy_from_user ((void *)&info, (void *)userspace_info,348 sizeof (info)) != 0){349 350 351 352 if (rc >= 0) {353 vrc = vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT,354 355 356 357 358 && copy_to_user ((void *)userspace_info, (void *)&info,359 sizeof(info)) != 0){360 361 362 363 371 int rc = 0, vrc = VINF_SUCCESS; 372 373 VBoxGuestHGCMDisconnectInfo info; 374 if (copy_from_user((void *)&info, (void *)userspace_info, sizeof (info)) != 0) 375 { 376 LogRelFunc (("VBOXGUEST_IOCTL_HGCM_DISCONNECT: can not get info\n")); 377 rc = -EFAULT; 378 } 379 if (rc >= 0) 380 { 381 vrc = vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT, &info); 382 rc = -RTErrConvertToErrno(vrc); 383 } 384 if ( rc >= 0 385 && copy_to_user((void *)userspace_info, (void *)&info, sizeof(info)) != 0) 386 { 387 LogRelFunc (("VBOXGUEST_IOCTL_HGCM_DISCONNECT: failed to return the connection structure\n")); 388 rc = -EFAULT; 389 } 390 return rc; 364 391 } 365 392 … … 382 409 void *pKernel = NULL; 383 410 int rc = 0; 411 384 412 AssertPtrReturn(ppBuf, -EINVAL); 385 413 AssertPtrReturn(pUser, -EINVAL); 414 386 415 pBuf = kmalloc(sizeof(*pBuf), GFP_KERNEL); 387 416 if (pBuf == NULL) 388 417 rc = -ENOMEM; 389 if (rc >= 0) { 418 if (rc >= 0) 419 { 390 420 pKernel = kmalloc(cb, GFP_KERNEL); 391 421 if (pKernel == NULL) … … 396 426 && copy_from_user(pKernel, pUser, cb) != 0) 397 427 rc = -EFAULT; 398 if (rc >= 0) { 428 if (rc >= 0) 429 { 399 430 pBuf->pKernel = pKernel; 400 431 pBuf->pUser = pUser; … … 402 433 *ppBuf = pBuf; 403 434 } 404 else { 435 else 436 { 405 437 kfree(pBuf); 406 438 kfree(pKernel); … … 504 536 } 505 537 else 538 { 506 539 if (ppvCtx[iParm] != NULL) 507 540 { … … 510 543 * we can see where it's coming from. */ 511 544 } 545 } 512 546 } 513 547 return rc; … … 525 559 static int vboxadd_hgcm_call(unsigned long userspace_info, uint32_t u32Size) 526 560 { 527 VBoxGuestHGCMCallInfo *pInfo = NULL; 528 void *apvCtx[VBOX_HGCM_MAX_PARMS]; 529 unsigned haveParms = 0; 530 int rc = 0; 531 532 pInfo = kmalloc(u32Size, GFP_KERNEL); 533 if (pInfo == NULL) 534 rc = -ENOMEM; 535 if (rc >= 0 && 536 0 != copy_from_user ((void *)pInfo, (void *)userspace_info, u32Size)) { 537 LogRelFunc (("can not get info from user space\n")); 538 rc = -EFAULT; 539 } 540 if (rc >= 0 && 541 sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter) != u32Size) { 542 LogRelFunc (("bad parameter size, structure says %d, ioctl says %d\n", 543 sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter), 544 u32Size)); 545 rc = -EINVAL; 546 } 547 if (rc >= 0) { 548 haveParms = 1; 549 rc = vboxadd_buffer_hgcm_parms(apvCtx, pInfo); 550 } 551 if (rc >= 0) { 552 int vrc; 553 vrc = vboxadd_cmc_call(vboxDev, 554 VBOXGUEST_IOCTL_HGCM_CALL(u32Size), pInfo); 555 rc = -RTErrConvertToErrno(vrc); 556 if ( rc >= 0 557 && copy_to_user ((void *)userspace_info, (void *)pInfo, 558 u32Size)) { 559 LogRelFunc (("failed to return the information to user space\n")); 560 rc = -EFAULT; 561 } 562 } 563 if (haveParms) 564 { 565 int rc2 = vboxadd_unbuffer_hgcm_parms(apvCtx, pInfo); 566 if (rc >= 0 && rc2 < 0) 567 rc = rc2; 568 } 569 if (pInfo != NULL) 570 kfree(pInfo); 571 return rc; 561 VBoxGuestHGCMCallInfo *pInfo = NULL; 562 void *apvCtx[VBOX_HGCM_MAX_PARMS]; 563 unsigned haveParms = 0; 564 int rc = 0; 565 566 pInfo = kmalloc(u32Size, GFP_KERNEL); 567 if (pInfo == NULL) 568 rc = -ENOMEM; 569 if ( rc >= 0 570 && 0 != copy_from_user ((void *)pInfo, (void *)userspace_info, u32Size)) 571 { 572 LogRelFunc (("can not get info from user space\n")); 573 rc = -EFAULT; 574 } 575 if ( rc >= 0 576 && sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter) != u32Size) 577 { 578 LogRelFunc (("bad parameter size, structure says %d, ioctl says %d\n", 579 sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter), 580 u32Size)); 581 rc = -EINVAL; 582 } 583 if (rc >= 0) 584 { 585 haveParms = 1; 586 rc = vboxadd_buffer_hgcm_parms(apvCtx, pInfo); 587 } 588 if (rc >= 0) 589 { 590 int vrc; 591 vrc = vboxadd_cmc_call(vboxDev, 592 VBOXGUEST_IOCTL_HGCM_CALL(u32Size), pInfo); 593 rc = -RTErrConvertToErrno(vrc); 594 if ( rc >= 0 595 && copy_to_user ((void *)userspace_info, (void *)pInfo, 596 u32Size)) 597 { 598 LogRelFunc (("failed to return the information to user space\n")); 599 rc = -EFAULT; 600 } 601 } 602 if (haveParms) 603 { 604 int rc2 = vboxadd_unbuffer_hgcm_parms(apvCtx, pInfo); 605 if (rc >= 0 && rc2 < 0) 606 rc = rc2; 607 } 608 if (pInfo != NULL) 609 kfree(pInfo); 610 return rc; 572 611 } 573 612 … … 582 621 */ 583 622 static int vboxadd_hgcm_call_timed(unsigned long userspace_info, 584 uint32_t u32Size) 585 { 586 VBoxGuestHGCMCallInfoTimed *pInfo = NULL; 587 void *apvCtx[VBOX_HGCM_MAX_PARMS]; 588 unsigned haveParms = 0; 589 int rc = 0; 590 591 pInfo = kmalloc(u32Size, GFP_KERNEL); 592 if (pInfo == NULL) 593 rc = -ENOMEM; 594 if (rc >= 0 && 595 0 != copy_from_user ((void *)pInfo, (void *)userspace_info, u32Size)) { 596 LogRelFunc (("can not get info from user space\n")); 597 rc = -EFAULT; 598 } 599 if (rc >= 0 && 600 sizeof(*pInfo) + pInfo->info.cParms * sizeof(HGCMFunctionParameter) != u32Size) { 601 LogRelFunc (("bad parameter size, structure says %d, ioctl says %d\n", 602 sizeof(*pInfo) + pInfo->info.cParms * sizeof(HGCMFunctionParameter), 603 u32Size)); 604 rc = -EINVAL; 605 } 606 if (rc >= 0) { 607 haveParms = 1; 608 rc = vboxadd_buffer_hgcm_parms(apvCtx, &pInfo->info); 609 } 610 if (rc >= 0) { 611 int vrc; 612 pInfo->fInterruptible = true; /* User space may not do uninterruptible waits */ 613 vrc = vboxadd_cmc_call(vboxDev, 614 VBOXGUEST_IOCTL_HGCM_CALL_TIMED(u32Size), pInfo); 615 rc = -RTErrConvertToErrno(vrc); 616 if ( rc >= 0 617 && copy_to_user ((void *)userspace_info, (void *)pInfo, 618 u32Size)) { 619 LogRelFunc (("failed to return the information to user space\n")); 620 rc = -EFAULT; 621 } 622 } 623 if (haveParms) 624 { 625 int rc2 = vboxadd_unbuffer_hgcm_parms(apvCtx, &pInfo->info); 626 if (rc >= 0 && rc2 < 0) 627 rc = rc2; 628 } 629 if (pInfo != NULL) 630 kfree(pInfo); 631 return rc; 623 uint32_t u32Size) 624 { 625 VBoxGuestHGCMCallInfoTimed *pInfo = NULL; 626 void *apvCtx[VBOX_HGCM_MAX_PARMS]; 627 unsigned haveParms = 0; 628 int rc = 0; 629 630 pInfo = kmalloc(u32Size, GFP_KERNEL); 631 if (pInfo == NULL) 632 rc = -ENOMEM; 633 if ( rc >= 0 634 && 0 != copy_from_user ((void *)pInfo, (void *)userspace_info, u32Size)) 635 { 636 LogRelFunc (("can not get info from user space\n")); 637 rc = -EFAULT; 638 } 639 if ( rc >= 0 640 && sizeof(*pInfo) + pInfo->info.cParms * sizeof(HGCMFunctionParameter) != u32Size) 641 { 642 LogRelFunc (("bad parameter size, structure says %d, ioctl says %d\n", 643 sizeof(*pInfo) + pInfo->info.cParms * sizeof(HGCMFunctionParameter), 644 u32Size)); 645 rc = -EINVAL; 646 } 647 if (rc >= 0) 648 { 649 haveParms = 1; 650 rc = vboxadd_buffer_hgcm_parms(apvCtx, &pInfo->info); 651 } 652 if (rc >= 0) 653 { 654 int vrc; 655 pInfo->fInterruptible = true; /* User space may not do uninterruptible waits */ 656 vrc = vboxadd_cmc_call(vboxDev, 657 VBOXGUEST_IOCTL_HGCM_CALL_TIMED(u32Size), pInfo); 658 rc = -RTErrConvertToErrno(vrc); 659 if ( rc >= 0 660 && copy_to_user ((void *)userspace_info, (void *)pInfo, u32Size)) 661 { 662 LogRelFunc (("failed to return the information to user space\n")); 663 rc = -EFAULT; 664 } 665 } 666 if (haveParms) 667 { 668 int rc2 = vboxadd_unbuffer_hgcm_parms(apvCtx, &pInfo->info); 669 if (rc >= 0 && rc2 < 0) 670 rc = rc2; 671 } 672 if (pInfo != NULL) 673 kfree(pInfo); 674 return rc; 632 675 } 633 676 … … 671 714 unsigned int cmd, unsigned long arg) 672 715 { 673 int rc = 0; 674 675 /* Deal with variable size ioctls first. */ 676 if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0)) 677 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) { 678 char *pszMessage; 679 680 IOCTL_LOG_ENTRY(arg); 681 pszMessage = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); 682 if (NULL == pszMessage) { 683 LogRelFunc(("VBOXGUEST_IOCTL_LOG: cannot allocate %d bytes of memory!\n", 684 _IOC_SIZE(cmd))); 685 rc = -ENOMEM; 686 } 687 if ( (0 == rc) 688 && copy_from_user(pszMessage, (void*)arg, _IOC_SIZE(cmd))) { 689 LogRelFunc(("VBOXGUEST_IOCTL_LOG: copy_from_user failed!\n")); 690 rc = -EFAULT; 691 } 692 if (0 == rc) { 693 Log(("%.*s", _IOC_SIZE(cmd), pszMessage)); 694 } 695 if (NULL != pszMessage) { 696 kfree(pszMessage); 697 } 698 IOCTL_LOG_EXIT(arg); 699 } 700 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_VMMREQUEST(0)) 701 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) { 702 VMMDevRequestHeader reqHeader; 703 VMMDevRequestHeader *reqFull = NULL; 704 size_t cbRequestSize; 705 size_t cbVanillaRequestSize; 706 707 IOCTL_VMM_ENTRY(arg); 708 if (copy_from_user(&reqHeader, (void*)arg, sizeof(reqHeader))) 716 int rc = 0; 717 718 /* Deal with variable size ioctls first. */ 719 if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0)) 720 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 721 { 722 char *pszMessage; 723 724 IOCTL_LOG_ENTRY(arg); 725 pszMessage = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); 726 if (NULL == pszMessage) 727 { 728 LogRelFunc(("VBOXGUEST_IOCTL_LOG: cannot allocate %d bytes of memory!\n", 729 _IOC_SIZE(cmd))); 730 rc = -ENOMEM; 731 } 732 if ( (0 == rc) 733 && copy_from_user(pszMessage, (void*)arg, _IOC_SIZE(cmd))) 734 { 735 LogRelFunc(("VBOXGUEST_IOCTL_LOG: copy_from_user failed!\n")); 736 rc = -EFAULT; 737 } 738 if (0 == rc) 739 { 740 Log(("%.*s", _IOC_SIZE(cmd), pszMessage)); 741 } 742 if (NULL != pszMessage) 743 { 744 kfree(pszMessage); 745 } 746 IOCTL_LOG_EXIT(arg); 747 } 748 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_VMMREQUEST(0)) 749 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 750 { 751 VMMDevRequestHeader reqHeader; 752 VMMDevRequestHeader *reqFull = NULL; 753 size_t cbRequestSize; 754 size_t cbVanillaRequestSize; 755 756 IOCTL_VMM_ENTRY(arg); 757 if (copy_from_user(&reqHeader, (void*)arg, sizeof(reqHeader))) 758 { 759 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: copy_from_user failed for vmm request!\n")); 760 rc = -EFAULT; 761 } 762 if (0 == rc) 763 { 764 /* get the request size */ 765 cbVanillaRequestSize = vmmdevGetRequestSize(reqHeader.requestType); 766 if (!cbVanillaRequestSize) 709 767 { 710 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: copy_from_user failed for vmm request!\n")); 768 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: invalid request type: %d\n", 769 reqHeader.requestType)); 770 rc = -EINVAL; 771 } 772 } 773 if (0 == rc) 774 { 775 cbRequestSize = reqHeader.size; 776 if (cbRequestSize < cbVanillaRequestSize) 777 { 778 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: invalid request size: %d min: %d type: %d\n", 779 cbRequestSize, 780 cbVanillaRequestSize, 781 reqHeader.requestType)); 782 rc = -EINVAL; 783 } 784 } 785 if (0 == rc) 786 { 787 /* request storage for the full request */ 788 rc = VbglGRAlloc(&reqFull, cbRequestSize, reqHeader.requestType); 789 if (RT_FAILURE(rc)) 790 { 791 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: could not allocate request structure! rc = %d\n", rc)); 711 792 rc = -EFAULT; 712 793 } 713 if (0 == rc) 794 } 795 if (0 == rc) 796 { 797 /* now get the full request */ 798 if (copy_from_user(reqFull, (void*)arg, cbRequestSize)) 714 799 { 715 /* get the request size */ 716 cbVanillaRequestSize = vmmdevGetRequestSize(reqHeader.requestType); 717 if (!cbVanillaRequestSize) 800 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: failed to fetch full request from user space!\n")); 801 rc = -EFAULT; 802 } 803 } 804 805 /* now issue the request */ 806 if (0 == rc) 807 { 808 int rrc = VbglGRPerform(reqFull); 809 810 /* asynchronous processing? */ 811 if (rrc == VINF_HGCM_ASYNC_EXECUTE) 812 { 813 VMMDevHGCMRequestHeader *reqHGCM = (VMMDevHGCMRequestHeader*)reqFull; 814 wait_event_interruptible (vboxDev->eventq, reqHGCM->fu32Flags & VBOX_HGCM_REQ_DONE); 815 rrc = reqFull->rc; 816 } 817 818 /* failed? */ 819 if (RT_FAILURE(rrc) || RT_FAILURE(reqFull->rc)) 820 { 821 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: request execution failed!\n")); 822 rc = RT_FAILURE(rrc) ? -RTErrConvertToErrno(rrc) 823 : -RTErrConvertToErrno(reqFull->rc); 824 } 825 else 826 { 827 /* success, copy the result data to user space */ 828 if (copy_to_user((void*)arg, (void*)reqFull, cbRequestSize)) 718 829 { 719 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: invalid request type: %d\n", 720 reqHeader.requestType)); 721 rc = -EINVAL; 722 } 723 } 724 if (0 == rc) 725 { 726 cbRequestSize = reqHeader.size; 727 if (cbRequestSize < cbVanillaRequestSize) 728 { 729 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: invalid request size: %d min: %d type: %d\n", 730 cbRequestSize, 731 cbVanillaRequestSize, 732 reqHeader.requestType)); 733 rc = -EINVAL; 734 } 735 } 736 if (0 == rc) 737 { 738 /* request storage for the full request */ 739 rc = VbglGRAlloc(&reqFull, cbRequestSize, reqHeader.requestType); 740 if (RT_FAILURE(rc)) 741 { 742 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: could not allocate request structure! rc = %d\n", rc)); 830 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: error copying request result to user space!\n")); 743 831 rc = -EFAULT; 744 832 } 745 833 } 746 if (0 == rc) 747 { 748 /* now get the full request */ 749 if (copy_from_user(reqFull, (void*)arg, cbRequestSize)) 750 { 751 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: failed to fetch full request from user space!\n")); 752 rc = -EFAULT; 753 } 754 } 755 756 /* now issue the request */ 757 if (0 == rc) 758 { 759 int rrc = VbglGRPerform(reqFull); 760 761 /* asynchronous processing? */ 762 if (rrc == VINF_HGCM_ASYNC_EXECUTE) 763 { 764 VMMDevHGCMRequestHeader *reqHGCM = (VMMDevHGCMRequestHeader*)reqFull; 765 wait_event_interruptible (vboxDev->eventq, reqHGCM->fu32Flags & VBOX_HGCM_REQ_DONE); 766 rrc = reqFull->rc; 767 } 768 769 /* failed? */ 770 if (RT_FAILURE(rrc) || RT_FAILURE(reqFull->rc)) 771 { 772 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: request execution failed!\n")); 773 rc = RT_FAILURE(rrc) ? -RTErrConvertToErrno(rrc) 774 : -RTErrConvertToErrno(reqFull->rc); 775 } 776 else 777 { 778 /* success, copy the result data to user space */ 779 if (copy_to_user((void*)arg, (void*)reqFull, cbRequestSize)) 780 { 781 LogRelFunc(("VBOXGUEST_IOCTL_VMMREQUEST: error copying request result to user space!\n")); 782 rc = -EFAULT; 783 } 784 } 785 } 786 if (NULL != reqFull) 787 VbglGRFree(reqFull); 788 IOCTL_VMM_EXIT(arg); 789 } 790 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)) 791 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 792 { 834 } 835 if (NULL != reqFull) 836 VbglGRFree(reqFull); 837 IOCTL_VMM_EXIT(arg); 838 } 839 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)) 840 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 841 { 793 842 /* Do the HGCM call using the Vbgl bits */ 794 795 796 797 798 799 800 843 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL", arg); 844 rc = vboxadd_hgcm_call(arg, _IOC_SIZE(cmd)); 845 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL", arg); 846 } 847 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0)) 848 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 849 { 801 850 /* Do the HGCM call using the Vbgl bits */ 802 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 803 rc = vboxadd_hgcm_call_timed(arg, _IOC_SIZE(cmd)); 804 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 805 } 806 else 807 { 808 switch (cmd) { 851 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 852 rc = vboxadd_hgcm_call_timed(arg, _IOC_SIZE(cmd)); 853 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 854 } 855 else 856 { 857 switch (cmd) 858 { 809 859 case VBOXGUEST_IOCTL_WAITEVENT: 810 811 812 813 860 IOCTL_ENTRY("VBOXGUEST_IOCTL_WAITEVENT", arg); 861 rc = vboxadd_wait_event((void *) arg); 862 IOCTL_EXIT("VBOXGUEST_IOCTL_WAITEVENT", arg); 863 break; 814 864 case VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS: 815 816 817 818 865 IOCTL_ENTRY("VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS", arg); 866 ++vboxDev->u32GuestInterruptions; 867 IOCTL_EXIT("VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS", arg); 868 break; 819 869 case VBOXGUEST_IOCTL_HGCM_CONNECT: 820 821 822 823 870 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CONNECT", arg); 871 rc = vboxadd_hgcm_connect(filp, arg); 872 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CONNECT", arg); 873 break; 824 874 case VBOXGUEST_IOCTL_HGCM_DISCONNECT: 825 826 827 828 875 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_DISCONNECT", arg); 876 vboxadd_hgcm_disconnect(filp, arg); 877 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_DISCONNECT", arg); 878 break; 829 879 case VBOXGUEST_IOCTL_CTL_FILTER_MASK: 830 880 { 831 VBoxGuestFilterMaskInfo info; 832 IOCTL_ENTRY("VBOXGUEST_IOCTL_CTL_FILTER_MASK", arg); 833 if (copy_from_user((void*)&info, (void*)arg, sizeof(info))) 834 { 835 LogRelFunc(("VBOXGUEST_IOCTL_CTL_FILTER_MASK: error getting parameters from user space!\n")); 836 rc = -EFAULT; 837 break; 838 } 839 rc = -RTErrConvertToErrno(vboxadd_control_filter_mask(&info)); 840 IOCTL_EXIT("VBOXGUEST_IOCTL_CTL_FILTER_MASK", arg); 881 VBoxGuestFilterMaskInfo info; 882 IOCTL_ENTRY("VBOXGUEST_IOCTL_CTL_FILTER_MASK", arg); 883 if (copy_from_user((void*)&info, (void*)arg, sizeof(info))) 884 { 885 LogRelFunc(("VBOXGUEST_IOCTL_CTL_FILTER_MASK: error getting parameters from user space!\n")); 886 rc = -EFAULT; 841 887 break; 888 } 889 rc = -RTErrConvertToErrno(vboxadd_control_filter_mask(&info)); 890 IOCTL_EXIT("VBOXGUEST_IOCTL_CTL_FILTER_MASK", arg); 891 break; 842 892 } 843 893 default: 844 845 846 847 848 849 894 LogRelFunc(("unknown command: %x\n", cmd)); 895 rc = -EINVAL; 896 break; 897 } 898 } 899 return rc; 850 900 } 851 901 … … 856 906 unsigned int cmd, unsigned long arg) 857 907 { 858 859 860 861 if (VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0))862 863 908 int rc = 0; 909 910 /* Deal with variable size ioctls first. */ 911 if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)) 912 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 913 { 864 914 /* Do the HGCM call using the Vbgl bits */ 865 866 867 868 869 870 871 915 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL", arg); 916 rc = vboxadd_hgcm_call(arg, _IOC_SIZE(cmd)); 917 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL", arg); 918 } 919 else if ( VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(0)) 920 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 921 { 872 922 /* Do the HGCM call using the Vbgl bits */ 873 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 874 rc = vboxadd_hgcm_call_timed(arg, _IOC_SIZE(cmd)); 875 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 876 } 877 else 878 { 879 switch (cmd) { 923 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 924 rc = vboxadd_hgcm_call_timed(arg, _IOC_SIZE(cmd)); 925 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMED", arg); 926 } 927 else 928 { 929 switch (cmd) 930 { 880 931 case VBOXGUEST_IOCTL_HGCM_CONNECT: 881 882 883 884 932 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CONNECT", arg); 933 rc = vboxadd_hgcm_connect(filp, arg); 934 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CONNECT", arg); 935 break; 885 936 case VBOXGUEST_IOCTL_HGCM_DISCONNECT: 886 887 888 889 937 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_DISCONNECT", arg); 938 vboxadd_hgcm_disconnect(filp, arg); 939 IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_DISCONNECT", arg); 940 break; 890 941 default: 891 892 893 894 895 896 942 LogRelFunc(("unknown command: %x\n", cmd)); 943 rc = -EINVAL; 944 break; 945 } 946 } 947 return rc; 897 948 } 898 949 … … 941 992 static int vboxadd_release(struct inode *inode, struct file * filp) 942 993 { 943 944 945 946 994 vboxadd_unregister_all_hgcm_connections(filp); 995 /* Deactivate our asynchronous queue. */ 996 vboxadd_fasync(-1, filp, 0); 997 return 0; 947 998 } 948 999 … … 953 1004 static int vboxuser_release(struct inode *inode, struct file * filp) 954 1005 { 955 956 1006 vboxadd_unregister_all_hgcm_connections(filp); 1007 return 0; 957 1008 } 958 1009 … … 1144 1195 VbglGRFree(&req->header); 1145 1196 return 0; 1197 1146 1198 bail_out: 1147 1199 /* error return */ … … 1235 1287 #else 1236 1288 #define PCI_DEV_GET(v,d,p) pci_find_device(v,d,p) 1237 #define PCI_DEV_PUT(x) 1289 #define PCI_DEV_PUT(x) do {} while(0) 1238 1290 #endif 1239 1291 … … 1245 1297 { 1246 1298 int rc = 0, rcVBox = VINF_SUCCESS; 1247 bool haveVBoxAdd = false, haveVBoxUser = false, haveGuestLib = false;1299 bool fHaveVBoxAdd = false, fHaveVBoxUser = false, fHaveGuestLib = false; 1248 1300 struct pci_dev *pcidev = NULL; 1249 1301 … … 1272 1324 LogRel(("vboxadd: could not enable device: %d\n", rc)); 1273 1325 } 1274 if ( rc)1326 if (!rc) 1275 1327 LogRel(("Starting VirtualBox version %s Guest Additions\n", 1276 1328 VBOX_VERSION_STRING)); … … 1282 1334 if (rc) /* As we pass a non-zero major, rc should be zero on success. */ 1283 1335 LogRel(("vboxadd: register_chrdev failed: vbox_major: %d, err = %d\n", 1284 1336 vbox_major, rc)); 1285 1337 } 1286 1338 else if (!rc) /* Register as a miscellaneous device otherwise */ … … 1292 1344 } 1293 1345 if (!rc) 1294 haveVBoxAdd = true;1346 fHaveVBoxAdd = true; 1295 1347 1296 1348 /* Register our user session device */ … … 1302 1354 } 1303 1355 if (!rc) 1304 haveVBoxUser = true;1356 fHaveVBoxUser = true; 1305 1357 1306 1358 /* allocate and initialize device extension */ … … 1373 1425 } 1374 1426 if (!rc) 1375 haveGuestLib = true;1427 fHaveGuestLib = true; 1376 1428 1377 1429 /* report guest information to host, this must be done as the very first request */ … … 1399 1451 rcVBox = VbglGRPerform(&infoReq->header); 1400 1452 } 1401 if (infoReq && (RT_FAILURE(rcVBox) || RT_FAILURE(infoReq->header.rc))) 1453 if ( infoReq 1454 && ( RT_FAILURE(rcVBox) 1455 || RT_FAILURE(infoReq->header.rc))) 1402 1456 { 1403 1457 LogRel(("vboxadd: error reporting guest information to host: %Rrc, header: %Rrc\n", … … 1486 1540 info.u32NotMask = 0; 1487 1541 rcVBox = vboxadd_control_filter_mask(&info); 1488 if ( !RT_SUCCESS(rcVBox))1542 if (RT_FAILURE(rcVBox)) 1489 1543 { 1490 1544 LogRel(("vboxadd: failed to register for VMMDEV_EVENT_MOUSE_POSITION_CHANGED events: %Rrc\n", … … 1508 1562 else /* Clean up on failure */ 1509 1563 { 1510 if ( haveGuestLib)1564 if (fHaveGuestLib) 1511 1565 VbglTerminate(); 1512 1566 if (vboxDev) 1513 1567 free_resources(); 1514 if ( haveVBoxUser)1568 if (fHaveVBoxUser) 1515 1569 misc_deregister(&gMiscVBoxUser); 1516 if ( haveVBoxAdd && vbox_major > 0)1570 if (fHaveVBoxAdd && vbox_major > 0) 1517 1571 unregister_chrdev(vbox_major, VBOXADD_NAME); 1518 else if ( haveVBoxAdd)1572 else if (fHaveVBoxAdd) 1519 1573 misc_deregister(&gMiscVBoxAdd); 1520 1574 } 1575 1521 1576 /* We always release this. Presumably because we no longer need to do 1522 1577 * anything with the device structure. */ 1523 1578 if (pcidev) 1524 1579 PCI_DEV_PUT(pcidev); 1580 1525 1581 return rc; 1526 1582 }
Note:
See TracChangeset
for help on using the changeset viewer.