VirtualBox

Changeset 3142 in vbox


Ignore:
Timestamp:
Jun 18, 2007 2:36:56 PM (18 years ago)
Author:
vboxsync
Message:

Moved the X11 guest clipboard connection and disconnection code into the additions kernel module to deal with problems when the client is terminated too abruptly

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VBoxGuest.h

    r3110 r3142  
    961961#pragma pack()
    962962
    963 #define IOCTL_VBOXGUEST_HGCM_CONNECT    IOCTL_CODE(FILE_DEVICE_UNKNOWN, 3072, METHOD_BUFFERED, FILE_WRITE_ACCESS, sizeof(VBoxGuestHGCMConnectInfo))
    964 #define IOCTL_VBOXGUEST_HGCM_DISCONNECT IOCTL_CODE(FILE_DEVICE_UNKNOWN, 3073, METHOD_BUFFERED, FILE_WRITE_ACCESS, sizeof(VBoxGuestHGCMDisconnectInfo))
    965 #define IOCTL_VBOXGUEST_HGCM_CALL       IOCTL_CODE(FILE_DEVICE_UNKNOWN, 3074, METHOD_BUFFERED, FILE_WRITE_ACCESS, sizeof(VBoxGuestHGCMCallInfo))
     963#define IOCTL_VBOXGUEST_HGCM_CONNECT      IOCTL_CODE(FILE_DEVICE_UNKNOWN, 3072, METHOD_BUFFERED, FILE_WRITE_ACCESS, sizeof(VBoxGuestHGCMConnectInfo))
     964#define IOCTL_VBOXGUEST_HGCM_DISCONNECT   IOCTL_CODE(FILE_DEVICE_UNKNOWN, 3073, METHOD_BUFFERED, FILE_WRITE_ACCESS, sizeof(VBoxGuestHGCMDisconnectInfo))
     965#define IOCTL_VBOXGUEST_HGCM_CALL         IOCTL_CODE(FILE_DEVICE_UNKNOWN, 3074, METHOD_BUFFERED, FILE_WRITE_ACCESS, sizeof(VBoxGuestHGCMCallInfo))
     966#define IOCTL_VBOXGUEST_CLIPBOARD_CONNECT IOCTL_CODE(FILE_DEVICE_UNKNOWN, 3075, METHOD_BUFFERED, FILE_WRITE_ACCESS, sizeof(uint32_t))
    966967
    967968#define VBOXGUEST_HGCM_CALL_PARMS(a) ((HGCMFunctionParameter *)((uint8_t *)(a) + sizeof (VBoxGuestHGCMCallInfo)))
  • trunk/src/VBox/Additions/linux/module/vboxmod.c

    r2980 r3142  
    277277               address space. */
    278278            return vbox_ioctl_hgcm_call(arg, vboxDev);
     279        }
     280
     281        case IOCTL_VBOXGUEST_CLIPBOARD_CONNECT:
     282        {
     283            static uint32_t u32ClientID = 0;
     284            VMMDevHGCMDisconnect *reqDisconnect = NULL;
     285            VMMDevHGCMConnect *reqConnect = NULL;
     286            size_t cbRequestSize;
     287            int rc;
     288
     289            /* First, disconnect any old client. */
     290            if (u32ClientID != 0)
     291            {
     292                /* get the request size */
     293                cbRequestSize = vmmdevGetRequestSize(VMMDevReq_HGCMDisconnect);
     294                /* request storage for the request */
     295                rc = VbglGRAlloc((VMMDevRequestHeader **) &reqDisconnect, cbRequestSize,
     296                                 VMMDevReq_HGCMDisconnect);
     297                if (VBOX_FAILURE(rc))
     298                {
     299                    printk(KERN_ERR
     300                          "vboxadd_ioctl: could not allocate request structure! rc = %d\n", rc);
     301                    return -EFAULT;
     302                }
     303                /* now get the full request */
     304                vmmdevInitRequest(&reqDisconnect->header.header, VMMDevReq_HGCMDisconnect);
     305                reqDisconnect->u32ClientID = u32ClientID;
     306
     307                /* now issue the request */
     308                rc = VbglGRPerform(&reqDisconnect->header.header);
     309
     310                /* asynchronous processing? */
     311                if (rc == VINF_HGCM_ASYNC_EXECUTE)
     312                {
     313                    VMMDevHGCMRequestHeader *reqHGCM = &reqDisconnect->header;
     314                    wait_event (vboxDev->eventq, reqHGCM->fu32Flags & VBOX_HGCM_REQ_DONE);
     315                    rc = reqHGCM->header.rc;
     316                }
     317
     318                /* failed? */
     319                if (VBOX_FAILURE(rc) || VBOX_FAILURE(reqDisconnect->header.header.rc))
     320                {
     321                    printk(KERN_ERR "vboxadd_ioctl: request execution failed!\n");
     322                    VbglGRFree(&reqDisconnect->header.header);
     323                    return -EFAULT;
     324                }
     325            }
     326
     327            /* And connect... */
     328            /* get the request size */
     329            cbRequestSize = vmmdevGetRequestSize(VMMDevReq_HGCMConnect);
     330            /* request storage for the request */
     331            rc = VbglGRAlloc((VMMDevRequestHeader **) &reqConnect, cbRequestSize, VMMDevReq_HGCMConnect);
     332            if (VBOX_FAILURE(rc))
     333            {
     334                printk(KERN_ERR
     335                       "vboxadd_ioctl: could not allocate request structure! rc = %d\n", rc);
     336                return -EFAULT;
     337            }
     338            /* now get the full request */
     339            vmmdevInitRequest((VMMDevRequestHeader*)reqConnect, VMMDevReq_HGCMConnect);
     340            reqConnect->loc.type = VMMDevHGCMLoc_LocalHost_Existing;
     341            strcpy (reqConnect->loc.u.host.achName, "VBoxSharedClipboard");
     342
     343            /* now issue the request */
     344            rc = VbglGRPerform(&reqConnect->header.header);
     345
     346            /* asynchronous processing? */
     347            if (rc == VINF_HGCM_ASYNC_EXECUTE)
     348            {
     349                VMMDevHGCMRequestHeader *reqHGCM = &reqConnect->header;
     350                wait_event (vboxDev->eventq, reqHGCM->fu32Flags & VBOX_HGCM_REQ_DONE);
     351                rc = reqHGCM->header.rc;
     352            }
     353
     354            /* failed? */
     355            if (VBOX_FAILURE(rc) || VBOX_FAILURE(reqConnect->header.header.rc))
     356            {
     357                printk(KERN_ERR "vboxadd_ioctl: request execution failed!\n");
     358                VbglGRFree(&reqConnect->header.header);
     359                return -EFAULT;
     360            }
     361            else
     362            {
     363                /* success, copy the result data to user space */
     364                u32ClientID = reqConnect->u32ClientID;
     365                if (copy_to_user((void*)arg, (void*)&(reqConnect->u32ClientID), sizeof(uint32_t)))
     366                {
     367                    printk(KERN_ERR
     368                           "vboxadd_ioctl: error copying request result to user space!\n");
     369                    VbglGRFree(&reqConnect->header.header);
     370                    return -EFAULT;
     371                }
     372            }
     373            VbglGRFree(&reqConnect->header.header);
     374            break;
    279375        }
    280376
  • trunk/src/VBox/Additions/linux/xclient/clipboard.cpp

    r3126 r3142  
    13651365void vboxClipboardDisconnect (void)
    13661366{
     1367#if 0
    13671368    VMMDevHGCMDisconnect request;
     1369#endif
    13681370    LogFlowFunc(("\n"));
    13691371
    13701372    AssertReturn(g_ctx.client != 0, (void) 0);
     1373#if 0
     1374    /* Currently, disconnecting is not needed, as the new "connect clipboard"
     1375       ioctl in the Guest Additions kernel module disconnects the last
     1376       connection made automatically.  The reason for this change was that
     1377       currently only one clipboard connection is allowed, and that if the
     1378       client holding that connection was terminated too abruptly, the
     1379       information needed to disconnect that connection was lost.  If the
     1380       subsystem is ever changed to allow several connections, this will have
     1381       to be rethought. */
    13711382    vmmdevInitRequest((VMMDevRequestHeader*)&request, VMMDevReq_HGCMDisconnect);
    13721383    request.u32ClientID = g_ctx.client;
    13731384    ioctl(g_ctx.sendDevice, IOCTL_VBOXGUEST_VMMREQUEST, (void*)&request);
     1385#endif
    13741386    LogFlowFunc(("returning\n"));
    13751387}
     
    14031415}
    14041416
    1405 void vboxClipboardSignalHandler(int number)
    1406 {
    1407     LogFlowFunc(("number: %d\n", number));
    1408     vboxClipboardDisconnect();
    1409     if (g_ctx.daemonise == 0)
    1410     {
    1411         cout << "Received signal " << number << ".  Aborting" << endl;
    1412     }
    1413     LogFlowFunc(("exiting\n"));
    1414     exit(1);
    1415 }
    14161417
    14171418/**
     
    14221423int vboxClipboardConnect (void)
    14231424{
    1424     VMMDevHGCMConnect request;
    1425     struct sigaction sSigAction;
    1426 
    14271425    LogFlowFunc(("\n"));
    1428     memset(&request, 0, sizeof(request));
    1429     request.u32ClientID = 0;
     1426    int rc;
    14301427    /* Only one client is supported for now */
    14311428    AssertReturn(g_ctx.client == 0, VERR_NOT_SUPPORTED);
    14321429
    1433     vmmdevInitRequest((VMMDevRequestHeader*)&request, VMMDevReq_HGCMConnect);
    1434     request.loc.type = VMMDevHGCMLoc_LocalHost_Existing;
    1435     strcpy (request.loc.u.host.achName, "VBoxSharedClipboard");
    1436     if (ioctl(g_ctx.sendDevice, IOCTL_VBOXGUEST_VMMREQUEST, (void*)&request) >= 0)
    1437     {
    1438         if (VBOX_SUCCESS(request.header.header.rc))
    1439         {
    1440             if (request.u32ClientID == 0)
    1441             {
    1442                 cout << "We got an invalid client ID of 0!" << endl;
    1443                 return VERR_NOT_SUPPORTED;
    1444             }
    1445             g_ctx.client = request.u32ClientID;
    1446             g_ctx.eOwner = HOST;
    1447         }
    1448         else
    1449         {
    1450             Log(("Error connecting to host.  header.rc = %Vrc\n", request.header.header.rc));
    1451             cout << "Unable to connect to the host system." << endl;
    1452             LogFlowFunc(("returned VERR_NOT_SUPPORTED\n"));
     1430    rc = ioctl(g_ctx.sendDevice, IOCTL_VBOXGUEST_CLIPBOARD_CONNECT, (void*)&g_ctx.client);
     1431    if (rc >= 0)
     1432    {
     1433        if (g_ctx.client == 0)
     1434        {
     1435            cout << "We got an invalid client ID of 0!" << endl;
    14531436            return VERR_NOT_SUPPORTED;
    14541437        }
    1455 
     1438        g_ctx.eOwner = HOST;
    14561439    }
    14571440    else
    14581441    {
    1459         Log(("Error performing VMM request ioctl. errno = %d\n", errno));
    1460         cout << "The VirtualBox device in the guest is not responding correctly." << endl;
     1442        Log(("Error connecting to host.  rc = %d (%s)\n", rc, strerror(-rc)));
     1443        cout << "Unable to connect to the host system." << endl;
    14611444        LogFlowFunc(("returned VERR_NOT_SUPPORTED\n"));
    14621445        return VERR_NOT_SUPPORTED;
    14631446    }
    1464     /* If the programme exits without disconnecting from the shared clipboard service, we
    1465        will need to reboot the guest in order to use it again.  So we set handlers for as
    1466        many fatal conditions as possible which disconnect and exit the programme. */
     1447    /* Set an X11 error handler, so that we don't die when we get BadAtom errors. */
    14671448    XSetErrorHandler(vboxClipboardXLibErrorHandler);
    1468     sSigAction.sa_handler = vboxClipboardSignalHandler;
    1469     sigemptyset(&sSigAction.sa_mask);
    1470     sSigAction.sa_flags = 0;
    1471     sigaction(SIGSEGV, &sSigAction, 0);
    1472     sigaction(SIGBUS, &sSigAction, 0);
    1473     sigaction(SIGUSR1, &sSigAction, 0);
    1474     sigaction(SIGINT, &sSigAction, 0);
    1475     sigaction(SIGQUIT, &sSigAction, 0);
    1476     sigaction(SIGTERM, &sSigAction, 0);
    1477     sigaction(SIGTRAP, &sSigAction, 0);
    14781449    LogFlowFunc(("returned VINF_SUCCESS\n"));
    14791450    return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette