VirtualBox

Changeset 49891 in vbox


Ignore:
Timestamp:
Dec 12, 2013 8:09:20 PM (11 years ago)
Author:
vboxsync
Message:

Merged private draganddrop branch into trunk.

Location:
trunk
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/include/VBox/HostServices/DragAndDropSvc.h

    r42264 r49891  
    44
    55/*
    6  * Copyright (C) 2011-2012 Oracle Corporation
     6 * Copyright (C) 2011-2013 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    7272    HOST_DND_HG_EVT_DROPPED,
    7373    HOST_DND_HG_EVT_CANCEL,
     74    /** Gets the actual MIME data, based on
     75     *  the format(s) specified by HOST_DND_HG_EVT_ENTER. */
    7476    HOST_DND_HG_SND_DATA,
     77    /** Sent when the actual buffer for HOST_DND_HG_SND_DATA
     78     *  was too small. */
    7579    HOST_DND_HG_SND_MORE_DATA,
    7680    HOST_DND_HG_SND_DIR,
     
    392396    uint32_t uPercentage;
    393397    uint32_t uState;
     398    int rc;
    394399} VBOXDNDCBHGEVTPROGRESSDATA;
    395 typedef VBOXDNDCBHGEVTPROGRESSDATA *PVBOXDNDCBHGEVTPROGRESSDATA ;
     400typedef VBOXDNDCBHGEVTPROGRESSDATA *PVBOXDNDCBHGEVTPROGRESSDATA;
    396401
    397402typedef struct VBOXDNDCBGHACKPENDINGDATA
     
    419424    /** Callback data header. */
    420425    VBOXDNDCBHEADERDATA hdr;
    421     int32_t  rc;
     426    int32_t rc;
    422427} VBOXDNDCBEVTERRORDATA;
    423428typedef VBOXDNDCBEVTERRORDATA *PVBOXDNDCBEVTERRORDATA;
  • trunk/include/VBox/VBoxGuestLib.h

    r49349 r49891  
    7878
    7979RT_C_DECLS_BEGIN
    80 
    8180
    8281/** @defgroup grp_guest_lib_r0     Ring-0 interface.
     
    694693{
    695694    uint32_t uType;               /** The event type this struct contains */
    696     uint32_t uScreenId;           /** Screen id this request belongs to */
     695    uint32_t uScreenId;           /** Screen ID this request belongs to */
    697696    char    *pszFormats;          /** Format list (\r\n separated) */
    698697    uint32_t cbFormats;           /** Size of pszFormats (\0 included) */
     
    715714typedef VBGLR3DNDHGCMEVENT *PVBGLR3DNDHGCMEVENT;
    716715typedef const PVBGLR3DNDHGCMEVENT CPVBGLR3DNDHGCMEVENT;
    717 VBGLR3DECL(int)     VbglR3DnDInit(void);
    718 VBGLR3DECL(int)     VbglR3DnDTerm(void);
    719 
    720716VBGLR3DECL(int)     VbglR3DnDConnect(uint32_t *pu32ClientId);
    721717VBGLR3DECL(int)     VbglR3DnDDisconnect(uint32_t u32ClientId);
    722718
    723 VBGLR3DECL(int)     VbglR3DnDProcessNextMessage(CPVBGLR3DNDHGCMEVENT pEvent);
    724 
    725 VBGLR3DECL(int)     VbglR3DnDHGAcknowledgeOperation(uint32_t uAction);
    726 VBGLR3DECL(int)     VbglR3DnDHGRequestData(const char* pcszFormat);
     719VBGLR3DECL(int)     VbglR3DnDProcessNextMessage(uint32_t u32ClientId, CPVBGLR3DNDHGCMEVENT pEvent);
     720
     721VBGLR3DECL(int)     VbglR3DnDHGAcknowledgeOperation(uint32_t u32ClientId, uint32_t uAction);
     722VBGLR3DECL(int)     VbglR3DnDHGRequestData(uint32_t u32ClientId, const char* pcszFormat);
    727723#  ifdef VBOX_WITH_DRAG_AND_DROP_GH
    728 VBGLR3DECL(int)     VbglR3DnDGHAcknowledgePending(uint32_t uDefAction, uint32_t uAllActions, const char* pcszFormat);
    729 VBGLR3DECL(int)     VbglR3DnDGHSendData(void *pvData, uint32_t cbData);
    730 VBGLR3DECL(int)     VbglR3DnDGHErrorEvent(int rcOp);
     724VBGLR3DECL(int)     VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId, uint32_t uDefAction, uint32_t uAllActions, const char* pcszFormat);
     725VBGLR3DECL(int)     VbglR3DnDGHSendData(uint32_t u32ClientId, void *pvData, uint32_t cbData);
     726VBGLR3DECL(int)     VbglR3DnDGHErrorEvent(uint32_t u32ClientId, int rcOp);
    731727#  endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    732728/** @} */
  • trunk/include/VBox/log.h

    r48809 r49891  
    222222    /** Guest control. */
    223223    LOG_GROUP_GUEST_CONTROL,
     224    /** Guest drag'n drop. */
     225    LOG_GROUP_GUEST_DND,
    224226    /** GUI group. */
    225227    LOG_GROUP_GUI,
     
    770772    "GMM",          \
    771773    "GUEST_CONTROL", \
     774    "GUEST_DND",    \
    772775    "GUI",          \
    773776    "GVMM",         \
  • trunk/src/VBox

  • trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk

    r48070 r49891  
    2626endif
    2727VBoxTray_SDKS     = ReorderCompilerIncs $(VBOX_WINDDK_GST)
    28 VBoxTray_DEFS     = VBOX_WITH_HGCM LOG_TO_BACKDOOR
     28VBoxTray_DEFS     = \
     29        VBOX_WITH_HGCM \
     30        VBOX_BUILD_TARGET=\"$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)\"
    2931VBoxTray_INCS     = ../include
    3032VBoxTray_SOURCES  = \
     
    3941        VBoxHelpers.cpp \
    4042        VBoxTray.rc
     43ifdef VBOX_WITH_DRAG_AND_DROP
     44 VBoxTray_DEFS     += \
     45        VBOX_WITH_DRAG_AND_DROP \
     46        $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,)
     47 VBoxTray_SOURCES  += \
     48        VBoxDnD.cpp \
     49        VBoxDnDDataObject.cpp \
     50        VBoxDnDEnumFormat.cpp \
     51        VBoxDnDDropSource.cpp
     52endif
    4153ifdef VBOX_WITH_GUEST_PROPS
    42  VBoxTray_DEFS     +=  _WIN32_IE=0x500 VBOX_WITH_GUEST_PROPS
     54 VBoxTray_DEFS     += _WIN32_IE=0x500 VBOX_WITH_GUEST_PROPS
    4355 VBoxTray_SOURCES  += \
    4456        VBoxHostVersion.cpp \
     
    4658endif
    4759ifdef VBOX_WITH_SHARED_FOLDERS
    48  VBoxTray_DEFS     +=  VBOX_WITH_SHARED_FOLDERS
     60 VBoxTray_DEFS     += VBOX_WITH_SHARED_FOLDERS
    4961 VBoxTray_SOURCES  += \
    5062        VBoxSharedFolders.cpp
     
    5769        VBoxMMR.cpp
    5870endif
    59 
    6071ifdef VBOX_WITH_WDDM
    6172 VBoxTray_DEFS   += VBOX_WITH_WDDM
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r44528 r49891  
    525525    }
    526526
     527#ifndef DEBUG_andy
    527528    Log(("VBoxTray: vboxClipboardProcessMsg returned with rc = %ld\n", rc));
     529#endif
    528530    return rc;
    529531}
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp

    r48979 r49891  
    964964        else
    965965        {
     966#ifndef DEBUG_andy /* Too noisy for me. */
    966967            Log(("VBoxTray: VBoxDisplayThread: error 0 from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
     968#endif
    967969            /* sleep a bit to not eat too much CPU in case the above call always fails */
    968970            if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp

    r48070 r49891  
    2020*   Header Files                                                               *
    2121*******************************************************************************/
     22#ifdef DEBUG
     23# define LOG_ENABLED
     24# define LOG_GROUP LOG_GROUP_DEFAULT
     25#endif
     26
     27#include <package-generated.h>
     28#include "product-generated.h"
     29
    2230#include "VBoxTray.h"
    2331#include "VBoxTrayMsg.h"
     
    3038#include "VBoxHostVersion.h"
    3139#include "VBoxSharedFolders.h"
     40#ifdef VBOX_WITH_DRAG_AND_DROP
     41# include "VBoxDnD.h"
     42#endif
    3243#include "VBoxIPC.h"
    3344#include "VBoxLA.h"
     
    4253#include <iprt/buildconfig.h>
    4354#include <iprt/ldr.h>
     55#include <iprt/process.h>
     56#include <iprt/system.h>
     57#include <iprt/time.h>
     58#include <VBox/log.h>
    4459
    4560/* Default desktop state tracking */
     
    133148DWORD                 gMajorVersion;
    134149
     150static PRTLOGGER      g_pLoggerRelease = NULL;
     151static uint32_t       g_cHistory = 10;                   /* Enable log rotation, 10 files. */
     152static uint32_t       g_uHistoryFileTime = RT_SEC_1DAY;  /* Max 1 day per file. */
     153static uint64_t       g_uHistoryFileSize = 100 * _1M;    /* Max 100MB per file. */
    135154
    136155/* The service table. */
     
    195214        NULL /* pfnStop */,
    196215        VBoxMMRDestroy
     216    },
     217#endif
     218#ifdef VBOX_WITH_DRAG_AND_DROP
     219    {
     220        "Drag and Drop",
     221        VBoxDnDInit,
     222        VBoxDnDThread,
     223        VBoxDnDStop,
     224        VBoxDnDDestroy
    197225    },
    198226#endif
     
    475503        ghVBoxDriver = NULL;
    476504    }
     505}
     506
     507/**
     508 * Release logger callback.
     509 *
     510 * @return  IPRT status code.
     511 * @param   pLoggerRelease
     512 * @param   enmPhase
     513 * @param   pfnLog
     514 */
     515static void vboxTrayLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog)
     516{
     517    /* Some introductory information. */
     518    static RTTIMESPEC s_TimeSpec;
     519    char szTmp[256];
     520    if (enmPhase == RTLOGPHASE_BEGIN)
     521        RTTimeNow(&s_TimeSpec);
     522    RTTimeSpecToString(&s_TimeSpec, szTmp, sizeof(szTmp));
     523
     524    switch (enmPhase)
     525    {
     526        case RTLOGPHASE_BEGIN:
     527        {
     528            pfnLog(pLoggerRelease,
     529                   "VBoxTray %s r%s %s (%s %s) release log\n"
     530                   "Log opened %s\n",
     531                   RTBldCfgVersion(), RTBldCfgRevisionStr(), VBOX_BUILD_TARGET,
     532                   __DATE__, __TIME__, szTmp);
     533
     534            int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));
     535            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
     536                pfnLog(pLoggerRelease, "OS Product: %s\n", szTmp);
     537            vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));
     538            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
     539                pfnLog(pLoggerRelease, "OS Release: %s\n", szTmp);
     540            vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));
     541            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
     542                pfnLog(pLoggerRelease, "OS Version: %s\n", szTmp);
     543            if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)
     544                pfnLog(pLoggerRelease, "OS Service Pack: %s\n", szTmp);
     545
     546            /* the package type is interesting for Linux distributions */
     547            char szExecName[RTPATH_MAX];
     548            char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));
     549            pfnLog(pLoggerRelease,
     550                   "Executable: %s\n"
     551                   "Process ID: %u\n"
     552                   "Package type: %s"
     553#ifdef VBOX_OSE
     554                   " (OSE)"
     555#endif
     556                   "\n",
     557                   pszExecName ? pszExecName : "unknown",
     558                   RTProcSelf(),
     559                   VBOX_PACKAGE_STRING);
     560            break;
     561        }
     562
     563        case RTLOGPHASE_PREROTATE:
     564            pfnLog(pLoggerRelease, "Log rotated - Log started %s\n", szTmp);
     565            break;
     566
     567        case RTLOGPHASE_POSTROTATE:
     568            pfnLog(pLoggerRelease, "Log continuation - Log started %s\n", szTmp);
     569            break;
     570
     571        case RTLOGPHASE_END:
     572            pfnLog(pLoggerRelease, "End of log file - Log started %s\n", szTmp);
     573            break;
     574
     575        default:
     576            /* nothing */;
     577    }
     578}
     579
     580/**
     581 * Creates the default release logger outputting to the specified file.
     582 * Pass NULL for disabled logging.
     583 *
     584 * @return  IPRT status code.
     585 * @param   pszLogFile              Filename for log output.  Optional.
     586 */
     587static int vboxTrayLogCreate(const char *pszLogFile)
     588{
     589    /* Create release logger (stdout + file). */
     590    static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
     591    RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG;
     592#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
     593    fFlags |= RTLOGFLAGS_USECRLF;
     594#endif
     595    char szError[RTPATH_MAX + 128] = "";
     596    int rc = RTLogCreateEx(&g_pLoggerRelease, fFlags,
     597#ifdef DEBUG
     598                           "all.e.l.f",
     599                           "VBOXTRAY_LOG",
     600#else
     601                           "all",
     602                           "VBOXTRAY_RELEASE_LOG",
     603#endif
     604                           RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT,
     605                           vboxTrayLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime,
     606                           szError, sizeof(szError), pszLogFile);
     607    if (RT_SUCCESS(rc))
     608    {
     609#ifdef DEBUG
     610        RTLogSetDefaultInstance(g_pLoggerRelease);
     611#else
     612        /* Register this logger as the release logger. */
     613        RTLogRelSetDefaultInstance(g_pLoggerRelease);
     614#endif
     615        /* Explicitly flush the log in case of VBOXTRAY_RELEASE_LOG=buffered. */
     616        RTLogFlush(g_pLoggerRelease);
     617    }
     618    else
     619        MessageBox(GetDesktopWindow(),
     620                   szError, "VBoxTray - Logging Error", MB_OK | MB_ICONERROR);
     621
     622    return rc;
     623}
     624
     625static void vboxTrayLogDestroy(void)
     626{
     627    RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
    477628}
    478629
     
    802953                            while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    803954                            {
     955#ifndef DEBUG_andy
    804956                                Log(("VBoxTray: msg %p\n", msg.message));
     957#endif
    805958                                if (msg.message == WM_QUIT)
    806959                                {
     
    833986int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    834987{
    835     /* Do not use a global namespace ("Global\\") for mutex name here, will blow up NT4 compatibility! */
     988    /* Note: Do not use a global namespace ("Global\\") for mutex name here,
     989     * will blow up NT4 compatibility! */
    836990    HANDLE hMutexAppRunning = CreateMutex(NULL, FALSE, "VBoxTray");
    837991    if (   hMutexAppRunning != NULL
    838992        && GetLastError() == ERROR_ALREADY_EXISTS)
    839993    {
    840         /* Close the mutex for this application instance. */
     994        /* VBoxTray already running? Bail out. */
    841995        CloseHandle (hMutexAppRunning);
    842996        hMutexAppRunning = NULL;
     
    8471001
    8481002    int rc = RTR3InitExeNoArguments(0);
     1003    if (RT_SUCCESS(rc))
     1004        rc = vboxTrayLogCreate(NULL /* pszLogFile */);
     1005
    8491006    if (RT_SUCCESS(rc))
    8501007    {
     
    9311088
    9321089    VbglR3Term();
     1090
     1091    vboxTrayLogDestroy();
     1092
    9331093    return RT_SUCCESS(rc) ? 0 : 1;
    9341094}
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxVRDP.cpp

    r46593 r49891  
    409409                else
    410410                {
     411#ifndef DEBUG_andy /* Too noisy for me. */
    411412                    Log(("VBoxTray: VBoxVRDPThread: Error from DeviceIoControl VBOXGUEST_IOCTL_VMMREQUEST\n"));
    412 
     413#endif
    413414                    /* sleep a bit to not eat too much CPU in case the above call always fails */
    414415                    if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
     
    422423        else
    423424        {
     425#ifndef DEBUG_andy
    424426            Log(("VBoxTray: VBoxVRDPThread: Error from DeviceIoControl VBOXGUEST_IOCTL_WAITEVENT\n"));
    425 
     427#endif
    426428            /* sleep a bit to not eat too much CPU in case the above call always fails */
    427429            if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 10) == WAIT_OBJECT_0)
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp

    r42261 r49891  
    55
    66/*
    7  * Copyright (C) 2011-2012 Oracle Corporation
     7 * Copyright (C) 2011-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4141#include "VBox/HostServices/DragAndDropSvc.h"
    4242
    43 #define VERBOSE 1
    44 
    45 #if defined(VERBOSE) && defined(DEBUG_poetzsch)
    46 # include <iprt/stream.h>
    47 # define DO(s) RTPrintf s
    48 #else
    49 # define DO(s) do {} while(0)
    50 //# define DO(s) Log s
    51 #endif
    52 
    5343/* Here all the communication with the host over HGCM is handled platform
    5444 * neutral. Also the receiving of URIs content (directory trees and files) is
     
    6151 */
    6252
    63 /* Not really used at the moment (only one client is possible): */
    64 uint32_t g_clientId = 0;
    65 
    6653/******************************************************************************
    6754 *    Private internal functions                                              *
     
    7057static int vbglR3DnDCreateDropDir(char* pszDropDir, size_t cbSize)
    7158{
    72     /* Validate input */
    7359    AssertPtrReturn(pszDropDir, VERR_INVALID_POINTER);
    7460    AssertReturn(cbSize,        VERR_INVALID_PARAMETER);
    7561
    76     /* Get the users document directory (usually $HOME/Documents). */
    77     int rc = RTPathUserDocuments(pszDropDir, cbSize);
     62    /** @todo On Windows we also could use the registry to override
     63     *        this path, on Posix a dotfile and/or a guest property
     64     *        can be used. */
     65
     66    /* Get the users temp directory. Don't use the user's root directory (or
     67     * something inside it) because we don't know for how long/if the data will
     68     * be kept after the guest OS used it. */
     69    int rc = RTPathTemp(pszDropDir, cbSize);
    7870    if (RT_FAILURE(rc))
    7971        return rc;
     72
    8073    /* Append our base drop directory. */
    8174    rc = RTPathAppend(pszDropDir, cbSize, "VirtualBox Dropped Files");
    8275    if (RT_FAILURE(rc))
    8376        return rc;
     77
    8478    /* Create it when necessary. */
    8579    if (!RTDirExists(pszDropDir))
     
    8983            return rc;
    9084    }
     85
    9186    /* The actually drop directory consist of the current time stamp and a
    9287     * unique number when necessary. */
     
    9590    if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime)))
    9691        return VERR_BUFFER_OVERFLOW;
     92#ifdef RT_OS_WINDOWS
     93    /* Filter out characters not allowed on Windows platforms, put in by
     94       RTTimeSpecToString(). */
     95    /** @todo Use something like RTPathSanitize() when available. Later. */
     96    RTUNICP aCpSet[] =
     97        { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_',
     98          0xa0, 0xd7af, '\0' };
     99    RTStrPurgeComplementSet(pszTime, aCpSet, '_' /* Replacement */);
     100#endif
     101
    97102    rc = RTPathAppend(pszDropDir, cbSize, pszTime);
    98103    if (RT_FAILURE(rc))
     
    105110static int vbglR3DnDQueryNextHostMessageType(uint32_t uClientId, uint32_t *puMsg, uint32_t *pcParms, bool fWait)
    106111{
    107     /* Validate input */
    108112    AssertPtrReturn(puMsg,   VERR_INVALID_POINTER);
    109113    AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
    110114
    111     /* Initialize header */
    112115    DragAndDropSvc::VBOXDNDNEXTMSGMSG Msg;
    113116    RT_ZERO(Msg);
     
    116119    Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG;
    117120    Msg.hdr.cParms      = 3;
    118     /* Initialize parameter */
     121
    119122    Msg.msg.SetUInt32(0);
    120123    Msg.num_parms.SetUInt32(0);
    121124    Msg.block.SetUInt32(fWait);
    122     /* Do request */
     125
    123126    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    124127    if (RT_SUCCESS(rc))
     
    132135        }
    133136    }
     137
    134138    return rc;
    135139}
     
    146150                                           uint32_t *pcbFormatsRecv)
    147151{
    148     /* Validate input */
    149152    AssertPtrReturn(puScreenId,     VERR_INVALID_POINTER);
    150153    AssertPtrReturn(puX,            VERR_INVALID_POINTER);
     
    156159    AssertPtrReturn(pcbFormatsRecv, VERR_INVALID_POINTER);
    157160
    158     /* Initialize header */
    159161    DragAndDropSvc::VBOXDNDHGACTIONMSG Msg;
    160162    RT_ZERO(Msg);
     
    162164    Msg.hdr.u32Function = uMsg;
    163165    Msg.hdr.cParms      = 7;
    164     /* Initialize parameter */
     166
    165167    Msg.uScreenId.SetUInt32(0);
    166168    Msg.uX.SetUInt32(0);
     
    170172    Msg.pvFormats.SetPtr(pszFormats, cbFormats);
    171173    Msg.cFormats.SetUInt32(0);
    172     /* Do request */
     174
    173175    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    174176    if (RT_SUCCESS(rc))
     
    188190        }
    189191    }
     192
    190193    return rc;
    191194}
     
    193196static int vbglR3DnDHGProcessLeaveMessage(uint32_t uClientId)
    194197{
    195     /* Initialize header */
    196198    DragAndDropSvc::VBOXDNDHGLEAVEMSG Msg;
    197199    RT_ZERO(Msg);
     
    199201    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_LEAVE;
    200202    Msg.hdr.cParms      = 0;
    201     /* Do request */
    202     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    203     if (RT_SUCCESS(rc))
    204         rc = Msg.hdr.result;
     203
     204    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     205    if (RT_SUCCESS(rc))
     206        rc = Msg.hdr.result;
     207
    205208    return rc;
    206209}
     
    208211static int vbglR3DnDHGProcessCancelMessage(uint32_t uClientId)
    209212{
    210     /* Initialize header */
    211213    DragAndDropSvc::VBOXDNDHGCANCELMSG Msg;
    212214    RT_ZERO(Msg);
     
    214216    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_EVT_CANCEL;
    215217    Msg.hdr.cParms      = 0;
    216     /* Do request */
    217     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    218     if (RT_SUCCESS(rc))
    219         rc = Msg.hdr.result;
     218
     219    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     220    if (RT_SUCCESS(rc))
     221        rc = Msg.hdr.result;
     222
    220223    return rc;
    221224}
     
    227230                                            uint32_t *pfMode)
    228231{
    229     /* Validate input */
    230232    AssertPtrReturn(pszDirname,     VERR_INVALID_POINTER);
    231233    AssertReturn(cbDirname,         VERR_INVALID_PARAMETER);
     
    233235    AssertPtrReturn(pfMode,         VERR_INVALID_POINTER);
    234236
    235     /* Initialize header */
    236237    DragAndDropSvc::VBOXDNDHGSENDDIRMSG Msg;
    237238    RT_ZERO(Msg);
     
    239240    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DIR;
    240241    Msg.hdr.cParms      = 3;
    241     /* Initialize parameter */
     242
    242243    Msg.pvName.SetPtr(pszDirname, cbDirname);
    243244    Msg.cName.SetUInt32(0);
    244245    Msg.fMode.SetUInt32(0);
    245     /* Do request */
     246
    246247    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    247248    if (RT_SUCCESS(rc))
     
    257258        }
    258259    }
     260
    259261    return rc;
    260262}
     
    269271                                             uint32_t *pfMode)
    270272{
    271     /* Validate input */
    272273    AssertPtrReturn(pszFilename,     VERR_INVALID_POINTER);
    273274    AssertReturn(cbFilename,         VERR_INVALID_PARAMETER);
     
    278279    AssertPtrReturn(pfMode,          VERR_INVALID_POINTER);
    279280
    280     /* Initialize header */
    281281    DragAndDropSvc::VBOXDNDHGSENDFILEMSG Msg;
    282282    RT_ZERO(Msg);
     
    284284    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_FILE;
    285285    Msg.hdr.cParms      = 5;
    286     /* Initialize parameter */
     286
    287287    Msg.pvName.SetPtr(pszFilename, cbFilename);
    288288    Msg.cName.SetUInt32(0);
     
    290290    Msg.cData.SetUInt32(0);
    291291    Msg.fMode.SetUInt32(0);
    292     /* Do request */
     292
    293293    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    294294    if (RT_SUCCESS(rc))
     
    306306        }
    307307    }
     308
    308309    return rc;
    309310}
     
    376377        uint32_t uNextMsg;
    377378        uint32_t cNextParms;
    378         rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false);
    379         DO(("%Rrc - %d\n", rc , uNextMsg));
     379        rc = vbglR3DnDQueryNextHostMessageType(uClientId, &uNextMsg, &cNextParms, false /* fWait */);
    380380        if (RT_SUCCESS(rc))
    381381        {
     
    392392                    if (RT_SUCCESS(rc))
    393393                    {
    394                         DO(("Got drop dir: %s - %o - %Rrc\n", pszPathname, fMode, rc));
    395394                        char *pszNewDir = RTPathJoinA(pszDropDir, pszPathname);
    396395                        rc = RTDirCreate(pszNewDir, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRWXU, 0);
     
    415414                    {
    416415                        char *pszNewFile = RTPathJoinA(pszDropDir, pszPathname);
    417                         DO(("Got drop file: %s - %d - %o - %Rrc\n", pszPathname, cbDataRecv, fMode, rc));
    418416                        RTFILE hFile;
     417                        /** @todo r=andy Keep the file open and locked during the actual file transfer. Otherwise this will
     418                         *               create all sorts of funny races because we don't know if the guest has
     419                         *               modified the file in between the file data send calls. */
    419420                        rc = RTFileOpen(&hFile, pszNewFile, RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
    420421                        if (RT_SUCCESS(rc))
     
    443444                    /* Break out of the loop. */
    444445                }
    445                 default: fLoop = false; break;
     446                default:
     447                    fLoop = false;
     448                    break;
    446449            }
    447         } else
     450        }
     451        else
    448452        {
    449453            if (rc == VERR_NO_DATA)
     
    451455            break;
    452456        }
    453     }while(fLoop);
     457
     458    } while (fLoop);
    454459
    455460    RTMemFree(pvTmpData);
     461
    456462    /* Cleanup on failure or if the user has canceled. */
    457463    if (RT_FAILURE(rc))
     
    477483                                                 uint32_t *pcbDataRecv)
    478484{
    479     /* Validate input */
    480485    AssertPtrReturn(puScreenId,    VERR_INVALID_POINTER);
    481486    AssertPtrReturn(pszFormat,     VERR_INVALID_POINTER);
     
    486491    AssertPtrReturn(pcbDataRecv,   VERR_INVALID_POINTER);
    487492
    488     /* Initialize header */
    489493    DragAndDropSvc::VBOXDNDHGSENDDATAMSG Msg;
    490494    RT_ZERO(Msg);
     
    492496    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_DATA;
    493497    Msg.hdr.cParms      = 5;
    494     /* Initialize parameter */
     498
    495499    Msg.uScreenId.SetUInt32(0);
    496500    Msg.pvFormat.SetPtr(pszFormat, cbFormat);
     
    498502    Msg.pvData.SetPtr(pvData, cbData);
    499503    Msg.cData.SetUInt32(0);
    500     /* Do request */
     504
    501505    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    502506    if (RT_SUCCESS(rc))
     
    515519        }
    516520    }
     521
    517522    return rc;
    518523}
     
    523528                                                     uint32_t *pcbDataRecv)
    524529{
    525     /* Validate input */
    526530    AssertPtrReturn(pvData,      VERR_INVALID_POINTER);
    527531    AssertReturn(cbData,         VERR_INVALID_PARAMETER);
    528532    AssertPtrReturn(pcbDataRecv, VERR_INVALID_POINTER);
    529533
    530     /* Initialize header */
    531534    DragAndDropSvc::VBOXDNDHGSENDMOREDATAMSG Msg;
    532535    RT_ZERO(Msg);
    533     Msg.hdr.u32ClientID = g_clientId;
     536    Msg.hdr.u32ClientID = uClientId;
    534537    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA;
    535538    Msg.hdr.cParms      = 2;
    536     /* Initialize parameter */
     539
    537540    Msg.pvData.SetPtr(pvData, cbData);
    538541    Msg.cData.SetUInt32(0);
    539     /* Do request */
     542
    540543    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    541544    if (RT_SUCCESS(rc))
     
    554557}
    555558
    556 static int vbglR3DnDHGProcessSendDataMessages(uint32_t  uClientId,
    557                                               uint32_t *puScreenId,
    558                                               char     *pszFormat,
    559                                               uint32_t  cbFormat,
    560                                               uint32_t *pcbFormatRecv,
    561                                               void    **ppvData,
    562                                               uint32_t  cbData,
    563                                               size_t   *pcbDataRecv)
     559static int vbglR3DnDHGProcessSendDataMessageLoop(uint32_t  uClientId,
     560                                                 uint32_t *puScreenId,
     561                                                 char     *pszFormat,
     562                                                 uint32_t  cbFormat,
     563                                                 uint32_t *pcbFormatRecv,
     564                                                 void    **ppvData,
     565                                                 uint32_t  cbData,
     566                                                 size_t   *pcbDataRecv)
    564567{
    565568    uint32_t cbDataRecv = 0;
     
    572575                                                   cbData,
    573576                                                   &cbDataRecv);
    574 
    575     size_t cbAllDataRecv = cbDataRecv;
     577    uint32_t cbAllDataRecv = cbDataRecv;
    576578    while (rc == VERR_BUFFER_OVERFLOW)
    577579    {
     
    624626                                             size_t    *pcbDataRecv)
    625627{
    626     int rc = vbglR3DnDHGProcessSendDataMessages(uClientId,
    627                                                 puScreenId,
    628                                                 pszFormat,
    629                                                 cbFormat,
    630                                                 pcbFormatRecv,
    631                                                 ppvData,
    632                                                 cbData,
    633                                                 pcbDataRecv);
    634     if (RT_SUCCESS(rc))
    635     {
    636         /* Check if this is a uri-event */
     628    int rc = vbglR3DnDHGProcessSendDataMessageLoop(uClientId,
     629                                                   puScreenId,
     630                                                   pszFormat,
     631                                                   cbFormat,
     632                                                   pcbFormatRecv,
     633                                                   ppvData,
     634                                                   cbData,
     635                                                   pcbDataRecv);
     636    if (RT_SUCCESS(rc))
     637    {
     638        /* Check if this is a uri-event. If so, let VbglR3 do all the actual
     639         * data transfer + file /directory creation internally without letting
     640         * the caller know. */
    637641        if (RTStrNICmp(pszFormat, "text/uri-list", *pcbFormatRecv) == 0)
    638642            rc = vbglR3DnDHGProcessURIMessages(uClientId,
     
    645649                                               pcbDataRecv);
    646650    }
     651
    647652    return rc;
    648653}
     
    651656                                                   uint32_t *puScreenId)
    652657{
    653     /* Validate input */
    654658    AssertPtrReturn(puScreenId, VERR_INVALID_POINTER);
    655659
    656     /* Initialize header */
    657660    DragAndDropSvc::VBOXDNDGHREQPENDINGMSG Msg;
    658661    RT_ZERO(Msg);
     
    660663    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_REQ_PENDING;
    661664    Msg.hdr.cParms      = 1;
    662     /* Initialize parameter */
     665
    663666    Msg.uScreenId.SetUInt32(0);
    664     /* Do request */
     667
    665668    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    666669    if (RT_SUCCESS(rc))
     
    673676        }
    674677    }
     678
    675679    return rc;
    676680}
     
    682686                                            uint32_t *puAction)
    683687{
    684     /* Validate input */
    685688    AssertPtrReturn(pszFormat,     VERR_INVALID_POINTER);
    686689    AssertReturn(cbFormat,         VERR_INVALID_PARAMETER);
     
    688691    AssertPtrReturn(puAction,      VERR_INVALID_POINTER);
    689692
    690     /* Initialize header */
    691693    DragAndDropSvc::VBOXDNDGHDROPPEDMSG Msg;
    692694    RT_ZERO(Msg);
     
    694696    Msg.hdr.u32Function = DragAndDropSvc::HOST_DND_GH_EVT_DROPPED;
    695697    Msg.hdr.cParms      = 3;
    696     /* Initialize parameter */
     698
    697699    Msg.pvFormat.SetPtr(pszFormat, cbFormat);
    698700    Msg.cFormat.SetUInt32(0);
    699701    Msg.uAction.SetUInt32(0);
    700     /* Do request */
     702
    701703    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    702704    if (RT_SUCCESS(rc))
     
    712714        }
    713715    }
     716
    714717    return rc;
    715718}
     
    719722 ******************************************************************************/
    720723
    721 /**
    722  * Initialize Drag & Drop.
    723  *
    724  * This will enable the Drag & Drop events.
    725  *
    726  * @returns VBox status code.
    727  */
    728 VBGLR3DECL(int) VbglR3DnDInit(void)
    729 {
    730     return VbglR3DnDConnect(&g_clientId);
    731 }
    732 
    733 /**
    734  * Terminate Drag and Drop.
    735  *
    736  * This will Drag and Drop events.
    737  *
    738  * @returns VBox status.
    739  */
    740 VBGLR3DECL(int) VbglR3DnDTerm(void)
    741 {
    742     return VbglR3DnDDisconnect(g_clientId);
    743 }
    744 
    745724VBGLR3DECL(int) VbglR3DnDConnect(uint32_t *pu32ClientId)
    746725{
    747     /* Validate input */
    748726    AssertPtrReturn(pu32ClientId, VERR_INVALID_POINTER);
    749727
     
    770748VBGLR3DECL(int) VbglR3DnDDisconnect(uint32_t u32ClientId)
    771749{
    772     /* Initialize header */
    773750    VBoxGuestHGCMDisconnectInfo Info;
    774751    Info.result      = VERR_WRONG_ORDER;
    775752    Info.u32ClientID = u32ClientId;
     753
    776754    /* Do request */
    777755    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
    778756    if (RT_SUCCESS(rc))
    779757        rc = Info.result;
    780     return rc;
    781 }
    782 
    783 VBGLR3DECL(int) VbglR3DnDProcessNextMessage(CPVBGLR3DNDHGCMEVENT pEvent)
    784 {
    785     /* Validate input */
     758
     759    return rc;
     760}
     761
     762VBGLR3DECL(int) VbglR3DnDProcessNextMessage(uint32_t u32ClientId, CPVBGLR3DNDHGCMEVENT pEvent)
     763{
    786764    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    787765
     
    789767    uint32_t       uNumParms  = 0;
    790768    const uint32_t ccbFormats = _64K;
    791     const uint32_t ccbData    = _1M;
    792     int rc = vbglR3DnDQueryNextHostMessageType(g_clientId, &uMsg, &uNumParms, true);
    793     if (RT_SUCCESS(rc))
    794     {
    795         DO(("Got message %d\n", uMsg));
     769    const uint32_t ccbData    = _64K;
     770    int rc = vbglR3DnDQueryNextHostMessageType(u32ClientId, &uMsg, &uNumParms,
     771                                               true /* fWait */);
     772    if (RT_SUCCESS(rc))
     773    {
    796774        switch(uMsg)
    797775        {
     
    803781                pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
    804782                if (!pEvent->pszFormats)
    805                     return VERR_NO_MEMORY;
    806                 rc = vbglR3DnDHGProcessActionMessage(g_clientId,
    807                                                      uMsg,
    808                                                      &pEvent->uScreenId,
    809                                                      &pEvent->u.a.uXpos,
    810                                                      &pEvent->u.a.uYpos,
    811                                                      &pEvent->u.a.uDefAction,
    812                                                      &pEvent->u.a.uAllActions,
    813                                                      pEvent->pszFormats,
    814                                                      ccbFormats,
    815                                                      &pEvent->cbFormats);
     783                    rc = VERR_NO_MEMORY;
     784
     785                if (RT_SUCCESS(rc))
     786                    rc = vbglR3DnDHGProcessActionMessage(u32ClientId,
     787                                                         uMsg,
     788                                                         &pEvent->uScreenId,
     789                                                         &pEvent->u.a.uXpos,
     790                                                         &pEvent->u.a.uYpos,
     791                                                         &pEvent->u.a.uDefAction,
     792                                                         &pEvent->u.a.uAllActions,
     793                                                         pEvent->pszFormats,
     794                                                         ccbFormats,
     795                                                         &pEvent->cbFormats);
    816796                break;
    817797            }
     
    819799            {
    820800                pEvent->uType = uMsg;
    821                 rc = vbglR3DnDHGProcessLeaveMessage(g_clientId);
     801                rc = vbglR3DnDHGProcessLeaveMessage(u32ClientId);
    822802                break;
    823803            }
     
    827807                pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
    828808                if (!pEvent->pszFormats)
    829                     return VERR_NO_MEMORY;
    830                 pEvent->u.b.pvData = RTMemAlloc(ccbData);
    831                 if (!pEvent->u.b.pvData)
     809                    rc = VERR_NO_MEMORY;
     810
     811                if (RT_SUCCESS(rc))
    832812                {
    833                     RTMemFree(pEvent->pszFormats);
    834                     pEvent->pszFormats = NULL;
    835                     return VERR_NO_MEMORY;
     813                    pEvent->u.b.pvData = RTMemAlloc(ccbData);
     814                    if (!pEvent->u.b.pvData)
     815                    {
     816                        RTMemFree(pEvent->pszFormats);
     817                        pEvent->pszFormats = NULL;
     818                        rc = VERR_NO_MEMORY;
     819                    }
    836820                }
    837                 rc = vbglR3DnDHGProcessSendDataMessage(g_clientId,
    838                                                        &pEvent->uScreenId,
    839                                                        pEvent->pszFormats,
    840                                                        ccbFormats,
    841                                                        &pEvent->cbFormats,
    842                                                        &pEvent->u.b.pvData,
    843                                                        ccbData,
    844                                                        &pEvent->u.b.cbData);
     821
     822                if (RT_SUCCESS(rc))
     823                    rc = vbglR3DnDHGProcessSendDataMessage(u32ClientId,
     824                                                           &pEvent->uScreenId,
     825                                                           pEvent->pszFormats,
     826                                                           ccbFormats,
     827                                                           &pEvent->cbFormats,
     828                                                           &pEvent->u.b.pvData,
     829                                                           ccbData,
     830                                                           &pEvent->u.b.cbData);
     831                break;
     832            }
     833            case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
     834            {
     835                pEvent->uType = uMsg;
     836                rc = vbglR3DnDHGProcessCancelMessage(u32ClientId);
    845837                break;
    846838            }
     
    849841            {
    850842                pEvent->uType = uMsg;
    851                 rc = vbglR3DnDGHProcessRequestPendingMessage(g_clientId,
     843                rc = vbglR3DnDGHProcessRequestPendingMessage(u32ClientId,
    852844                                                             &pEvent->uScreenId);
    853845                break;
     
    858850                pEvent->pszFormats = static_cast<char*>(RTMemAlloc(ccbFormats));
    859851                if (!pEvent->pszFormats)
    860                     return VERR_NO_MEMORY;
    861                 rc = vbglR3DnDGHProcessDroppedMessage(g_clientId,
    862                                                       pEvent->pszFormats,
    863                                                       ccbFormats,
    864                                                       &pEvent->cbFormats,
    865                                                       &pEvent->u.a.uDefAction);
     852                    rc = VERR_NO_MEMORY;
     853
     854                if (RT_SUCCESS(rc))
     855                    rc = vbglR3DnDGHProcessDroppedMessage(u32ClientId,
     856                                                          pEvent->pszFormats,
     857                                                          ccbFormats,
     858                                                          &pEvent->cbFormats,
     859                                                          &pEvent->u.a.uDefAction);
    866860                break;
    867861            }
    868862#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    869             case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
    870             {
    871                 pEvent->uType = uMsg;
    872                 rc = vbglR3DnDHGProcessCancelMessage(g_clientId);
    873                 if (RT_SUCCESS(rc))
    874                     rc = VERR_CANCELLED;
     863            default:
     864                AssertMsgFailedReturn(("Message %u isn't expected in this context", uMsg),
     865                                      VERR_INVALID_PARAMETER);
    875866                break;
    876             }
    877             default: AssertMsgFailedReturn(("Message %u isn't expected in this context", uMsg), VERR_INVALID_PARAMETER); break;
    878         }
    879     }
    880     return rc;
    881 }
    882 
    883 VBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t uAction)
    884 {
    885     DO(("ACK: %u\n", uAction));
    886     /* Initialize header */
     867        }
     868    }
     869
     870    return rc;
     871}
     872
     873VBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t u32ClientId, uint32_t uAction)
     874{
    887875    DragAndDropSvc::VBOXDNDHGACKOPMSG Msg;
    888876    RT_ZERO(Msg);
    889877    Msg.hdr.result      = VERR_WRONG_ORDER;
    890     Msg.hdr.u32ClientID = g_clientId;
     878    Msg.hdr.u32ClientID = u32ClientId;
    891879    Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_ACK_OP;
    892880    Msg.hdr.cParms      = 1;
     
    897885    if (RT_SUCCESS(rc))
    898886        rc = Msg.hdr.result;
    899     return rc;
    900 }
    901 
    902 VBGLR3DECL(int) VbglR3DnDHGRequestData(const char* pcszFormat)
    903 {
    904     DO(("DATA_REQ: '%s'\n", pcszFormat));
    905     /* Validate input */
     887
     888    return rc;
     889}
     890
     891VBGLR3DECL(int) VbglR3DnDHGRequestData(uint32_t u32ClientId, const char* pcszFormat)
     892{
    906893    AssertPtrReturn(pcszFormat, VERR_INVALID_PARAMETER);
    907894
    908     /* Initialize header */
    909895    DragAndDropSvc::VBOXDNDHGREQDATAMSG Msg;
    910896    RT_ZERO(Msg);
    911897    Msg.hdr.result      = VERR_WRONG_ORDER;
    912     Msg.hdr.u32ClientID = g_clientId;
     898    Msg.hdr.u32ClientID = u32ClientId;
    913899    Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_HG_REQ_DATA;
    914900    Msg.hdr.cParms      = 1;
     
    918904    if (RT_SUCCESS(rc))
    919905        rc = Msg.hdr.result;
    920     return rc;
    921 }
    922 
    923 VBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t uDefAction, uint32_t uAllActions, const char* pcszFormat)
    924 {
    925     DO(("PEND: %u: %u (%s)\n", uDefAction, uAllActions, pcszFormat));
    926     /* Validate input */
     906
     907    return rc;
     908}
     909
     910VBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId,
     911                                              uint32_t uDefAction, uint32_t uAllActions,
     912                                              const char* pcszFormat)
     913{
    927914    AssertPtrReturn(pcszFormat, VERR_INVALID_POINTER);
    928915
    929     /* Initialize header */
    930916    DragAndDropSvc::VBOXDNDGHACKPENDINGMSG Msg;
    931917    RT_ZERO(Msg);
    932918    Msg.hdr.result      = VERR_WRONG_ORDER;
    933     Msg.hdr.u32ClientID = g_clientId;
     919    Msg.hdr.u32ClientID = u32ClientId;
    934920    Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_ACK_PENDING;
    935921    Msg.hdr.cParms      = 3;
     
    942928    if (RT_SUCCESS(rc))
    943929        rc = Msg.hdr.result;
    944     return rc;
    945 }
    946 
    947 VBGLR3DECL(int) VbglR3DnDGHSendData(void *pvData, uint32_t cbData)
    948 {
    949     DO(("DATA: %x (%u)\n", pvData, cbData));
    950     /* Validate input */
     930
     931    return rc;
     932}
     933
     934VBGLR3DECL(int) VbglR3DnDGHSendData(uint32_t u32ClientId, void *pvData, uint32_t cbData)
     935{
    951936    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    952937    AssertReturn(cbData,    VERR_INVALID_PARAMETER);
     
    962947     */
    963948
    964     /* Initialize header */
    965949    DragAndDropSvc::VBOXDNDGHSENDDATAMSG Msg;
    966950    RT_ZERO(Msg);
    967951    Msg.hdr.result      = VERR_WRONG_ORDER;
    968     Msg.hdr.u32ClientID = g_clientId;
     952    Msg.hdr.u32ClientID = u32ClientId;
    969953    Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_SND_DATA;
    970954    Msg.hdr.cParms      = 2;
     
    992976//        RTThreadSleep(500);
    993977    }
    994     return rc;
    995 }
    996 
    997 VBGLR3DECL(int) VbglR3DnDGHErrorEvent(int rcOp)
    998 {
    999     DO(("GH_ERROR\n"));
    1000 
    1001     /* Initialize header */
     978
     979    return rc;
     980}
     981
     982VBGLR3DECL(int) VbglR3DnDGHErrorEvent(uint32_t u32ClientId, int rcOp)
     983{
    1002984    DragAndDropSvc::VBOXDNDGHEVTERRORMSG Msg;
    1003985    RT_ZERO(Msg);
    1004986    Msg.hdr.result      = VERR_WRONG_ORDER;
    1005     Msg.hdr.u32ClientID = g_clientId;
     987    Msg.hdr.u32ClientID = u32ClientId;
    1006988    Msg.hdr.u32Function = DragAndDropSvc::GUEST_DND_GH_EVT_ERROR;
    1007989    Msg.hdr.cParms      = 1;
     
    1012994    if (RT_SUCCESS(rc))
    1013995        rc = Msg.hdr.result;
    1014     return rc;
    1015 }
     996
     997    return rc;
     998}
  • trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp

    r49455 r49891  
    44
    55/*
    6  * Copyright (C) 2011-2012 Oracle Corporation
     6 * Copyright (C) 2011-2013 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5555 * G->H:
    5656 * This is a lot more trickery than H->G. When a pending event from HGCM
    57  * arrives, we asks if there is currently an owner of the XdndSelection
     57 * arrives, we ask if there currently is an owner of the XdndSelection
    5858 * property. If so, our proxy window is shown (1x1, but without backing store)
    5959 * and some mouse event is triggered. This should be followed by an XdndEnter
     
    6565 * Todo:
    6666 * - this isn't finished, yet. Currently the mouse isn't correctly released
    67  * in the guest (both, when the drop was successfully or canceled).
     67 *   in the guest (both, when the drop was successfully or canceled).
    6868 * - cancel (e.g. with the ESC key) doesn't work
    6969 *
     
    7474 * - really check for the Xdnd version and the supported features
    7575 */
    76 
    77 #define VERBOSE 1
    78 
    79 #if defined(VERBOSE) && defined(DEBUG_poetzsch)
    80 # include <iprt/stream.h>
    81 # define DO(s) RTPrintf s
    82 #else
    83 # define DO(s) do {} while (0)
    84 //# define DO(s) Log s
    85 #endif
    8676
    8777#define VBOX_XDND_VERSION    (4)
     
    154144public:
    155145
    156     static xHelpers *instance(Display *pDisplay = 0)
     146    static xHelpers *getInstance(Display *pDisplay = 0)
    157147    {
    158148        if (!m_pInstance)
    159149        {
    160             AssertPtrReturn(pDisplay, 0);
     150            AssertPtrReturn(pDisplay, NULL);
    161151            m_pInstance = new xHelpers(pDisplay);
    162152        }
     153
    163154        return m_pInstance;
    164155    }
     
    211202
    212203/* Some xHelpers convenience defines. */
    213 #define gX11 xHelpers::instance()
     204#define gX11 xHelpers::getInstance()
    214205#define xAtom(xa) gX11->xAtom((xa))
    215206#define xAtomToString(xa) gX11->xAtomToString((xa))
     
    285276
    286277/* Todo: make this iterative */
    287 Window xHelpers::applicationWindowBelowCursor(Window parentWin) const
     278Window xHelpers::applicationWindowBelowCursor(Window wndParent) const
    288279{
    289280    /* No parent, nothing to do. */
    290     if(parentWin == 0)
     281    if(wndParent == 0)
    291282        return 0;
    292283
    293     Window appWin = 0;
     284    Window wndApp = 0;
    294285    int cProps = -1;
    295286    /* Fetch all x11 window properties of the parent window. */
    296     Atom *pProps = XListProperties(m_pDisplay, parentWin, &cProps);
     287    Atom *pProps = XListProperties(m_pDisplay, wndParent, &cProps);
    297288    if (cProps > 0)
    298289    {
    299290        /* We check the window for the WM_STATE property. */
    300         for(int i = 0; i < cProps; ++i)
    301             if(pProps[i] == xAtom(XA_WM_STATE))
     291        for (int i = 0; i < cProps; ++i)
     292            if (pProps[i] == xAtom(XA_WM_STATE))
    302293            {
    303294                /* Found it. */
    304                 appWin = parentWin;
     295                wndApp = wndParent;
    305296                break;
    306297            }
     
    309300    }
    310301
    311     if (!appWin)
    312     {
    313         Window childWin, wtmp;
     302    if (!wndApp)
     303    {
     304        Window wndChild, wndTemp;
    314305        int tmp;
    315306        unsigned int utmp;
    316307        /* Query the next child window of the parent window at the current
    317308         * mouse position. */
    318         XQueryPointer(m_pDisplay, parentWin, &wtmp, &childWin, &tmp, &tmp, &tmp, &tmp, &utmp);
     309        XQueryPointer(m_pDisplay, wndParent, &wndTemp, &wndChild, &tmp, &tmp, &tmp, &tmp, &utmp);
    319310        /* Recursive call our self to dive into the child tree. */
    320         appWin = applicationWindowBelowCursor(childWin);
    321     }
    322 
    323     return appWin;
     311        wndApp = applicationWindowBelowCursor(wndChild);
     312    }
     313
     314    return wndApp;
    324315}
    325316
     
    390381
    391382    /* Member vars */
     383    uint32_t            m_uClientID;
    392384    DragAndDropService *m_pParent;
    393385    Display            *m_pDisplay;
    394386    int                 m_screenId;
    395387    Screen             *m_pScreen;
    396     Window              m_rootWin;
    397     Window              m_proxyWin;
    398     Window              m_curWin;
     388    Window              m_wndRoot;
     389    Window              m_wndProxy;
     390    Window              m_wndCur;
    399391    long                m_curVer;
    400392    RTCList<Atom>       m_formats;
     
    418410{
    419411public:
    420     DragAndDropService()
     412    DragAndDropService(void)
    421413      : m_pDisplay(0)
    422414      , m_hHGCMThread(NIL_RTTHREAD)
     
    433425    virtual int run(bool fDaemonised = false);
    434426
    435     virtual void cleanup()
     427    virtual void cleanup(void)
    436428    {
    437429        /* Cleanup */
    438430        x11DragAndDropTerm();
    439         VbglR3DnDTerm();
    440431    };
    441432
    442433private:
    443     int x11DragAndDropInit();
    444     int x11DragAndDropTerm();
     434    int x11DragAndDropInit(void);
     435    int x11DragAndDropTerm(void);
    445436    static int hgcmEventThread(RTTHREAD hThread, void *pvUser);
    446437    static int x11EventThread(RTTHREAD hThread, void *pvUser);
     
    451442     * Unfortunately this doesn't work exactly with the events we need. So we
    452443     * use this predicate method below and XCheckIfEvent. */
    453     static Bool isDnDRespondEvent(Display * /* pDisplay */, XEvent *pEvent, char *pUser)
     444    static bool isDnDRespondEvent(Display * /* pDisplay */, XEvent *pEvent, char *pUser)
    454445    {
    455446        if (!pEvent)
    456             return False;
     447            return false;
    457448        if (   pEvent->type == SelectionClear
    458449            || pEvent->type == ClientMessage
     
    463454//            || (   pEvent->type == SelectionRequest
    464455//                && reinterpret_cast<XSelectionRequestEvent*>(pEvent)->requestor == reinterpret_cast<Window>(pUser)))
    465             return True;
    466         return False;
     456            return true;
     457        return false;
    467458    }
    468459
     
    487478
    488479DragInstance::DragInstance(Display *pDisplay, DragAndDropService *pParent)
    489   : m_pParent(pParent)
     480  : m_uClientID(0)
     481  , m_pParent(pParent)
    490482  , m_pDisplay(pDisplay)
    491483  , m_pScreen(0)
    492   , m_rootWin(0)
    493   , m_proxyWin(0)
    494   , m_curWin(0)
     484  , m_wndRoot(0)
     485  , m_wndProxy(0)
     486  , m_wndCur(0)
    495487  , m_curVer(-1)
    496488  , m_mode(Unknown)
     
    500492}
    501493
    502 void DragInstance::uninit()
     494void DragInstance::uninit(void)
    503495{
    504496    reset();
    505     if (m_proxyWin != 0)
    506         XDestroyWindow(m_pDisplay, m_proxyWin);
     497    if (m_wndProxy != 0)
     498        XDestroyWindow(m_pDisplay, m_wndProxy);
     499
     500    if (m_uClientID)
     501    {
     502        VbglR3DnDDisconnect(m_uClientID);
     503        m_uClientID = 0;
     504    }
     505
    507506    m_state    = Uninitialized;
    508507    m_screenId = -1;
    509508    m_pScreen  = 0;
    510     m_rootWin  = 0;
    511     m_proxyWin = 0;
    512 }
    513 
    514 void DragInstance::reset()
     509    m_wndRoot  = 0;
     510    m_wndProxy = 0;
     511}
     512
     513void DragInstance::reset(void)
    515514{
    516515    /* Hide the proxy win. */
     
    518517    /* If we are currently the Xdnd selection owner, clear that. */
    519518    Window w = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));
    520     if (w == m_proxyWin)
     519    if (w == m_wndProxy)
    521520        XSetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection), None, CurrentTime);
    522521    /* Clear any other DnD specific data on the proxy win. */
    523     clearFormatsWindowProperty(m_proxyWin);
    524     clearActionsWindowProperty(m_proxyWin);
     522    clearFormatsWindowProperty(m_wndProxy);
     523    clearActionsWindowProperty(m_wndProxy);
    525524    /* Reset the internal state. */
    526525    m_formats.clear();
    527     m_curWin = 0;
     526    m_wndCur = 0;
    528527    m_curVer = -1;
    529528    m_state  = Initialized;
     
    546545int DragInstance::init(uint32_t u32ScreenId)
    547546{
    548     int rc = VINF_SUCCESS;
     547    int rc;
     548
    549549    do
    550550    {
    551551        uninit();
    552         /* Enough screens configured in the x11 server? */
     552
     553        rc = VbglR3DnDConnect(&m_uClientID);
     554        if (RT_FAILURE(rc))
     555            break;
     556
     557        /*
     558         * Enough screens configured in the x11 server?
     559         */
    553560        if ((int)u32ScreenId > ScreenCount(m_pDisplay))
    554561        {
    555             rc = VERR_GENERAL_FAILURE;
     562            rc = VERR_INVALID_PARAMETER;
    556563            break;
    557564        }
     
    565572        m_screenId = u32ScreenId;
    566573        /* Now query the corresponding root window of this screen. */
    567         m_rootWin = RootWindow(m_pDisplay, m_screenId);
    568         if (!m_rootWin)
     574        m_wndRoot = RootWindow(m_pDisplay, m_screenId);
     575        if (!m_wndRoot)
    569576        {
    570577            rc = VERR_GENERAL_FAILURE;
    571578            break;
    572579        }
    573         /* Create an invisible window which will act as proxy for the DnD
     580
     581        /*
     582         * Create an invisible window which will act as proxy for the DnD
    574583         * operation. This window will be used for both the GH and HG
    575          * direction. */
     584         * direction.
     585         */
    576586        XSetWindowAttributes attr;
    577587        RT_ZERO(attr);
    578588        attr.do_not_propagate_mask = 0;
    579589        attr.override_redirect     = True;
    580 //        attr.background_pixel      = WhitePixel(m_pDisplay, m_screenId);
    581         m_proxyWin = XCreateWindow(m_pDisplay, m_rootWin, 0, 0, 1, 1, 0,
     590#if 0
     591        attr.background_pixel      = WhitePixel(m_pDisplay, m_screenId);
     592#endif
     593        m_wndProxy = XCreateWindow(m_pDisplay, m_wndRoot, 0, 0, 1, 1, 0,
    582594                                   CopyFromParent, InputOnly, CopyFromParent,
    583595                                   CWOverrideRedirect | CWDontPropagate,
    584596                                   &attr);
    585 
    586 //        m_proxyWin = XCreateSimpleWindow(m_pDisplay, m_rootWin, 0, 0, 50, 50, 0, WhitePixel(m_pDisplay, m_screenId), WhitePixel(m_pDisplay, m_screenId));
    587 
    588         if (!m_proxyWin)
     597#ifdef DEBUG_andy
     598        m_wndProxy = XCreateSimpleWindow(m_pDisplay, m_wndRoot, 0, 0, 50, 50, 0,
     599                                         WhitePixel(m_pDisplay, m_screenId),
     600                                         WhitePixel(m_pDisplay, m_screenId));
     601#endif
     602        if (!m_wndProxy)
    589603        {
    590604            rc = VERR_GENERAL_FAILURE;
    591605            break;
    592606        }
     607
    593608        /* Make the new window Xdnd aware. */
    594609        Atom ver = VBOX_XDND_VERSION;
    595         XChangeProperty(m_pDisplay, m_proxyWin, xAtom(XA_XdndAware), XA_ATOM, 32, PropModeReplace,
     610        XChangeProperty(m_pDisplay, m_wndProxy, xAtom(XA_XdndAware), XA_ATOM, 32, PropModeReplace,
    596611                        reinterpret_cast<unsigned char*>(&ver), 1);
    597612    } while (0);
    598613
    599     m_state = Initialized;
    600 
     614    if (RT_SUCCESS(rc))
     615        m_state = Initialized;
     616
     617    LogFlowFuncLeaveRC(rc);
    601618    return rc;
    602619}
     
    606623 */
    607624
    608 int DragInstance::hgEnter(const RTCList<RTCString> &formats, uint32_t actions)
    609 {
    610     int rc = VINF_SUCCESS;
    611 
     625int DragInstance::hgEnter(const RTCList<RTCString> &formats, uint32_t uActions)
     626{
    612627    reset();
    613     DO(("DnD_ENTR: formats=%u: ", formats.size()));
    614 #if defined(VERBOSE) && defined(DEBUG_poetzsch)
     628
     629#ifdef DEBUG
     630    LogFlowThisFunc(("uActions=0x%x, lstFormats=%zu: ", uActions, formats.size()));
    615631    for (size_t i = 0; i < formats.size(); ++i)
    616         DO(("'%s' ", formats.at(i).c_str()));
    617 #endif /* DEBUG */
    618     DO(("\n"));
     632        LogFlow(("'%s' ", formats.at(i).c_str()));
     633    LogFlow(("\n"));
     634#endif
    619635
    620636    m_formats = toAtomList(formats);
     
    622638    /* If we have more than 3 formats we have to use the type list extension. */
    623639    if (m_formats.size() > 3)
    624         setFormatsWindowProperty(m_proxyWin, xAtom(XA_XdndTypeList));
     640        setFormatsWindowProperty(m_wndProxy, xAtom(XA_XdndTypeList));
    625641
    626642    /* Announce the possible actions */
    627     setActionsWindowProperty(m_proxyWin, toX11Actions(actions));
     643    setActionsWindowProperty(m_wndProxy, toX11Actions(uActions));
    628644
    629645    /* Set the DnD selection owner to our window. */
    630     XSetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection), m_proxyWin, CurrentTime);
     646    XSetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection), m_wndProxy, CurrentTime);
    631647
    632648    m_mode  = HG;
    633649    m_state = Dragging;
    634650
    635     return rc;
    636 }
    637 
    638 int DragInstance::hgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t action)
    639 {
    640     DO(("DnD_MOVE: "));
     651    return VINF_SUCCESS;
     652}
     653
     654int DragInstance::hgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction)
     655{
     656    LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=%RU32\n",
     657                     u32xPos, u32yPos, uAction));
    641658
    642659    if (   m_mode  != HG
     
    650667    moveCursor(u32xPos, u32yPos);
    651668
    652     Window newWin = None; /* Default to _no_ window below the cursor. */
    653     long   newVer = -1;   /* This means the current window is _not_ XdndAware. */
     669    long newVer = -1; /* This means the current window is _not_ XdndAware. */
    654670
    655671    /* Search for the application window below the cursor. */
    656     newWin = gX11->applicationWindowBelowCursor(m_rootWin);
    657     if (newWin != None)
     672    Window wndCursor = gX11->applicationWindowBelowCursor(m_wndRoot);
     673    if (wndCursor != None)
    658674    {
    659675        /* Temp stuff for the XGetWindowProperty call. */
     
    662678        unsigned long cItems, cbRemaining;
    663679        unsigned char *pcData = NULL;
     680
    664681        /* Query the XdndAware property from the window. We are interested in
    665682         * the version and if it is XdndAware at all. */
    666         xrc = XGetWindowProperty(m_pDisplay, newWin, xAtom(XA_XdndAware), 0, 2, False, AnyPropertyType, &atmp, &fmt, &cItems, &cbRemaining, &pcData);
     683        xrc = XGetWindowProperty(m_pDisplay, wndCursor, xAtom(XA_XdndAware),
     684                                 0, 2, False, AnyPropertyType,
     685                                 &atmp, &fmt, &cItems, &cbRemaining, &pcData);
    667686        if (RT_UNLIKELY(xrc != Success))
    668             DO(("DnD_MOVE: error in getting the window property (%s)\n", gX11->xErrorToString(xrc).c_str()));
     687            LogFlowThisFunc(("Error in getting the window property: %s\n", gX11->xErrorToString(xrc).c_str()));
    669688        else
    670689        {
    671690            if (RT_UNLIKELY(pcData == NULL || fmt != 32 || cItems != 1))
    672                 DO(("Prop=error[data=%#x,fmt=%u,items=%u] ", pcData, fmt, cItems));
     691                LogFlowThisFunc(("Wrong properties pcData=%#x, iFmt=%u, cItems=%u\n", pcData, fmt, cItems));
    673692            else
    674693            {
    675694                newVer = reinterpret_cast<long*>(pcData)[0];
    676                 DO(("XdndAware=%u ", newVer));
     695                LogFlowThisFunc(("wndCursor=%#x, XdndAware=%u\n", newVer));
    677696            }
    678697            XFree(pcData);
     
    680699    }
    681700
    682     if (newWin != m_curWin && m_curVer != -1)
    683     {
    684         DO(("leave=%#x ", m_curWin));
     701    /*
     702     * Is the window under the cursor another one than our current one?
     703     */
     704    if (wndCursor != m_wndCur && m_curVer != -1)
     705    {
     706        LogFlowThisFunc(("Leaving window=%#x\n", m_wndCur));
    685707
    686708        /* We left the current XdndAware window. Announce this to the window. */
    687 
    688709        XClientMessageEvent m;
    689710        RT_ZERO(m);
    690711        m.type         = ClientMessage;
    691712        m.display      = m_pDisplay;
    692         m.window       = m_curWin;
     713        m.window       = m_wndCur;
    693714        m.message_type = xAtom(XA_XdndLeave);
    694715        m.format       = 32;
    695         m.data.l[0]    = m_proxyWin;
    696 
    697         xrc = XSendEvent(m_pDisplay, m_curWin, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
     716        m.data.l[0]    = m_wndProxy;
     717
     718        xrc = XSendEvent(m_pDisplay, m_wndCur, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    698719        if (RT_UNLIKELY(xrc == 0))
    699             DO(("DnD_MOVE: error sending xevent\n"));
    700     }
    701 
    702     if (newWin != m_curWin && newVer != -1)
    703     {
    704         DO(("enter=%#x ", newWin));
    705 
    706         /* We enter a new window. Announce the XdndEnter event to the new
     720            LogFlowThisFunc(("Error sending XA_XdndLeave to old window=%#x\n", m_wndCur));
     721    }
     722
     723    /*
     724     * Do we have a new window which now is under the cursor?
     725     */
     726    if (wndCursor != m_wndCur && newVer != -1)
     727    {
     728        LogFlowThisFunc(("Entering window=%#x\n", wndCursor));
     729
     730        /*
     731         * We enter a new window. Announce the XdndEnter event to the new
    707732         * window. The first three mime types are attached to the event (the
    708733         * others could be requested by the XdndTypeList property from the
    709          * window itself). */
    710 
     734         * window itself).
     735         */
    711736        XClientMessageEvent m;
    712737        RT_ZERO(m);
    713738        m.type         = ClientMessage;
    714739        m.display      = m_pDisplay;
    715         m.window       = newWin;
     740        m.window       = wndCursor;
    716741        m.message_type = xAtom(XA_XdndEnter);
    717742        m.format       = 32;
    718         m.data.l[0]    = m_proxyWin;
     743        m.data.l[0]    = m_wndProxy;
    719744        m.data.l[1]    = RT_MAKE_U32_FROM_U8(m_formats.size() > 3 ? 1 : 0, 0, 0, RT_MIN(VBOX_XDND_VERSION, newVer));
    720745        m.data.l[2]    = m_formats.value(0, None);
     
    722747        m.data.l[4]    = m_formats.value(2, None);
    723748
    724         xrc = XSendEvent(m_pDisplay, newWin, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
     749        xrc = XSendEvent(m_pDisplay, wndCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    725750        if (RT_UNLIKELY(xrc == 0))
    726             DO(("DnD_MOVE: error sending xevent\n"));
     751            LogFlowThisFunc(("Error sending XA_XdndEnter to new window=%#x\n", wndCursor));
    727752    }
    728753
    729754    if (newVer != -1)
    730755    {
    731         DO(("move=%#x pos=%ux%u ", newWin, u32xPos, u32yPos));
    732 
    733         /* Send a XdndPosition event with the proposed action to the guest. */
    734 
    735         Atom pa = toX11Action(action);
    736         DO(("action='%s' ", xAtomToString(pa).c_str()));
     756        LogFlowThisFunc(("Moving window=%#x, xPos=%RU32, yPos=%RU32\n",
     757                         wndCursor, u32xPos, u32yPos));
     758
     759        /*
     760         * Send a XdndPosition event with the proposed action to the guest.
     761         */
     762        Atom pa = toX11Action(uAction);
     763        LogFlowThisFunc(("strAction='%s' ", xAtomToString(pa).c_str()));
    737764
    738765        XClientMessageEvent m;
     
    740767        m.type         = ClientMessage;
    741768        m.display      = m_pDisplay;
    742         m.window       = newWin;
     769        m.window       = wndCursor;
    743770        m.message_type = xAtom(XA_XdndPosition);
    744771        m.format       = 32;
    745         m.data.l[0]    = m_proxyWin;
     772        m.data.l[0]    = m_wndProxy;
    746773        m.data.l[2]    = RT_MAKE_U32(u32yPos, u32xPos);
    747774        m.data.l[3]    = CurrentTime;
    748775        m.data.l[4]    = pa;
    749776
    750         xrc = XSendEvent(m_pDisplay, newWin, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
     777        xrc = XSendEvent(m_pDisplay, wndCursor, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    751778        if (RT_UNLIKELY(xrc == 0))
    752             DO(("DnD_MOVE: error sending xevent\n"));
    753     }
    754     if (newWin == None && newVer == -1)
     779            LogFlowThisFunc(("Error sending XA_XdndPosition to window=%#x\n", wndCursor));
     780    }
     781
     782    if (wndCursor == None && newVer == -1)
     783    {
    755784        /* No window to process, so send a ignore ack event to the host. */
    756         rc = VbglR3DnDHGAcknowledgeOperation(DND_IGNORE_ACTION);
    757 
    758     m_curWin = newWin;
     785        rc = VbglR3DnDHGAcknowledgeOperation(m_uClientID, DND_IGNORE_ACTION);
     786    }
     787
     788    m_wndCur = wndCursor;
    759789    m_curVer = RT_MIN(VBOX_XDND_VERSION, newVer);
    760790
    761     DO(("\n"));
    762 
     791    LogFlowFuncLeaveRC(rc);
    763792    return rc;
    764793}
     
    774803    int rc = VINF_SUCCESS;
    775804    if (   e.xclient.message_type == xAtom(XA_XdndStatus)
    776         && m_curWin               == static_cast<Window>(e.xclient.data.l[0]))
     805        && m_wndCur               == static_cast<Window>(e.xclient.data.l[0]))
    777806    {
    778807        /* The XdndStatus message tell us if the window will accept the DnD
    779808         * event and with which action. We immediately send this info down to
    780809         * the host as a response of a previous DnD message. */
    781         DO(("DnD_STAT: win=%#x,accept=%RTbool,action='%s'\n",
    782             e.xclient.data.l[0],
    783             ASMBitTest(&e.xclient.data.l[1], 0),
    784             xAtomToString(e.xclient.data.l[4]).c_str()));
     810        LogFlowThisFunc(("XA_XdndStatus wnd=%#x, accept=%RTbool, action='%s'\n",
     811                         e.xclient.data.l[0],
     812                         ASMBitTest(&e.xclient.data.l[1], 0),
     813                         xAtomToString(e.xclient.data.l[4]).c_str()));
     814
    785815        uint32_t uAction = DND_IGNORE_ACTION;
    786         /* Todo: compare this with the allowed actions. */
     816        /** @todo Compare this with the allowed actions. */
    787817        if (ASMBitTest(&e.xclient.data.l[1], 0))
    788818            uAction = toHGCMAction(static_cast<Atom>(e.xclient.data.l[4]));
    789         rc = VbglR3DnDHGAcknowledgeOperation(uAction);
     819
     820        rc = VbglR3DnDHGAcknowledgeOperation(m_uClientID, uAction);
    790821    }
    791822    else if (e.xclient.message_type == xAtom(XA_XdndFinished))
    792823    {
    793824        /* This message is send on a un/successful DnD drop request. */
    794         DO(("DnD_FINI: win=%#x,success=%RTbool,action='%s'\n",
     825        LogFlowThisFunc(("XA_XdndFinished: wnd=%#x, success=%RTbool, action='%s'\n",
    795826            e.xclient.data.l[0],
    796827            ASMBitTest(&e.xclient.data.l[1], 0),
    797828            xAtomToString(e.xclient.data.l[2]).c_str()));
     829
    798830        reset();
    799831    }
    800832    else
    801         DO(("DnD_CLI: win=%#x,msg='%s'\n", e.xclient.data.l[0], xAtomToString(e.xclient.message_type).c_str()));
     833        LogFlowThisFunc(("Unhandled: wnd=%#x, msg='%s'\n",
     834                         e.xclient.data.l[0], xAtomToString(e.xclient.message_type).c_str()));
     835
     836    LogFlowFuncLeaveRC(rc);
    802837    return rc;
    803838}
    804839
    805 int DragInstance::hgDrop()
    806 {
    807     DO(("DnD_DROP: win=%#x\n", m_curWin));
     840int DragInstance::hgDrop(void)
     841{
     842    LogFlowThisFunc(("wndCur=%#x, mMode=%RU32, mState=%RU32\n",
     843                     m_wndCur, m_mode, m_state));
    808844
    809845    if (   m_mode  != HG
     
    818854    m.type         = ClientMessage;
    819855    m.display      = m_pDisplay;
    820     m.window       = m_curWin;
     856    m.window       = m_wndCur;
    821857    m.message_type = xAtom(XA_XdndDrop);
    822858    m.format       = 32;
    823     m.data.l[0]    = m_proxyWin;
     859    m.data.l[0]    = m_wndProxy;
    824860    m.data.l[2]    = CurrentTime;
    825861
    826     int xrc = XSendEvent(m_pDisplay, m_curWin, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
     862    int xrc = XSendEvent(m_pDisplay, m_wndCur, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    827863    if (RT_UNLIKELY(xrc == 0))
    828         DO(("DnD_DROP: error sending xevent\n"));
    829 
    830     m_curWin = None;
     864        LogFlowThisFunc(("Error sending XA_XdndDrop to window=%#x\n", m_wndCur));
     865
     866    m_wndCur = None;
    831867    m_curVer = -1;
    832868
    833869    m_state = Dropped;
    834870
     871    LogFlowFuncLeaveRC(rc);
    835872    return rc;
    836873}
     
    844881        return VERR_INVALID_STATE;
    845882
    846     DO(("DnD_SELR: owner=%#x,requestor=%#x,sel_atom='%s',tar_atom='%s',prop_atom='%s',time=%u\n",
    847         e.xselectionrequest.owner,
    848         e.xselectionrequest.requestor,
    849         xAtomToString(e.xselectionrequest.selection).c_str(),
    850         xAtomToString(e.xselectionrequest.target).c_str(),
    851         xAtomToString(e.xselectionrequest.property).c_str(),
    852         e.xselectionrequest.time));
     883    LogFlowThisFunc(("owner=%#x, requestor=%#x, sel_atom='%s', tar_atom='%s', prop_atom='%s', time=%u\n",
     884                     e.xselectionrequest.owner,
     885                     e.xselectionrequest.requestor,
     886                     xAtomToString(e.xselectionrequest.selection).c_str(),
     887                     xAtomToString(e.xselectionrequest.target).c_str(),
     888                     xAtomToString(e.xselectionrequest.property).c_str(),
     889                     e.xselectionrequest.time));
    853890
    854891    int rc = VINF_SUCCESS;
    855892
    856     /* A window is asking for some data. Normally here the data would be copied
     893    /*
     894     * A window is asking for some data. Normally here the data would be copied
    857895     * into the selection buffer and send to the requestor. Obviously we can't
    858896     * do that, cause we first need to ask the host for the data of the
    859897     * requested mime type. This is done and later answered with the correct
    860      * data (s. dataReceived). */
     898     * data (s. dataReceived).
     899     */
    861900
    862901    /* Is the requestor asking for the possible mime types? */
    863902    if(e.xselectionrequest.target == xAtom(XA_TARGETS))
    864903    {
    865         DO(("DnD_SELR: ask for target list\n"));
     904        LogFlowThisFunc(("wnd=%#x asking for target list\n", e.xselectionrequest.requestor));
     905
    866906        /* If so, set the window property with the formats on the requestor
    867907         * window. */
    868908        setFormatsWindowProperty(e.xselectionrequest.requestor, e.xselectionrequest.property);
     909
    869910        XEvent s;
    870911        RT_ZERO(s);
     
    876917        s.xselection.target    = e.xselectionrequest.target;
    877918        s.xselection.property  = e.xselectionrequest.property;
     919
    878920        int xrc = XSendEvent(e.xselection.display, e.xselectionrequest.requestor, False, 0, &s);
    879921        if (RT_UNLIKELY(xrc == 0))
    880             DO(("DnD_SELR: error sending xevent\n"));
     922            LogFlowThisFunc(("Error sending SelectionNotify event to wnd=%#x\n", e.xselectionrequest.requestor));
    881923    }
    882924    /* Is the requestor asking for a specific mime type (we support)? */
    883925    else if(m_formats.contains(e.xselectionrequest.target))
    884926    {
    885         DO(("DnD_SELR: ask for data (format='%s')\n", xAtomToString(e.xselectionrequest.target).c_str()));
     927        LogFlowThisFunc(("wnd=%#x asking for data (format='%s')\n",
     928                         e.xselectionrequest.requestor, xAtomToString(e.xselectionrequest.target).c_str()));
     929
    886930        /* If so, we need to inform the host about this request. Save the
    887931         * selection request event for later use. */
     
    889933            //        || m_curWin != e.xselectionrequest.requestor)
    890934        {
    891             DO(("DnD_SELR: refuse\n"));
     935            LogFlowThisFunc(("Refusing ...\n"));
     936
    892937            XEvent s;
    893938            RT_ZERO(s);
     
    899944            s.xselection.target    = None;
    900945            s.xselection.property  = e.xselectionrequest.property;
     946
    901947            int xrc = XSendEvent(e.xselection.display, e.xselectionrequest.requestor, False, 0, &s);
    902948            if (RT_UNLIKELY(xrc == 0))
    903                 DO(("DnD_SELR: error sending xevent\n"));
     949                LogFlowThisFunc(("Error sending SelectionNotify event to wnd=%#x\n", e.xselectionrequest.requestor));
    904950        }
    905951        else
    906952        {
     953            LogFlowThisFunc(("Copying data from host ...\n"));
     954
    907955            memcpy(&m_selEvent, &e, sizeof(XEvent));
    908             rc = VbglR3DnDHGRequestData(xAtomToString(e.xselectionrequest.target).c_str());
     956            rc = VbglR3DnDHGRequestData(m_uClientID, xAtomToString(e.xselectionrequest.target).c_str());
    909957        }
    910958    }
     
    912960    else
    913961    {
    914         DO(("DnD_SELR: refuse\n"));
     962        LogFlowThisFunc(("Refusing unknown command\n"));
     963
    915964        /* We don't understand this request message and therefore answer with an
    916965         * refusal messages. */
     
    926975        int xrc = XSendEvent(e.xselection.display, e.xselectionrequest.requestor, False, 0, &s);
    927976        if (RT_UNLIKELY(xrc == 0))
    928             DO(("DnD_SELR: error sending xevent\n"));
    929     }
    930 
     977            LogFlowThisFunc(("Error sending SelectionNotify event to wnd=%#x\n", e.xselectionrequest.requestor));
     978    }
     979
     980    LogFlowFuncLeaveRC(rc);
    931981    return rc;
    932982}
     
    9511001    memcpy(pvNewData, pvData, cData);
    9521002
    953     /* The host send us the DnD data in the requested mime type. This allows us
     1003    /*
     1004     * The host send us the DnD data in the requested mime type. This allows us
    9541005     * to fill the XdndSelection property of the requestor window with the data
    955      * and afterwards inform him about the new status. */
     1006     * and afterwards inform him about the new status.
     1007     */
    9561008    XEvent s;
    9571009    RT_ZERO(s);
     
    9651017    s.xselection.property  = m_selEvent.xselectionrequest.property;
    9661018
    967     DO(("DnD_SEND: owner=%#x,requestor=%#x,sel_atom='%s',tar_atom='%s',prop_atom='%s',time=%u\n",
    968         m_selEvent.xselectionrequest.owner,
    969         s.xselection.requestor,
    970         xAtomToString(s.xselection.selection).c_str(),
    971         xAtomToString(s.xselection.target).c_str(),
    972         xAtomToString(s.xselection.property).c_str(),
    973         s.xselection.time));
     1019    LogFlowThisFunc(("owner=%#x,requestor=%#x,sel_atom='%s',tar_atom='%s',prop_atom='%s',time=%u\n",
     1020                     m_selEvent.xselectionrequest.owner,
     1021                     s.xselection.requestor,
     1022                     xAtomToString(s.xselection.selection).c_str(),
     1023                     xAtomToString(s.xselection.target).c_str(),
     1024                     xAtomToString(s.xselection.property).c_str(),
     1025                     s.xselection.time));
    9741026
    9751027    /* Fill up the property with the data. */
     
    9781030    int xrc = XSendEvent(s.xselection.display, s.xselection.requestor, True, 0, &s);
    9791031    if (RT_UNLIKELY(xrc == 0))
    980         DO(("DnD_SEND: error sending xevent\n"));
     1032        LogFlowThisFunc(("Error sending SelectionNotify event to wnd=%#x\n", s.xselection.requestor));
    9811033
    9821034    return VINF_SUCCESS;
     
    9891041 */
    9901042
    991 int DragInstance::ghIsDnDPending()
     1043int DragInstance::ghIsDnDPending(void)
    9921044{
    9931045    int rc = VINF_SUCCESS;
    994     Window w = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));
    995     DO(("Checking pending %X %X\n", w, m_proxyWin));
     1046    Window wndOwner = XGetSelectionOwner(m_pDisplay, xAtom(XA_XdndSelection));
     1047    LogFlowThisFunc(("Checking pending wndOwner=%#x wndProxy=%#x\n", wndOwner, m_wndProxy));
     1048
    9961049    /* Is there someone own the Xdnd selection which aren't we. */
    997     if (   w
    998         && w != m_proxyWin)
     1050    if (   wndOwner
     1051        && wndOwner != m_wndProxy)
    9991052    {
    10001053        /* Map the window on the current cursor position, which should provoke
     
    10071060            int xrc = Success;
    10081061            XClientMessageEvent *clme = reinterpret_cast<XClientMessageEvent*>(&e);
    1009             DO(("next X event %s\n", gX11->xAtomToString(clme->message_type).c_str()));
     1062            LogFlowThisFunc(("Next X event %s\n", gX11->xAtomToString(clme->message_type).c_str()));
    10101063            if (clme->message_type == xAtom(XA_XdndEnter))
    10111064            {
     
    10181071                m_formats.clear();
    10191072                m_actions.clear();
    1020                 m_curWin = w;
    1021                 DO(("XA_XdndEnter\n"));
     1073                m_wndCur = wndOwner;
     1074                LogFlowThisFunc(("XA_XdndEnter\n"));
    10221075                /* Check if the mime types are in the msg itself or if we need
    10231076                 * to fetch the XdndTypeList property from the window. */
     
    10261079                    for (int i = 2; i < 5; ++i)
    10271080                    {
    1028                         DO(("receive list msg: %s\n", gX11->xAtomToString(clme->data.l[i]).c_str()));
     1081                        LogFlowThisFunc(("Receive list msg: %s\n", gX11->xAtomToString(clme->data.l[i]).c_str()));
    10291082                        m_formats.append(clme->data.l[i]);
    10301083                    }
     
    10321085                else
    10331086                {
    1034                     xrc = XGetWindowProperty(m_pDisplay, w, xAtom(XA_XdndTypeList), 0, VBOX_MAX_XPROPERTIES, False, XA_ATOM, &type, &f, &n, &a, &ret);
     1087                    xrc = XGetWindowProperty(m_pDisplay, wndOwner, xAtom(XA_XdndTypeList), 0, VBOX_MAX_XPROPERTIES, False, XA_ATOM, &type, &f, &n, &a, &ret);
    10351088                    if (   xrc == Success
    10361089                        && n > 0
     
    10401093                        for (int i = 0; i < RT_MIN(VBOX_MAX_XPROPERTIES, n); ++i)
    10411094                        {
    1042                             DO(("receive list: %s\n", gX11->xAtomToString(data[i]).c_str()));
     1095                            LogFlowThisFunc(("Receive list: %s\n", gX11->xAtomToString(data[i]).c_str()));
    10431096                            m_formats.append(data[i]);
    10441097                        }
     
    10471100                }
    10481101                /* Fetch the possible list of actions, if this property is set. */
    1049                 xrc = XGetWindowProperty(m_pDisplay, w, xAtom(XA_XdndActionList), 0, VBOX_MAX_XPROPERTIES, False, XA_ATOM, &type, &f, &n, &a, &ret);
     1102                xrc = XGetWindowProperty(m_pDisplay, wndOwner, xAtom(XA_XdndActionList), 0, VBOX_MAX_XPROPERTIES, False, XA_ATOM, &type, &f, &n, &a, &ret);
    10501103                if (   xrc == Success
    10511104                    && n > 0
     
    10551108                    for (int i = 0; i < RT_MIN(VBOX_MAX_XPROPERTIES, n); ++i)
    10561109                    {
    1057                         DO(("receive actions: %s\n", gX11->xAtomToString(data[i]).c_str()));
     1110                        LogFlowThisFunc(("Receive actions: %s\n", gX11->xAtomToString(data[i]).c_str()));
    10581111                        m_actions.append(data[i]);
    10591112                    }
     
    10721125                m.message_type = xAtom(XA_XdndStatus);
    10731126                m.format       = 32;
    1074                 m.data.l[0]    = m_proxyWin;
     1127                m.data.l[0]    = m_wndProxy;
    10751128                m.data.l[1]    = 1;
    10761129                m.data.l[4]    = xAtom(XA_XdndActionCopy);
    10771130                xrc = XSendEvent(m_pDisplay, clme->data.l[0], False, 0, reinterpret_cast<XEvent*>(&m));
    10781131                if (RT_UNLIKELY(xrc == 0))
    1079                     DO(("DnD_PNDG: error sending xevent\n"));
     1132                    LogFlowThisFunc(("Error sending xevent\n"));
    10801133            }
    10811134            else if (clme->message_type == xAtom(XA_XdndPosition))
    10821135            {
    1083                 DO(("XA_XdndPosition\n"));
     1136                LogFlowThisFunc(("XA_XdndPosition\n"));
    10841137                XClientMessageEvent m;
    10851138                RT_ZERO(m);
     
    10891142                m.message_type = xAtom(XA_XdndStatus);
    10901143                m.format       = 32;
    1091                 m.data.l[0]    = m_proxyWin;
     1144                m.data.l[0]    = m_wndProxy;
    10921145                m.data.l[1]    = 1;
    10931146                m.data.l[4]    = clme->data.l[4];
    10941147                xrc = XSendEvent(m_pDisplay, clme->data.l[0], False, 0, reinterpret_cast<XEvent*>(&m));
    10951148                if (RT_UNLIKELY(xrc == 0))
    1096                     DO(("DnD_PNDG: error sending xevent\n"));
     1149                    LogFlowThisFunc(("Error sending xevent\n"));
    10971150            }
    10981151            else if (clme->message_type == xAtom(XA_XdndLeave))
     
    11021155        hideProxyWin();
    11031156
    1104         rc = VbglR3DnDGHAcknowledgePending(DND_COPY_ACTION, toHGCMActions(m_actions), gX11->xAtomListToString(m_formats).c_str());
    1105     }
     1157        rc = VbglR3DnDGHAcknowledgePending(DND_COPY_ACTION, toHGCMActions(m_actions),
     1158                                           gX11->xAtomListToString(m_formats).c_str());
     1159    }
     1160
     1161    LogFlowFuncLeaveRC(rc);
    11061162    return rc;
    11071163}
     
    11091165int DragInstance::ghDropped(const RTCString &strFormat, uint32_t action)
    11101166{
    1111     DO(("DND_DRO: format='%s' action=%d\n", strFormat.c_str(), action));
     1167    LogFlowThisFunc(("format='%s' action=%d\n", strFormat.c_str(), action));
    11121168    int rc = VINF_SUCCESS;
    11131169
     
    11181174    /* We send a fake release event to the current window, cause
    11191175     * this should have the grab. */
    1120     sendButtonEvent(m_curWin, rx, ry, 1, false);
     1176    sendButtonEvent(m_wndCur, rx, ry, 1, false);
    11211177    /* The fake button release event, should lead to an XdndDrop event from the
    11221178     * source. Because of the showing of the proxy window, sometimes other Xdnd
     
    11451201            /* Request to convert the selection in the specific format and
    11461202             * place it to our proxy window as property. */
    1147             Window srcWin = m_curWin;//clme->data.l[0];
     1203            Window srcWin = m_wndCur;//clme->data.l[0];
    11481204            Atom aFormat  = gX11->stringToxAtom(strFormat.c_str());
    1149             XConvertSelection(m_pDisplay, xAtom(XA_XdndSelection), aFormat, xAtom(XA_XdndSelection), m_proxyWin, clme->data.l[2]);
     1205            XConvertSelection(m_pDisplay, xAtom(XA_XdndSelection), aFormat, xAtom(XA_XdndSelection), m_wndProxy, clme->data.l[2]);
    11501206            /* Wait for the selection notify event. */
    11511207            RT_ZERO(e);
     
    11561212                    && e.xselection.display   == m_pDisplay
    11571213                    && e.xselection.selection == xAtom(XA_XdndSelection)
    1158                     && e.xselection.requestor == m_proxyWin
     1214                    && e.xselection.requestor == m_wndProxy
    11591215                    && e.xselection.target    == aFormat)
    11601216                {
    1161                     DO(("DND_DRO: selection notfiy (from: %x)\n", m_curWin));
     1217                    LogFlowThisFunc(("Selection notfiy (from: %x)\n", m_wndCur));
    11621218                    Atom type;
    11631219                    int format;
    11641220                    unsigned long cItems, cbRemaining;
    11651221                    unsigned char *ucData = 0;
    1166                     XGetWindowProperty(m_pDisplay, m_proxyWin, xAtom(XA_XdndSelection),
     1222                    XGetWindowProperty(m_pDisplay, m_wndProxy, xAtom(XA_XdndSelection),
    11671223                                       0, VBOX_MAX_XPROPERTIES, True, AnyPropertyType,
    11681224                                       &type, &format, &cItems, &cbRemaining, &ucData);
    1169                     DO(("DND_DRO: %s %d %d %s\n", gX11->xAtomToString(type).c_str(), cItems, format, ucData));
     1225                    LogFlowThisFunc(("%s %d %d %s\n", gX11->xAtomToString(type).c_str(), cItems, format, ucData));
    11701226                    if (   type        != None
    11711227                        && ucData      != NULL
     
    11811237                            && ucData[cbData - 1] != '\0')
    11821238                        {
    1183                             DO(("rebuild %u\n", cbData));
     1239                            LogFlowThisFunc(("Rebuild %u\n", cbData));
    11841240                            unsigned char *ucData1 = static_cast<unsigned char*>(RTMemAlloc(cbData + 1));
    11851241                            if (ucData1)
     
    11981254                            rc = VbglR3DnDGHSendData(ucData, cbData);
    11991255
    1200                         DO(("send responce\n"));
     1256                        LogFlowThisFunc(("send responce\n"));
    12011257                        /* Confirm the result of the transfer to the source window. */
    12021258                        XClientMessageEvent m;
     
    12071263                        m.message_type = xAtom(XA_XdndFinished);
    12081264                        m.format       = 32;
    1209                         m.data.l[0]    = m_proxyWin;
     1265                        m.data.l[0]    = m_wndProxy;
    12101266                        m.data.l[1]    = RT_SUCCESS(rc) ?                   1 : 0;    /* Confirm or deny success */
    12111267                        m.data.l[2]    = RT_SUCCESS(rc) ? toX11Action(action) : None; /* Action used on success */
     
    12131269                        int xrc = XSendEvent(m_pDisplay, srcWin, True, NoEventMask, reinterpret_cast<XEvent*>(&m));
    12141270                        if (RT_UNLIKELY(xrc == 0))
    1215                             DO(("DnD_DRO: error sending xevent\n"));
     1271                            LogFlowThisFunc(("Error sending xevent\n"));
    12161272                    }
    12171273                    else
     
    12361292                        m.message_type = xAtom(XA_XdndFinished);
    12371293                        m.format       = 32;
    1238                         m.data.l[0]    = m_proxyWin;
     1294                        m.data.l[0]    = m_wndProxy;
    12391295                        m.data.l[1]    = 0;
    12401296                        m.data.l[2]    = None;
    12411297                        int xrc = XSendEvent(m_pDisplay, srcWin, False, NoEventMask, reinterpret_cast<XEvent*>(&m));
    12421298                        if (RT_UNLIKELY(xrc == 0))
    1243                             DO(("DnD_DRO: error sending xevent\n"));
    1244                         m_curWin = 0;
     1299                            LogFlowThisFunc(("Error sending xevent\n"));
     1300                        m_wndCur = 0;
    12451301                    }
    12461302                    /* Cleanup */
     
    12681324    reset();
    12691325
     1326    LogFlowFuncLeaveRC(rc);
    12701327    return rc;
    12711328}
     
    12811338    /* Move the guest pointer to the DnD position, so we can find the window
    12821339     * below that position. */
    1283     XWarpPointer(m_pDisplay, None, m_rootWin, 0, 0, 0, 0, u32xPos, u32yPos);
     1340    XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0, u32xPos, u32yPos);
    12841341    return VINF_SUCCESS;
    12851342}
     
    12951352        RT_ZERO(be);
    12961353        be.display      = m_pDisplay;
    1297         be.root         = m_rootWin;
     1354        be.root         = m_wndRoot;
    12981355        be.window       = w;
    12991356        be.subwindow    = None;
     
    13121369        int xrc = XSendEvent(m_pDisplay, be.window, True, ButtonPressMask, reinterpret_cast<XEvent*>(&be));
    13131370        if (RT_UNLIKELY(xrc == 0))
    1314             DO(("DnD_BTN: error sending xevent\n"));
    1315     }
    1316 
     1371            LogFlowThisFunc(("Error sending xevent\n"));
     1372    }
    13171373}
    13181374
     
    13231379    Window r, c;
    13241380//    XTestGrabControl(m_pDisplay, False);
    1325     XQueryPointer(m_pDisplay, m_rootWin, &r, &c, &rx, &ry, &cx, &cy, &m);
     1381    XQueryPointer(m_pDisplay, m_wndRoot, &r, &c, &rx, &ry, &cx, &cy, &m);
    13261382    XSynchronize(m_pDisplay, True);
    1327     XMapWindow(m_pDisplay, m_proxyWin);
    1328     XRaiseWindow(m_pDisplay, m_proxyWin);
    1329     XMoveResizeWindow(m_pDisplay, m_proxyWin, rx, ry, 1, 1);
    1330     XWarpPointer(m_pDisplay, None, m_rootWin, 0, 0, 0, 0, rx , ry);
     1383    XMapWindow(m_pDisplay, m_wndProxy);
     1384    XRaiseWindow(m_pDisplay, m_wndProxy);
     1385    XMoveResizeWindow(m_pDisplay, m_wndProxy, rx, ry, 1, 1);
     1386    XWarpPointer(m_pDisplay, None, m_wndRoot, 0, 0, 0, 0, rx , ry);
    13311387    XSynchronize(m_pDisplay, False);
    13321388//    XTestGrabControl(m_pDisplay, True);
    13331389}
    13341390
    1335 void DragInstance::hideProxyWin() const
    1336 {
    1337     XUnmapWindow(m_pDisplay, m_proxyWin);
     1391void DragInstance::hideProxyWin(void) const
     1392{
     1393    XUnmapWindow(m_pDisplay, m_wndProxy);
    13381394}
    13391395
    13401396/* Currently, not used */
    1341 void DragInstance::registerForEvents(Window w) const
     1397void DragInstance::registerForEvents(Window wndThis) const
    13421398{
    13431399//    if (w == m_proxyWin)
    13441400//        return;
    13451401
    1346     DO(("%x\n", w));
     1402    LogFlowThisFunc(("%x\n", wndThis));
    13471403//    XSelectInput(m_pDisplay, w, Button1MotionMask | Button2MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask);//| SubstructureNotifyMask);
    13481404//    XSelectInput(m_pDisplay, w, ButtonMotionMask); //PointerMotionMask);
    1349     XSelectInput(m_pDisplay, w, PointerMotionMask); //PointerMotionMask);
     1405    XSelectInput(m_pDisplay, wndThis, PointerMotionMask); //PointerMotionMask);
    13501406    Window hRealRoot, hParent;
    13511407    Window *phChildrenRaw = NULL;
    13521408    unsigned cChildren;
    1353     if (XQueryTree(m_pDisplay, w, &hRealRoot, &hParent, &phChildrenRaw, &cChildren))
     1409    if (XQueryTree(m_pDisplay, wndThis, &hRealRoot, &hParent, &phChildrenRaw, &cChildren))
    13541410    {
    13551411        for (unsigned i = 0; i < cChildren; ++i)
     
    13591415}
    13601416
    1361 void DragInstance::setActionsWindowProperty(Window win, const RTCList<Atom> &actionList) const
     1417void DragInstance::setActionsWindowProperty(Window wndThis, const RTCList<Atom> &actionList) const
    13621418{
    13631419    if (actionList.isEmpty())
    13641420        return;
    13651421
    1366     XChangeProperty(m_pDisplay, win, xAtom(XA_XdndActionList), XA_ATOM, 32, PropModeReplace,
     1422    XChangeProperty(m_pDisplay, wndThis, xAtom(XA_XdndActionList), XA_ATOM, 32, PropModeReplace,
    13671423                    reinterpret_cast<const unsigned char*>(actionList.raw()), actionList.size());
    13681424}
    13691425
    1370 void DragInstance::clearActionsWindowProperty(Window win) const
    1371 {
    1372     XDeleteProperty(m_pDisplay, win, xAtom(XA_XdndActionList));
    1373 }
    1374 
    1375 void DragInstance::setFormatsWindowProperty(Window win, Atom property) const
     1426void DragInstance::clearActionsWindowProperty(Window wndThis) const
     1427{
     1428    XDeleteProperty(m_pDisplay, wndThis, xAtom(XA_XdndActionList));
     1429}
     1430
     1431void DragInstance::setFormatsWindowProperty(Window wndThis, Atom property) const
    13761432{
    13771433    if (m_formats.isEmpty())
     
    13841440
    13851441    /* Add the property with the property data to the window. */
    1386     XChangeProperty(m_pDisplay, win, property, XA_ATOM, 32, PropModeReplace,
     1442    XChangeProperty(m_pDisplay, wndThis, property, XA_ATOM, 32, PropModeReplace,
    13871443                    reinterpret_cast<const unsigned char*>(targets.raw()), targets.size());
    13881444}
    13891445
    1390 void DragInstance::clearFormatsWindowProperty(Window win) const
    1391 {
    1392     XDeleteProperty(m_pDisplay, win, xAtom(XA_XdndTypeList));
     1446void DragInstance::clearFormatsWindowProperty(Window wndThis) const
     1447{
     1448    XDeleteProperty(m_pDisplay, wndThis, xAtom(XA_XdndTypeList));
    13931449}
    13941450
     
    14171473         * even if the data isn't zero terminated. */
    14181474        char *pszTmp = RTStrDupN(pszStr, cSize);
    1419         DO(("f: %s\n", pszTmp));
     1475        LogFlowThisFunc(("f: %s\n", pszTmp));
    14201476        atomList.append(XInternAtom(m_pDisplay, pszTmp, False));
    14211477        RTStrFree(pszTmp);
     
    15121568        if (!m_eventQueue.isEmpty())
    15131569        {
    1514             DO(("new msg size %d\n", m_eventQueue.size()));
     1570            LogFlowThisFunc(("new msg size %d\n", m_eventQueue.size()));
    15151571            /* Check if there is a client message in the queue. */
    15161572            for (size_t i = 0; i < m_eventQueue.size(); ++i)
     
    15181574                DnDEvent e = m_eventQueue.at(i);
    15191575                if(   e.type     == DnDEvent::X11_Type)
    1520                     DO(("new msg\n"));
     1576                    LogFlowThisFunc(("new msg\n"));
    15211577                if(   e.type     == DnDEvent::X11_Type
    15221578                   && e.x11.type == type)
     
    15511607    do
    15521608    {
    1553         /* Initialize our service */
    1554         rc = VbglR3DnDInit();
    1555         if (RT_FAILURE(rc))
    1556             break;
    1557 
    15581609        /* Initialize X11 DND */
    15591610        rc = x11DragAndDropInit();
     
    15621613
    15631614        m_pCurDnD = new DragInstance(m_pDisplay, this);
     1615        if (!m_pCurDnD)
     1616        {
     1617            rc = VERR_NO_MEMORY;
     1618            break;
     1619        }
    15641620        /* Note: For multiple screen support in VBox it is not necessary to use
    15651621         * another screen number than zero. Maybe in the future it will become
    15661622         * necessary if VBox supports multiple X11 screens. */
    1567         m_pCurDnD->init(0);
     1623        rc = m_pCurDnD->init(0);
     1624        if (RT_FAILURE(rc))
     1625            break;
     1626
    15681627        /* Loop over new events */
    15691628        do
     
    15771636                e = m_eventQueue.first();
    15781637                m_eventQueue.removeFirst();
    1579                 DO(("new msg %d\n", e.type));
     1638                LogFlowThisFunc(("new msg %d\n", e.type));
    15801639                if (e.type == DnDEvent::HGCM_Type)
    15811640                {
     
    16241683                        }
    16251684#endif
     1685                        default:
     1686                            LogFlowThisFunc(("Unknown message: %RU32\n", e.hgcm.uType));
     1687                            break;
    16261688                    }
     1689
    16271690                    /* Some messages require cleanup. */
    16281691                    switch (e.hgcm.uType)
     
    16471710                            break;
    16481711                        }
     1712                        default:
     1713                            break;
    16491714                    }
    1650 
    16511715                }
    16521716                else if(e.type == DnDEvent::X11_Type)
    16531717                {
    1654                     DO(("X11 type: %u\n", e.x11.type));
     1718                    LogFlowThisFunc(("X11 type: %u\n", e.x11.type));
    16551719                    /* Now the X11 event stuff */
    16561720                    switch (e.x11.type)
     
    16581722                        case SelectionRequest: m_pCurDnD->hgX11SelectionRequest(e.x11); break;
    16591723                        case ClientMessage:    m_pCurDnD->hgX11ClientMessage(e.x11); break;
    1660                         case SelectionClear:   DO(("DnD_CLER\n")); break;
     1724                        case SelectionClear:   LogFlowThisFunc(("DnD_CLER\n")); break;
    16611725//                      case MotionNotify: m_pCurDnD->hide(); break;
    16621726                    }
     
    16661730    } while (0);
    16671731
    1668     LogRelFlowFunc(("returning %Rrc\n", rc));
     1732    LogFlowFuncLeaveRC(rc);
    16691733    return rc;
    16701734}
    16711735
    1672 int DragAndDropService::x11DragAndDropInit()
     1736int DragAndDropService::x11DragAndDropInit(void)
    16731737{
    16741738    /* Connect to the x11 server. */
     
    16781742        return VERR_NOT_FOUND;
    16791743
    1680     xHelpers::instance(m_pDisplay);
     1744    xHelpers *pHelpers = xHelpers::getInstance(m_pDisplay);
     1745    if (!pHelpers)
     1746        return VERR_NO_MEMORY;
    16811747
    16821748    int rc = VINF_SUCCESS;
     
    17061772}
    17071773
    1708 int DragAndDropService::x11DragAndDropTerm()
     1774int DragAndDropService::x11DragAndDropTerm(void)
    17091775{
    17101776    /* Mark that we are stopping. */
     
    17241790        int xrc = XSendEvent(m_pDisplay, None, True, NoEventMask, reinterpret_cast<XEvent*>(&m));
    17251791        if (RT_UNLIKELY(xrc == 0))
    1726                 DO(("DnD_TERM: error sending xevent\n"));
     1792            LogFlowThisFunc(("Error sending xevent\n"));
    17271793    }
    17281794
     
    17551821    DragAndDropService *pThis = static_cast<DragAndDropService*>(pvUser);
    17561822    DnDEvent e;
     1823
     1824    uint32_t uClientID;
     1825    int rc = VbglR3DnDConnect(&uClientID);
     1826    if (RT_FAILURE(rc)) {
     1827        LogFlowFunc(("Unable to connect to HGCM service, rc=%Rrc\n", rc));
     1828        return rc;
     1829    }
     1830
    17571831    do
    17581832    {
     
    17601834        e.type = DnDEvent::HGCM_Type;
    17611835        /* Wait for new events */
    1762         int rc = VbglR3DnDProcessNextMessage(&e.hgcm);
     1836        rc = VbglR3DnDProcessNextMessage(uClientID, &e.hgcm);
    17631837        if (RT_SUCCESS(rc))
    17641838        {
     
    17691843        }
    17701844    } while (!ASMAtomicReadBool(&pThis->m_fSrvStopping));
     1845
     1846    VbglR3DnDDisconnect(uClientID);
    17711847
    17721848    return VINF_SUCCESS;
     
    18151891
    18161892/* Static factory */
    1817 VBoxClient::Service *VBoxClient::GetDragAndDropService()
    1818 {
    1819     return new(DragAndDropService);
    1820 }
     1893VBoxClient::Service *VBoxClient::GetDragAndDropService(void)
     1894{
     1895    DragAndDropService *pService = new DragAndDropService();
     1896    return pService;
     1897}
     1898
  • trunk/src/VBox/Frontends

  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDHandler.cpp

    r45358 r49891  
    77
    88/*
    9  * Copyright (C) 2011-2012 Oracle Corporation
     9 * Copyright (C) 2011-2013 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2525#include <QTimer>
    2626
     27#ifdef LOG_GROUP
     28# undef LOG_GROUP
     29#endif
     30#define LOG_GROUP LOG_GROUP_GUEST_DND
     31#include <VBox/log.h>
     32
    2733/* GUI includes: */
    2834#include "UIDnDHandler.h"
     
    4652Qt::DropAction UIDnDHandler::dragHGEnter(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget * /* pParent = 0 */)
    4753{
     54    LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n",
     55                 screenId, x, y, toVBoxDnDAction(proposedAction)));
     56
    4857    /* Ask the guest for starting a DnD event. */
    4958    KDragAndDropAction result = guest.DragHGEnter(screenId,
     
    5968Qt::DropAction UIDnDHandler::dragHGMove(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget * /* pParent = 0 */)
    6069{
    61     /* Ask the guest for starting a DnD event. */
     70#ifdef DEBUG_andy
     71    LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n",
     72                 screenId, x, y, toVBoxDnDAction(proposedAction)));
     73#endif
     74
     75    /* Notify the guest that the mouse has been moved while doing
     76     * a drag'n drop operation. */
    6277    KDragAndDropAction result = guest.DragHGMove(screenId,
    6378                                                 x,
     
    7287Qt::DropAction UIDnDHandler::dragHGDrop(CGuest &guest, ulong screenId, int x, int y, Qt::DropAction proposedAction, Qt::DropActions possibleActions, const QMimeData *pMimeData, QWidget *pParent /* = 0 */)
    7388{
     89    LogFlowFunc(("screenId=%RU32, x=%d, y=%d, action=%ld\n",
     90                 screenId, x, y, toVBoxDnDAction(proposedAction)));
     91
    7492    /* The format the guest requests. */
    7593    QString format;
     
    116134void UIDnDHandler::dragHGLeave(CGuest &guest, ulong screenId, QWidget * /* pParent = 0 */)
    117135{
     136    LogFlowFunc(("screenId=%RU32\n", screenId));
    118137    guest.DragHGLeave(screenId);
    119138}
     
    144163      , m_fState(Dragging)
    145164    {
    146         /* This is unbelievable hacky, but I didn't found another way. Stupid
     165        /*
     166         * This is unbelievable hacky, but I didn't find another way. Stupid
    147167         * Qt QDrag interface is so less verbose, that we in principle know
    148168         * nothing about what happens when the user drag something around. It
     
    158178         * one installed by the QDrag object.
    159179         *
    160          * Todo: test this on all supported platforms (X11 works) */
     180         ** @todo: Test this on all supported platforms (X11 works).
     181         */
    161182        QTimer::singleShot(0, this, SLOT(sltInstallEventFilter()));
    162183    }
     
    258279void UIDnDHandler::dragGHPending(CSession &session, ulong screenId, QWidget *pParent /* = 0 */)
    259280{
    260     /* How does this work: Host is asking the guest if there is any DnD
     281    /*
     282     * How this works: Host is asking the guest if there is any DnD
    261283     * operation pending, when the mouse leaves the guest window
    262284     * (DragGHPending). On return there is some info about a running DnD
     
    264286     * this information we create a Qt QDrag object with our own QMimeType
    265287     * implementation and call exec. Please note, this *blocks* until the DnD
    266      * operation has finished. */
     288     * operation has finished.
     289     */
    267290    CGuest guest = session.GetConsole().GetGuest();
    268291    QVector<QString> formats;
  • trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp

    r44102 r49891  
    55
    66/*
    7  * Copyright (C) 2011-2012 Oracle Corporation
     7 * Copyright (C) 2011-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2020 ******************************************************************************/
    2121
    22 #define LOG_GROUP LOG_GROUP_HGCM
     22#ifdef LOG_GROUP
     23 #undef LOG_GROUP
     24#endif
     25#define LOG_GROUP LOG_GROUP_GUEST_DND
    2326
    2427#include "dndmanager.h"
     
    2932#include <iprt/path.h>
    3033#include <iprt/uri.h>
    31 
    32 #define VERBOSE 1
    33 
    34 #if defined(VERBOSE) && defined(DEBUG_poetzsch)
    35 # include <iprt/stream.h>
    36 # define DO(s) RTPrintf s
    37 #else
    38 # define DO(s) do {} while(0)
    39 //# define DO(s) Log s
    40 #endif
    4134
    4235/******************************************************************************
     
    6558        paTmpParms[1].setUInt32(m_strPath.length() + 1);
    6659        paTmpParms[2].setUInt32(fMode);
     60
    6761        m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_DIR, 3, paTmpParms);
    6862    }
     
    9791public:
    9892    DnDHGSendFilePrivate(const RTCString &strHostPath, const RTCString &strGuestPath, uint32_t fMode, uint64_t cbSize, PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser);
    99     ~DnDHGSendFilePrivate();
     93    virtual ~DnDHGSendFilePrivate();
    10094
    10195    int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     
    10498    RTCString              m_strHostPath;
    10599    RTCString              m_strGuestPath;
    106     uint64_t               m_cbSize;
    107     uint64_t               m_cbDone;
     100    uint64_t               m_cbFileSize;
     101    uint64_t               m_cbFileProcessed;
    108102    RTFILE                 m_hCurFile;
    109103    VBOXHGCMSVCPARM        m_paSkelParms[5];
     
    146140  : m_strHostPath(strHostPath)
    147141  , m_strGuestPath(strGuestPath)
    148   , m_cbSize(cbSize)
    149   , m_cbDone(0)
     142  , m_cbFileSize(cbSize)
     143  , m_cbFileProcessed(0)
    150144  , m_hCurFile(0)
    151145  , m_pfnProgressCallback(pfnProgressCallback)
     
    157151    m_paSkelParms[3].setUInt32(0);
    158152    m_paSkelParms[4].setUInt32(fMode);
     153
    159154    m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_paSkelParms);
    160155}
     
    178173    if (!m_hCurFile)
    179174    {
    180         rc = RTFileOpen(&m_hCurFile, m_strHostPath.c_str(), RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_ALL);
    181         if (RT_FAILURE(rc))
    182             return rc;
    183     }
    184 
    185     /* How big is the pointer provided by the guest? */
    186     uint32_t cbToRead = paParms[2].u.pointer.size;
     175        /* Open files on the host with RTFILE_O_DENY_WRITE to prevent races where the host
     176         * writes to the file while the guest transfers it over. */
     177        rc = RTFileOpen(&m_hCurFile, m_strHostPath.c_str(),
     178                        RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
     179    }
     180
    187181    size_t cbRead;
    188     rc = RTFileRead(m_hCurFile, paParms[2].u.pointer.addr, cbToRead, &cbRead);
    189     if (RT_FAILURE(rc))
    190     {
    191         /* On error, immediately close the file. */
    192         RTFileClose(m_hCurFile);
    193         m_hCurFile = 0;
    194         return rc;
    195     }
    196     m_cbDone += cbRead;
    197     /* Tell the guest the actual size. */
    198     paParms[3].setUInt32(cbRead);
    199     /* Check if we are done. */
    200     if (m_cbSize == m_cbDone)
    201     {
    202         RTFileClose(m_hCurFile);
    203         m_hCurFile = 0;
    204     }
    205     else
    206     {
    207         /* More data! Prepare the next message. */
    208         m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_paSkelParms);
    209     }
    210 
    211     /* Advance progress info */
    212     if (   RT_SUCCESS(rc)
    213         && m_pfnProgressCallback)
    214         rc = m_pfnProgressCallback(cbRead, m_pvProgressUser);
     182    if (RT_SUCCESS(rc))
     183    {
     184        /* Get buffer size + pointer to buffer from guest side. */
     185        uint32_t cbToRead = paParms[2].u.pointer.size;
     186        Assert(cbToRead);
     187        void *pvBuf = paParms[2].u.pointer.addr;
     188        AssertPtr(pvBuf);
     189        rc = RTFileRead(m_hCurFile, pvBuf, cbToRead, &cbRead);
     190        if (RT_LIKELY(RT_SUCCESS(rc)))
     191        {
     192            /* Advance. */
     193            m_cbFileProcessed += cbRead;
     194            Assert(m_cbFileProcessed <= m_cbFileSize);
     195
     196            /* Tell the guest the actual size. */
     197            paParms[3].setUInt32(cbRead);
     198        }
     199    }
     200
     201    if (RT_SUCCESS(rc))
     202    {
     203        /* Check if we are done. */
     204        bool fDone = m_cbFileSize == m_cbFileProcessed;
     205        if (!fDone)
     206        {
     207            try
     208            {
     209                /* More data! Prepare the next message. */
     210                m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5 /* cParms */,
     211                                               m_paSkelParms);
     212            }
     213            catch(std::bad_alloc &)
     214            {
     215                rc = VERR_NO_MEMORY;
     216            }
     217        }
     218
     219        /* Advance progress info. */
     220        if (   RT_SUCCESS(rc)
     221            && m_pfnProgressCallback)
     222            rc = m_pfnProgressCallback(cbRead, m_pvProgressUser);
     223
     224        if (   fDone
     225            || RT_FAILURE(rc))
     226        {
     227            RTFileClose(m_hCurFile);
     228            m_hCurFile = 0;
     229        }
     230    }
    215231
    216232    return rc;
     
    241257
    242258    HGCM::Message *pCurMsg = m_pNextMsg;
     259    AssertPtr(pCurMsg);
     260
    243261    m_pNextMsg = 0;
    244262    rc = pCurMsg->getData(uMsg, cParms, paParms);
     
    258276        paTmpParms[0].setPointer(static_cast<uint8_t*>(pvOldData) + paParms[iPos].u.pointer.size, cOldData - paParms[iPos].u.pointer.size);
    259277        paTmpParms[1].setUInt32(cOldData - paParms[iPos].u.pointer.size);
    260         m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA, 2, paTmpParms);
    261     }
     278
     279        try
     280        {
     281            m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA, 2, paTmpParms);
     282        }
     283        catch(std::bad_alloc &)
     284        {
     285            rc = VERR_NO_MEMORY;
     286        }
     287    }
     288
    262289    delete pCurMsg;
    263290
     
    280307 */
    281308DnDHGSendDataMessage::DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], PFNDNDPROGRESS pfnProgressCallback, void *pvProgressUser)
    282   : m_cbAll(0)
    283   , m_cbTransfered(0)
    284   , m_pfnProgressCallback(pfnProgressCallback)
    285   , m_pvProgressUser(pvProgressUser)
     309    : m_cbAll(0)
     310    , m_cbTransfered(0)
     311    , m_pfnProgressCallback(pfnProgressCallback)
     312    , m_pvProgressUser(pvProgressUser)
    286313{
    287314    RTCString strNewUris;
     
    289316    if (hasFileUrls(static_cast<const char*>(paParms[1].u.pointer.addr), paParms[1].u.pointer.size))
    290317    {
    291         DO(("old data '%s'\n", (char*)paParms[3].u.pointer.addr));
     318        LogFlowFunc(("Old data: '%s'\n", (char*)paParms[3].u.pointer.addr));
    292319        /* The list is separated by newline (Even if only one file is
    293320         * listed). */
    294         RTCList<RTCString> oldUriList = RTCString(static_cast<const char*>(paParms[3].u.pointer.addr), paParms[3].u.pointer.size).split("\r\n");
     321        RTCList<RTCString> oldUriList = RTCString(static_cast<const char*>(paParms[3].u.pointer.addr),
     322                                                  paParms[3].u.pointer.size).split("\r\n");
    295323        if (!oldUriList.isEmpty())
    296324        {
     
    337365    m_cbAll += paParms[4].u.uint32;
    338366    /* The first message is the meta info for the data and the data itself. */
    339     m_pNextPathMsg = new DnDHGSendDataMessagePrivate(uMsg, cParms, paParms, &DnDHGSendDataMessage::progressCallback, this);
    340 
    341     DO(("new data '%s'\n", (char*)paParms[3].u.pointer.addr));
    342     DO(("cbAll: %u\n", m_cbAll));
    343     DO(("cbData: %u\n", paParms[4].u.uint32));
     367    m_pNextPathMsg = new DnDHGSendDataMessagePrivate(uMsg, cParms, paParms,
     368                                                     &DnDHGSendDataMessage::progressCallback, this);
     369
     370    LogFlowFunc(("new data '%s'\n", (char*)paParms[3].u.pointer.addr));
     371    LogFlowFunc(("cbAll: %zu\n", m_cbAll));
     372    LogFlowFunc(("cbData: %RU32\n", paParms[4].u.uint32));
    344373
    345374    for (size_t i = 0; i < m_uriList.size(); ++i)
    346         DO(("file: %s : %s - %o - %ld\n", m_uriList.at(i).m_strHostPath.c_str(), m_uriList.at(i).m_strGuestPath.c_str(), m_uriList.at(i).m_fMode, m_uriList.at(i).m_cbSize));
     375        LogFlowFunc(("file: %s : %s - %o - %ld\n",
     376                     m_uriList.at(i).m_strHostPath.c_str(), m_uriList.at(i).m_strGuestPath.c_str(),
     377                     m_uriList.at(i).m_fMode, m_uriList.at(i).m_cbSize));
    347378}
    348379
     
    391422         * this could be directories or regular files. */
    392423        PathEntry nextPath = m_uriList.first();
    393         if (RTFS_IS_DIRECTORY(nextPath.m_fMode))
    394             m_pNextPathMsg = new DnDHGSendDirPrivate(nextPath.m_strGuestPath, nextPath.m_fMode, nextPath.m_cbSize, &DnDHGSendDataMessage::progressCallback, this);
    395         else if (RTFS_IS_FILE(nextPath.m_fMode))
    396             m_pNextPathMsg = new DnDHGSendFilePrivate(nextPath.m_strHostPath, nextPath.m_strGuestPath, nextPath.m_fMode, nextPath.m_cbSize, &DnDHGSendDataMessage::progressCallback, this);
    397         else
    398             AssertMsgFailedReturn(("type '%d' is not supported for path '%s'", nextPath.m_fMode, nextPath.m_strHostPath.c_str()), VERR_NO_DATA);
    399         m_uriList.removeFirst();
    400     }
     424        try
     425        {
     426            if (RTFS_IS_DIRECTORY(nextPath.m_fMode))
     427                m_pNextPathMsg = new DnDHGSendDirPrivate(nextPath.m_strGuestPath,
     428                                                         nextPath.m_fMode, nextPath.m_cbSize,
     429                                                         &DnDHGSendDataMessage::progressCallback, this);
     430            else if (RTFS_IS_FILE(nextPath.m_fMode))
     431                m_pNextPathMsg = new DnDHGSendFilePrivate(nextPath.m_strHostPath, nextPath.m_strGuestPath,
     432                                                          nextPath.m_fMode, nextPath.m_cbSize,
     433                                                          &DnDHGSendDataMessage::progressCallback, this);
     434            else
     435                AssertMsgFailedReturn(("type '%d' is not supported for path '%s'",
     436                                       nextPath.m_fMode, nextPath.m_strHostPath.c_str()), VERR_NO_DATA);
     437
     438            m_uriList.removeFirst();
     439        }
     440        catch(std::bad_alloc &)
     441        {
     442            rc = VERR_NO_MEMORY;
     443        }
     444    }
     445
    401446    return rc;
    402447}
     
    404449bool DnDHGSendDataMessage::hasFileUrls(const char *pcszFormat, size_t cbMax) const
    405450{
    406     DO(("format %s\n", pcszFormat));
    407     /* text/uri also an official variant? */
     451    LogFlowFunc(("format %s\n", pcszFormat));
     452    /** @todo text/uri also an official variant? */
    408453    return    RTStrNICmp(pcszFormat, "text/uri-list", cbMax)             == 0
    409454           || RTStrNICmp(pcszFormat, "x-special/gnome-icon-list", cbMax) == 0;
     
    435480    m_uriList.append(PathEntry(pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize));
    436481    m_cbAll += cbSize;
    437     DO(("cbFile: %u\n", cbSize));
     482    LogFlowFunc(("cbFile: %RU64\n", cbSize));
    438483
    439484    PRTDIR hDir;
     
    518563        && pSelf->m_cbAll)
    519564        rc = pSelf->m_pfnProgressCallback((uint64_t)pSelf->m_cbTransfered * 100 / pSelf->m_cbAll,
    520                                           DragAndDropSvc::DND_PROGRESS_RUNNING, pSelf->m_pvProgressUser);
     565                                          DragAndDropSvc::DND_PROGRESS_RUNNING, VINF_SUCCESS /* rc */, pSelf->m_pvProgressUser);
    521566
    522567    return rc;
     
    530575{
    531576    int rc = VINF_SUCCESS;
    532     switch (uMsg)
    533     {
    534         case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
    535         {
    536             clear();
    537             LogFlowFunc(("HOST_DND_HG_EVT_ENTER\n"));
    538             DO(("HOST_DND_HG_EVT_ENTER\n"));
    539             /* Verify parameter count and types. */
    540             if (   cParms != 7
    541                 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
    542                 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */
    543                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */
    544                 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */
    545                 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */
    546                 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
    547                 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)
    548                 rc = VERR_INVALID_PARAMETER;
    549             else
    550             {
    551                 m_fOpInProcess = true;
    552                 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
    553                 m_dndMessageQueue.append(pMessage);
    554             }
    555             break;
    556         }
    557         case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
    558         {
    559             LogFlowFunc(("HOST_DND_HG_EVT_MOVE\n"));
    560             DO(("HOST_DND_HG_EVT_MOVE\n"));
    561             /* Verify parameter count and types. */
    562             if (   cParms != 7
    563                 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
    564                 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */
    565                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */
    566                 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */
    567                 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */
    568                 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
    569                 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)
    570                 rc = VERR_INVALID_PARAMETER;
    571             else
    572             {
    573                 m_fOpInProcess = true;
    574                 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
    575                 m_dndMessageQueue.append(pMessage);
    576             }
    577             break;
    578         }
    579         case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
    580         {
    581             LogFlowFunc(("HOST_DND_HG_EVT_LEAVE\n"));
    582             DO(("HOST_DND_HG_EVT_LEAVE\n"));
    583 
    584             /* Verify parameter count and types. */
    585             if (cParms != 0)
    586                 rc = VERR_INVALID_PARAMETER;
    587             else
    588             {
    589                 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
    590                 m_dndMessageQueue.append(pMessage);
    591             }
    592             m_fOpInProcess = false;
    593             break;
    594         }
    595         case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
    596         {
    597             LogFlowFunc(("HOST_DND_HG_EVT_DROPPED\n"));
    598             DO(("HOST_DND_HG_EVT_DROPPED\n"));
    599             /* Verify parameter count and types. */
    600             if (   cParms != 7
    601                 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
    602                 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */
    603                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */
    604                 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */
    605                 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */
    606                 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
    607                 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)
    608                 rc = VERR_INVALID_PARAMETER;
    609             else
    610             {
    611                 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
    612                 m_dndMessageQueue.append(pMessage);
    613             }
    614             break;
    615         }
    616         case DragAndDropSvc::HOST_DND_HG_SND_DATA:
    617         {
    618             LogFlowFunc(("HOST_DND_HG_SND_DATA\n"));
    619             DO(("HOST_DND_HG_SND_DATA\n"));
    620 
    621             /* Verify parameter count and types. */
    622             if (   cParms != 5
    623                 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
    624                 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR   /* format */
    625                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */
    626                 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
    627                 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* data size */)
    628                 rc = VERR_INVALID_PARAMETER;
    629             else
    630             {
    631                 DnDHGSendDataMessage *pMessage = new DnDHGSendDataMessage(uMsg, cParms, paParms, m_pfnProgressCallback, m_pvProgressUser);
    632                 m_dndMessageQueue.append(pMessage);
    633             }
    634             break;
    635         }
    636 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
    637         case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
    638         {
    639             LogFlowFunc(("HOST_DND_GH_REQ_PENDING\n"));
    640             DO(("HOST_DND_GH_REQ_PENDING\n"));
    641 
    642             /* Verify parameter count and types. */
    643             if (   cParms != 1
    644                 || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */)
    645                 rc = VERR_INVALID_PARAMETER;
    646             else
    647             {
    648                 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
    649                 m_dndMessageQueue.append(pMessage);
    650             }
    651             break;
    652         }
    653         case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
    654         {
    655             LogFlowFunc(("HOST_DND_GH_EVT_DROPPED\n"));
    656             DO(("HOST_DND_GH_EVT_DROPPED\n"));
    657 
    658             /* Verify parameter count and types. */
    659             if (   cParms != 3
    660                 || paParms[0].type != VBOX_HGCM_SVC_PARM_PTR   /* format */
    661                 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */
    662                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* action */)
    663                 rc = VERR_INVALID_PARAMETER;
    664             else
    665             {
    666                 DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
    667                 m_dndMessageQueue.append(pMessage);
    668             }
    669             break;
    670         }
    671 #endif
    672         default: rc = VERR_NOT_IMPLEMENTED; break;
     577
     578    try
     579    {
     580        switch (uMsg)
     581        {
     582            case DragAndDropSvc::HOST_DND_HG_EVT_ENTER:
     583            {
     584                clear();
     585                LogFlowFunc(("HOST_DND_HG_EVT_ENTER\n"));
     586
     587                /* Verify parameter count and types. */
     588                if (   cParms != 7
     589                    || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
     590                    || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */
     591                    || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */
     592                    || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */
     593                    || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */
     594                    || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
     595                    || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)
     596                    rc = VERR_INVALID_PARAMETER;
     597                else
     598                {
     599                    m_fOpInProcess = true;
     600                    DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
     601                    m_dndMessageQueue.append(pMessage);
     602                }
     603                break;
     604            }
     605            case DragAndDropSvc::HOST_DND_HG_EVT_MOVE:
     606            {
     607                LogFlowFunc(("HOST_DND_HG_EVT_MOVE\n"));
     608
     609                /* Verify parameter count and types. */
     610                if (   cParms != 7
     611                    || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
     612                    || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */
     613                    || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */
     614                    || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */
     615                    || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */
     616                    || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
     617                    || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)
     618                    rc = VERR_INVALID_PARAMETER;
     619                else
     620                {
     621                    m_fOpInProcess = true;
     622                    DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
     623                    m_dndMessageQueue.append(pMessage);
     624                }
     625                break;
     626            }
     627            case DragAndDropSvc::HOST_DND_HG_EVT_LEAVE:
     628            {
     629                LogFlowFunc(("HOST_DND_HG_EVT_LEAVE\n"));
     630
     631                /* Verify parameter count and types. */
     632                if (cParms != 0)
     633                    rc = VERR_INVALID_PARAMETER;
     634                else
     635                {
     636                    DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
     637                    m_dndMessageQueue.append(pMessage);
     638                }
     639                m_fOpInProcess = false;
     640                break;
     641            }
     642            case DragAndDropSvc::HOST_DND_HG_EVT_DROPPED:
     643            {
     644                LogFlowFunc(("HOST_DND_HG_EVT_DROPPED\n"));
     645
     646                /* Verify parameter count and types. */
     647                if (   cParms != 7
     648                    || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
     649                    || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* x-pos */
     650                    || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* y-pos */
     651                    || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* default action */
     652                    || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* allowed actions */
     653                    || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
     654                    || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* size */)
     655                    rc = VERR_INVALID_PARAMETER;
     656                else
     657                {
     658                    DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
     659                    m_dndMessageQueue.append(pMessage);
     660                }
     661                break;
     662            }
     663            case DragAndDropSvc::HOST_DND_HG_SND_DATA:
     664            {
     665                LogFlowFunc(("HOST_DND_HG_SND_DATA\n"));
     666
     667                /* Verify parameter count and types. */
     668                if (   cParms != 5
     669                    || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */
     670                    || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR   /* format */
     671                    || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */
     672                    || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR   /* data */
     673                    || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* data size */)
     674                    rc = VERR_INVALID_PARAMETER;
     675                else
     676                {
     677                    DnDHGSendDataMessage *pMessage = new DnDHGSendDataMessage(uMsg, cParms, paParms, m_pfnProgressCallback, m_pvProgressUser);
     678                    m_dndMessageQueue.append(pMessage);
     679                }
     680                break;
     681            }
     682    #ifdef VBOX_WITH_DRAG_AND_DROP_GH
     683            case DragAndDropSvc::HOST_DND_GH_REQ_PENDING:
     684            {
     685                LogFlowFunc(("HOST_DND_GH_REQ_PENDING\n"));
     686
     687                /* Verify parameter count and types. */
     688                if (   cParms != 1
     689                    || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* screen id */)
     690                    rc = VERR_INVALID_PARAMETER;
     691                else
     692                {
     693                    DnDGenericMessage *pMessage = new DnDGenericMessage(uMsg, cParms, paParms);
     694                    m_dndMessageQueue.append(pMessage);
     695                }
     696                break;
     697            }
     698            case DragAndDropSvc::HOST_DND_GH_EVT_DROPPED:
     699            {
     700                LogFlowFunc(("HOST_DND_GH_EVT_DROPPED\n"));
     701
     702                /* Verify parameter count and types. */
     703                if (   cParms != 3
     704                    || paParms[0].type != VBOX_HGCM_SVC_PARM_PTR   /* format */
     705                    || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* format size */
     706                    || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* action */)
     707                    rc = VERR_INVALID_PARAMETER;
     708                else
     709                {
     710                    try
     711                    {
     712                        DnDGenericMessage *pMessage
     713                            = new DnDGenericMessage(uMsg, cParms, paParms);
     714                        m_dndMessageQueue.append(pMessage);
     715                    }
     716                    catch(std::bad_alloc &)
     717                    {
     718                        rc = VERR_NO_MEMORY;
     719                    }
     720                }
     721                break;
     722            }
     723    #endif
     724            default:
     725                rc = VERR_NOT_IMPLEMENTED;
     726                break;
     727        }
     728    }
     729    catch(std::bad_alloc &)
     730    {
     731        rc = VERR_NO_MEMORY;
    673732    }
    674733
     
    710769    }
    711770
    712     DO(("next msg info: %d %d %Rrc\n", *puMsg, *pcParms, rc));
     771    LogFlowFunc(("Returning puMsg=%RU32, pcParms=%RU32, rc=%Rrc\n", *puMsg, *pcParms, rc));
    713772    return rc;
    714773}
     
    716775int DnDManager::nextMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    717776{
     777    LogFlowFunc(("uMsg=%RU32, cParms=%RU32\n", uMsg, cParms));
     778
    718779    if (!m_pCurMsg)
    719780    {
    720781        /* Check for pending messages in our queue. */
    721782        if (m_dndMessageQueue.isEmpty())
     783        {
     784            LogFlowFunc(("Message queue is empty, returning\n"));
    722785            return VERR_NO_DATA;
     786        }
     787
    723788        m_pCurMsg = m_dndMessageQueue.first();
    724789        m_dndMessageQueue.removeFirst();
     
    727792    /* Fetch the current message info */
    728793    int rc = m_pCurMsg->currentMessage(uMsg, cParms, paParms);
    729     /* If this message not provide any additional sub messages, clear it. */
     794    /* If this message doesn't provide any additional sub messages, clear it. */
    730795    if (!m_pCurMsg->isMessageWaiting())
     796    {
     797        delete m_pCurMsg;
     798        m_pCurMsg = NULL;
     799    }
     800
     801    /*
     802     * If there was an error handling the current message or the user has canceled
     803     * the operation, we need to cleanup all pending events and inform the progress
     804     * callback about our exit.
     805     */
     806    if (   RT_FAILURE(rc)
     807        && m_pfnProgressCallback)
     808    {
     809        /* Clear any pending messages. */
     810        clear();
     811
     812        /* Create a new cancel message to inform the guest + call
     813         * the host whether the current transfer was canceled or aborted
     814         * due to an error. */
     815        try
     816        {
     817            Assert(!m_pCurMsg);
     818            m_pCurMsg = new DnDHGCancelMessage();
     819            m_pfnProgressCallback(100 /* Percent */,
     820                                    rc == VERR_CANCELLED
     821                                  ? DragAndDropSvc::DND_PROGRESS_CANCELLED
     822                                  : DragAndDropSvc::DND_PROGRESS_ERROR, rc, m_pvProgressUser);
     823        }
     824        catch(std::bad_alloc &)
     825        {
     826            rc = VERR_NO_MEMORY;
     827        }
     828    }
     829
     830    LogFlowFunc(("Message processed with rc=%Rrc\n", rc));
     831    return rc;
     832}
     833
     834void DnDManager::clear()
     835{
     836    if (m_pCurMsg)
    731837    {
    732838        delete m_pCurMsg;
    733839        m_pCurMsg = 0;
    734840    }
    735 
    736     /* If the user has canceled the operation, we need to cleanup all pending
    737      * events and inform the progress callback about our successful cleanup. */
    738     if (   rc == VERR_CANCELLED
    739         && m_pfnProgressCallback)
    740     {
    741         /* Clear any pending messages */
    742         clear();
    743         /* Create a new cancel message to inform the guest. */
    744         m_pCurMsg = new DnDHGCancelMessage();
    745         m_pfnProgressCallback(100, DragAndDropSvc::DND_PROGRESS_CANCELLED, m_pvProgressUser);
    746     }
    747 
    748     DO(("next msg: %d %d %Rrc\n", uMsg, cParms, rc));
    749     return rc;
    750 }
    751 
    752 void DnDManager::clear()
    753 {
    754     if (m_pCurMsg)
    755     {
    756         delete m_pCurMsg;
    757         m_pCurMsg = 0;
    758     }
    759841    while (!m_dndMessageQueue.isEmpty())
    760842    {
  • trunk/src/VBox/HostServices/DragAndDrop/dndmanager.h

    r42342 r49891  
    2424#include <iprt/cpp/list.h>
    2525
    26 typedef DECLCALLBACK(int) FNDNDPROGRESS(unsigned uPercentage, uint32_t uState, void *pvUser);
     26typedef DECLCALLBACK(int) FNDNDPROGRESS(unsigned uPercentage, uint32_t uState, int rc, void *pvUser);
    2727typedef FNDNDPROGRESS *PFNDNDPROGRESS;
    2828
     
    168168      , m_pvProgressUser(pvProgressUser)
    169169    {}
    170     ~DnDManager()
     170    virtual ~DnDManager()
    171171    {
    172172        clear();
  • trunk/src/VBox/HostServices/DragAndDrop/service.cpp

    r43996 r49891  
    55
    66/*
    7  * Copyright (C) 2011-2012 Oracle Corporation
     7 * Copyright (C) 2011-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5555 *   Header Files                                                             *
    5656 ******************************************************************************/
    57 #define LOG_GROUP LOG_GROUP_HGCM
     57#ifdef LOG_GROUP
     58 #undef LOG_GROUP
     59#endif
     60#define LOG_GROUP LOG_GROUP_GUEST_DND
    5861
    5962#include "dndmanager.h"
    60 
    61 //# define DO(s) RTPrintf s
    62 #define DO(s) do {} while(0)
    63 //#define DO(s) Log s
    6463
    6564/******************************************************************************
     
    8887    int  hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    8988
    90     static DECLCALLBACK(int) progressCallback(unsigned uPercentage, uint32_t uState, void *pvUser);
     89    static DECLCALLBACK(int) progressCallback(uint32_t uPercentage, uint32_t uState, int rc, void *pvUser);
    9190    int      hostMessage(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    9291    void     modeSet(uint32_t u32Mode);
     
    128127{
    129128    LogFlowFunc(("New client (%ld) connected\n", u32ClientID));
    130     DO(("New client (%ld) connected\n", u32ClientID));
    131129    if (m_cClients < UINT32_MAX)
    132130        m_cClients++;
     
    173171void DragAndDropService::guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    174172{
     173    LogFlowFunc(("u32ClientID=%RU32, u32Function=%RU32, cParms=%RU32\n",
     174                 u32ClientID, u32Function, cParms));
     175
    175176    int rc = VINF_SUCCESS;
    176     LogFlowFunc(("u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n",
    177                  u32ClientID, u32Function, cParms, paParms));
    178 //    RTPrintf("u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n",
    179 //                 u32ClientID, u32Function, cParms, paParms);
    180 
    181177    switch (u32Function)
    182178    {
    183179        case DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG:
    184180        {
    185             DO(("GUEST_DND_GET_NEXT_HOST_MSG\n"));
     181            LogFlowFunc(("GUEST_DND_GET_NEXT_HOST_MSG\n"));
    186182            if (   cParms != 3
    187183                || paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* message */
     
    203199        case DragAndDropSvc::GUEST_DND_HG_ACK_OP:
    204200        {
    205             DO(("GUEST_DND_HG_ACK_OP\n"));
     201            LogFlowFunc(("GUEST_DND_HG_ACK_OP\n"));
    206202            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
    207203                && modeGet() != VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST)
    208204            {
    209                 DO(("=> ignoring!\n"));
     205                LogFlowFunc(("=> ignoring!\n"));
    210206                break;
    211207            }
     
    227223        case DragAndDropSvc::GUEST_DND_HG_REQ_DATA:
    228224        {
    229             DO(("GUEST_DND_HG_REQ_DATA\n"));
     225            LogFlowFunc(("GUEST_DND_HG_REQ_DATA\n"));
    230226            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
    231227                && modeGet() != VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST)
    232228            {
    233                 DO(("=> ignoring!\n"));
     229                LogFlowFunc(("=> ignoring!\n"));
    234230                break;
    235231            }
     
    257253        case DragAndDropSvc::GUEST_DND_GH_ACK_PENDING:
    258254        {
    259             DO(("GUEST_DND_GH_ACK_PENDING\n"));
     255            LogFlowFunc(("GUEST_DND_GH_ACK_PENDING\n"));
    260256            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
    261257                && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST)
    262258            {
    263                 DO(("=> ignoring!\n"));
     259                LogFlowFunc(("=> ignoring!\n"));
    264260                break;
    265261            }
     
    285281        case DragAndDropSvc::GUEST_DND_GH_SND_DATA:
    286282        {
    287             DO(("GUEST_DND_GH_SND_DATA\n"));
     283            LogFlowFunc(("GUEST_DND_GH_SND_DATA\n"));
    288284            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
    289285                && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST)
    290286            {
    291                 DO(("=> ignoring\n"));
     287                LogFlowFunc(("=> ignoring\n"));
    292288                break;
    293289            }
     
    310306        case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR:
    311307        {
    312             DO(("GUEST_DND_GH_EVT_ERROR\n"));
     308            LogFlowFunc(("GUEST_DND_GH_EVT_ERROR\n"));
    313309            if (   modeGet() != VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
    314310                && modeGet() != VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST)
    315311            {
    316                 DO(("=> ignoring!\n"));
     312                LogFlowFunc(("=> ignoring!\n"));
    317313                break;
    318314            }
     
    338334            /* All other messages are handled by the DnD manager. */
    339335            rc = m_pManager->nextMessage(u32Function, cParms, paParms);
    340             /* Check for error. Buffer overflow is allowed. It signals the
    341              * guest to ask for more data in the next event. */
    342             if (   RT_FAILURE(rc)
    343                 && rc != VERR_CANCELLED
    344                 && rc != VERR_BUFFER_OVERFLOW) /* Buffer overflow is allowed. */
    345             {
    346                 m_clientQueue.append(new HGCM::Client(u32ClientID, callHandle, u32Function, cParms, paParms));
    347                 rc = VINF_HGCM_ASYNC_EXECUTE;
    348             }
    349336            break;
    350337        }
     
    355342    if (rc != VINF_HGCM_ASYNC_EXECUTE)
    356343        m_pHelpers->pfnCallComplete(callHandle, rc);
    357     DO(("guest call: %Rrc\n", rc));
     344    LogFlowFunc(("Returning rc=%Rrc\n", rc));
    358345}
    359346
     
    415402int DragAndDropService::hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    416403{
     404    LogFlowFunc(("u32Function=%RU32, cParms=%RU32\n", u32Function, cParms));
     405
    417406    int rc = VINF_SUCCESS;
    418407    if (u32Function == DragAndDropSvc::HOST_DND_SET_MODE)
     
    428417    {
    429418        rc = m_pManager->addMessage(u32Function, cParms, paParms);
    430         if (    RT_SUCCESS(rc)
     419        if (   RT_SUCCESS(rc)
    431420            && !m_clientQueue.isEmpty())
    432421        {
    433422            HGCM::Client *pClient = m_clientQueue.first();
     423            AssertPtr(pClient);
    434424            /* Check if this was a request for getting the next host
    435425             * message. If so, return the message id and the parameter
     
    437427            if (pClient->message() == DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG)
    438428            {
    439                 DO(("client is waiting for next host msg\n"));
    440 //              rc = m_pManager->nextMessageInfo(&paParms[0].u.uint32, &paParms[1].u.uint32);
     429                LogFlowFunc(("Client %RU32 is waiting for next host msg\n", pClient->clientId()));
     430
    441431                uint32_t uMsg1;
    442432                uint32_t cParms1;
     
    463453}
    464454
    465 DECLCALLBACK(int) DragAndDropService::progressCallback(unsigned uPercentage, uint32_t uState, void *pvUser)
     455DECLCALLBACK(int) DragAndDropService::progressCallback(uint32_t uPercentage, uint32_t uState, int rc, void *pvUser)
    466456{
    467457    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
     
    471461    if (pSelf->m_pfnHostCallback)
    472462    {
    473         DO(("GUEST_DND_HG_EVT_PROGRESS %u\n", uPercentage));
     463        LogFlowFunc(("GUEST_DND_HG_EVT_PROGRESS: uPercentage=%RU32, uState=%RU32, rc=%Rrc\n",
     464                     uPercentage, uState, rc));
    474465        DragAndDropSvc::VBOXDNDCBHGEVTPROGRESSDATA data;
    475466        data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_HG_EVT_PROGRESS;
    476467        data.uPercentage  = uPercentage;
    477468        data.uState       = uState;
     469        data.rc           = rc;
    478470
    479471        return pSelf->m_pfnHostCallback(pSelf->m_pvHostData, DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS, &data, sizeof(data));
  • trunk/src/VBox/Main/src-client/GuestDnDImpl.cpp

    r45367 r49891  
    55
    66/*
    7  * Copyright (C) 2011-2012 Oracle Corporation
     7 * Copyright (C) 2011-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2929# include <VBox/HostServices/DragAndDropSvc.h>
    3030
     31# ifdef LOG_GROUP
     32 # undef LOG_GROUP
     33# endif
     34# define LOG_GROUP LOG_GROUP_GUEST_DND
     35# include <VBox/log.h>
     36
    3137# include <iprt/stream.h>
    3238# include <iprt/semaphore.h>
     
    4854 *    of it to the Main IGuest interface (see UIDnDHandler.cpp).
    4955 * 2. Main: Public interface for doing Drag and Drop. Also manage the IProgress
    50  *    interfaces for blocking the caller by showing a progress dialog. (see
    51  *    this file)
     56 *    interfaces for blocking the caller by showing a progress dialog (see
     57 *    this file).
    5258 * 3. HGCM service: Handle all messages from the host to the guest at once and
    53  *    encapsulate the internal communication details. (see dndmanager.cpp and
    54  *    friends)
     59 *    encapsulate the internal communication details (see dndmanager.cpp and
     60 *    friends).
    5561 * 4. Guest additions: Split into the platform neutral part (see
    5662 *    VBoxGuestR3LibDragAndDrop.cpp) and the guest OS specific parts.
    5763 *    Receive/send message from/to the HGCM service and does all guest specific
    58  *    operations. Currently only X11 is supported. (see draganddrop.cpp within
    59  *    VBoxClient)
    60  *
    61  * Host  -> Guest:
     64 *    operations. Currently only X11 is supported (see draganddrop.cpp within
     65 *    VBoxClient).
     66 *
     67 * Host -> Guest:
    6268 * 1. There are DnD Enter, Move, Leave events which are send exactly like this
    6369 *    to the guest. The info includes the pos, mimetypes and allowed actions.
     
    8692 * Dropping of a directory, means recursively transferring _all_ the content.
    8793 *
    88  * Directories and files are placed into a public visible user directory on the
    89  * guest (~/Documents/VirtualBox Dropped Files). We can't delete them after the
     94 * Directories and files are placed into the user's temporary directory on the
     95 * guest (e.g. /tmp/VirtualBox Dropped Files). We can't delete them after the
    9096 * DnD operation, because we didn't know what the DnD target does with it. E.g.
    9197 * it could just be opened in place. This could lead ofc to filling up the disk
     
    111117 * Cancel is supported in both directions and cleans up all previous steps
    112118 * (thats is: deleting already transfered dirs/files).
    113  *
    114  * There are a lot of DO (debug output) calls in the code. This could be
    115  * disabled, but should be removed (or replaced by Log calls) when this is
    116  * nearly finished.
    117  *
    118  * For Windows guests there could be different communication become necessary.
    119  * So the current interface isn't set in stone and should be made public only,
    120  * after someone had deeply looked into the Win guest support. See
    121  * http://www.catch22.net/tuts/dragdrop for a start.
    122  *
    123  * How to test:
    124  * First set VBOX_WITH_DRAG_AND_DROP=1 in LocalConfig.kmk. The best is if the
    125  * host match the guest OS arch. Just build the tree and point a shared folder
    126  * within the guest to the additions subfolder in bin. Start the guest and
    127  * execute ./VBoxClient --dragandrop --nodaemon within this shared folder. You
    128  * should now be able of dragging text or files to the guest. I used a 64bit
    129  * Linux for both the host and the guest. If the archs don't match, you need to
    130  * first setup a build environment in the guest ofc.
    131119 *
    132120 * In general I propose the following changes in the VBox HGCM infrastructure
     
    152140 * Todo:
    153141 * - Dragging out of the guest (partly done)
    154  *   - ESC doesn't really work
     142 *   - ESC doesn't really work (on Windows guests it's already implemented)
    155143 *   - transfer of URIs (that is the files and patching of the data)
    156144 *   - testing in a multi monitor setup
     
    230218
    231219    void adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const;
    232     void hostCall(const char* psczFunction, uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;
     220    void hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;
    233221
    234222    /* Static helper */
     
    254242/* What mime-types are supported by VirtualBox.
    255243 * Note: If you add something here, make sure you test it with all guest OS's!
     244 ** @todo Make this MIME list configurable / extendable (by extra data?). Currently
     245 *        this is done hardcoded on every guest platform (POSIX/Windows).
    256246 */
    257247/* static */
     
    296286int DnDGuestResponse::waitForGuestResponse()
    297287{
    298     return RTSemEventWait(m_EventSem, 300);
     288    int vrc = RTSemEventWait(m_EventSem, 300);
     289#ifdef DEBUG_andy
     290    LogFlowFunc(("rc=%Rrc\n", vrc));
     291#endif
     292    return vrc;
    299293}
    300294
     
    340334int DnDGuestResponse::setProgress(unsigned uPercentage, uint32_t uState, int rcOp /* = VINF_SUCCESS */)
    341335{
     336    LogFlowFunc(("uPercentage=%RU32, uState=%ld, rcOp=%Rrc\n", uPercentage, uState, rcOp));
     337
    342338    int vrc = VINF_SUCCESS;
    343     HRESULT rc;
    344339    if (!m_progress.isNull())
    345340    {
    346341        BOOL fCompleted;
    347         rc = m_progress->COMGETTER(Completed)(&fCompleted);
     342        HRESULT rc = m_progress->COMGETTER(Completed)(&fCompleted);
    348343        if (!fCompleted)
    349344        {
    350345            if (uState == DragAndDropSvc::DND_PROGRESS_ERROR)
     346            {
    351347                rc = m_progress->notifyComplete(E_FAIL,
    352348                                                COM_IIDOF(IGuest),
    353349                                                m_parent->getComponentName(),
    354350                                                m_parent->tr("Guest error (%Rrc)"), rcOp);
     351            }
    355352            else if (uState == DragAndDropSvc::DND_PROGRESS_CANCELLED)
    356                 rc = m_progress->notifyComplete(S_OK);
    357             else
     353            {
     354                rc = m_progress->Cancel();
     355                vrc = VERR_CANCELLED;
     356            }
     357            else /* uState == DragAndDropSvc::DND_PROGRESS_RUNNING */
    358358            {
    359359                rc = m_progress->SetCurrentOperationProgress(uPercentage);
     360#ifndef DEBUG_andy
     361                Assert(SUCCEEDED(rc));
     362#endif
    360363                if (   uState      == DragAndDropSvc::DND_PROGRESS_COMPLETE
    361364                    || uPercentage >= 100)
    362365                    rc = m_progress->notifyComplete(S_OK);
    363366            }
     367#ifndef DEBUG_andy
     368            Assert(SUCCEEDED(rc));
     369#endif
    364370        }
    365         BOOL fCanceled = FALSE;
    366         rc = m_progress->COMGETTER(Canceled)(&fCanceled);
    367         if (fCanceled)
    368             vrc = VERR_CANCELLED;
    369     }
     371    }
     372
    370373    return vrc;
    371374}
     
    391394}
    392395
    393 void GuestDnDPrivate::hostCall(const char* psczFunction, uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
    394 {
    395     VMMDev *vmmDev = 0;
     396void GuestDnDPrivate::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
     397{
     398    VMMDev *vmmDev = NULL;
    396399    {
    397400        /* Make sure mParent is valid, so set the read lock while using.
     
    409412                          p->tr("VMM device is not available (is the VM running?)"));
    410413
    411     LogFlowFunc(("hgcmHostCall msg=%s; numParms=%u\n", psczFunction, u32Function));
     414    LogFlowFunc(("hgcmHostCall msg=%RU32, numParms=%RU32\n", u32Function, cParms));
    412415    int vrc = vmmDev->hgcmHostCall("VBoxDragAndDropSvc",
    413416                                   u32Function,
     
    576579        paParms[i++].setUInt32(strFormats.length() + 1);
    577580
    578         d->hostCall("HOST_DND_HG_EVT_ENTER",
    579                     DragAndDropSvc::HOST_DND_HG_EVT_ENTER,
     581        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_ENTER,
    580582                    i,
    581583                    paParms);
     
    588590        /* Copy the response info */
    589591        *pResultAction = d->toMainAction(pDnD->defAction());
     592        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    590593    }
    591594    catch (HRESULT rc2)
     
    636639        paParms[i++].setUInt32(strFormats.length() + 1);
    637640
    638         d->hostCall("HOST_DND_HG_EVT_MOVE",
    639                     DragAndDropSvc::HOST_DND_HG_EVT_MOVE,
     641        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_MOVE,
    640642                    i,
    641643                    paParms);
     
    648650        /* Copy the response info */
    649651        *pResultAction = d->toMainAction(pDnD->defAction());
     652        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    650653    }
    651654    catch (HRESULT rc2)
     
    666669    try
    667670    {
    668         d->hostCall("HOST_DND_HG_EVT_LEAVE",
    669                     DragAndDropSvc::HOST_DND_HG_EVT_LEAVE,
     671        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_LEAVE,
    670672                    0,
    671673                    NULL);
     
    722724        paParms[i++].setUInt32(strFormats.length() + 1);
    723725
    724         d->hostCall("HOST_DND_HG_EVT_DROPPED",
    725                     DragAndDropSvc::HOST_DND_HG_EVT_DROPPED,
     726        d->hostCall(DragAndDropSvc::HOST_DND_HG_EVT_DROPPED,
    726727                    i,
    727728                    paParms);
     
    735736        *pResultAction = d->toMainAction(pDnD->defAction());
    736737        Bstr(pDnD->format()).cloneTo(pstrFormat);
     738
     739        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    737740    }
    738741    catch (HRESULT rc2)
     
    768771        pDnD->resetProgress(p);
    769772
    770         d->hostCall("HOST_DND_HG_SND_DATA",
    771                     DragAndDropSvc::HOST_DND_HG_SND_DATA,
     773        d->hostCall(DragAndDropSvc::HOST_DND_HG_SND_DATA,
    772774                    i,
    773775                    paParms);
     
    801803        paParms[i++].setUInt32(uScreenId);
    802804
    803         d->hostCall("HOST_DND_GH_REQ_PENDING",
    804                     DragAndDropSvc::HOST_DND_GH_REQ_PENDING,
     805        d->hostCall(DragAndDropSvc::HOST_DND_GH_REQ_PENDING,
    805806                    i,
    806807                    paParms);
     
    855856        pDnD->resetProgress(p);
    856857
    857         d->hostCall("HOST_DND_GH_EVT_DROPPED",
    858                     DragAndDropSvc::HOST_DND_GH_EVT_DROPPED,
     858        d->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED,
    859859                    i,
    860860                    paParms);
     
    902902DECLCALLBACK(int) GuestDnD::notifyGuestDragAndDropEvent(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms)
    903903{
     904    LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
     905                 pvExtension, u32Function, pvParms, cbParms));
     906
    904907    ComObjPtr<Guest> pGuest = reinterpret_cast<Guest*>(pvExtension);
    905908    if (!pGuest->m_pGuestDnD)
     
    909912    const ComObjPtr<Guest> &p = d->p;
    910913
    911     DnDGuestResponse *pDnD = d->response();
    912     if (pDnD == NULL)
     914    DnDGuestResponse *pResp = d->response();
     915    if (pResp == NULL)
    913916        return VERR_INVALID_PARAMETER;
    914917
     
    922925            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGACKOPDATA) == cbParms, VERR_INVALID_PARAMETER);
    923926            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_ACK_OP == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    924             pDnD->setDefAction(pCBData->uAction);
    925             rc = pDnD->notifyAboutGuestResponse();
     927            pResp->setDefAction(pCBData->uAction);
     928            rc = pResp->notifyAboutGuestResponse();
    926929            break;
    927930        }
     
    932935            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGREQDATADATA) == cbParms, VERR_INVALID_PARAMETER);
    933936            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_REQ_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    934             pDnD->setFormat(pCBData->pszFormat);
    935             rc = pDnD->notifyAboutGuestResponse();
     937            pResp->setFormat(pCBData->pszFormat);
     938            rc = pResp->notifyAboutGuestResponse();
    936939            break;
    937940        }
     
    942945            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBHGEVTPROGRESSDATA) == cbParms, VERR_INVALID_PARAMETER);
    943946            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_HG_EVT_PROGRESS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    944             rc = pDnD->setProgress(pCBData->uPercentage, pCBData->uState);
     947            rc = pResp->setProgress(pCBData->uPercentage, pCBData->uState, pCBData->rc);
    945948            break;
    946949        }
     
    952955            AssertReturn(sizeof(DragAndDropSvc::VBOXDNDCBGHACKPENDINGDATA) == cbParms, VERR_INVALID_PARAMETER);
    953956            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_ACK_PENDING == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    954             pDnD->setFormat(pCBData->pszFormat);
    955             pDnD->setDefAction(pCBData->uDefAction);
    956             pDnD->setAllActions(pCBData->uAllActions);
    957             rc = pDnD->notifyAboutGuestResponse();
     957            pResp->setFormat(pCBData->pszFormat);
     958            pResp->setDefAction(pCBData->uDefAction);
     959            pResp->setAllActions(pCBData->uAllActions);
     960            rc = pResp->notifyAboutGuestResponse();
    958961            break;
    959962        }
     
    965968            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_SND_DATA == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    966969            uint32_t cbCurSize = 0;
    967             pDnD->addData(pCBData->pvData, pCBData->cbData, &cbCurSize);
    968             rc = pDnD->setProgress(100.0 / pCBData->cbAllSize * cbCurSize, (pCBData->cbAllSize == cbCurSize ? DragAndDropSvc::DND_PROGRESS_COMPLETE : DragAndDropSvc::DND_PROGRESS_RUNNING));
     970            pResp->addData(pCBData->pvData, pCBData->cbData, &cbCurSize);
     971            rc = pResp->setProgress(100.0 / pCBData->cbAllSize * cbCurSize, (pCBData->cbAllSize == cbCurSize ? DragAndDropSvc::DND_PROGRESS_COMPLETE : DragAndDropSvc::DND_PROGRESS_RUNNING));
    969972            /* Todo: for now we instantly confirm the cancel. Check if the
    970973             * guest should first clean up stuff itself and than really confirm
    971974             * the cancel request by an extra message. */
    972975            if (rc == VERR_CANCELLED)
    973                 pDnD->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED);
     976                pResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_CANCELLED);
    974977            break;
    975978        }
     
    981984            AssertReturn(DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
    982985            /* Cleanup */
    983             pDnD->resetData();
    984             rc = pDnD->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
     986            pResp->resetData();
     987            rc = pResp->setProgress(100, DragAndDropSvc::DND_PROGRESS_ERROR, pCBData->rc);
    985988            break;
    986989        }
    987990#endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    988         default: AssertMsgFailedReturn(("Function %u not recognized!\n", u32Function), VERR_INVALID_PARAMETER); break;
    989     }
    990 
     991        default:
     992            AssertMsgFailedReturn(("Function %RU32 not supported\n", u32Function), VERR_NOT_SUPPORTED);
     993            break;
     994    }
     995
     996    LogFlowFunc(("Returning rc=%Rrc\n", rc));
    991997    return rc;
    992998}
  • trunk/tools/bin/gen-slickedit-workspace.sh

    r49226 r49891  
    146146            ;;
    147147    esac
    148     if test -n "$3"; 
     148    if test -n "$3";
    149149    then
    150150        MY_FOLDER="$1-$3.lst"
     
    225225            if test -d "${f}";
    226226            then
    227                 if test -z "${MY_OPT_USE_WILDCARDS}"; 
     227                if test -z "${MY_OPT_USE_WILDCARDS}";
    228228                then
    229229                    my_sub_tree "${MY_FILE}" "${f}"
    230230                else
    231231                    case "${f}" in
    232                         ${MY_ROOT_DIR}/include*) 
     232                        ${MY_ROOT_DIR}/include*)
    233233                            my_sub_tree "${MY_FILE}" "${f}" "Headers"
    234234                            ;;
    235                         *)  my_wildcard "${MY_FILE}" "${f}" 
     235                        *)  my_wildcard "${MY_FILE}" "${f}"
    236236                            ;;
    237237                    esac
     
    257257    if test -s "${MY_FILE}-Headers.lst";
    258258    then
    259         if test -z "${MY_OPT_USE_WILDCARDS}"; 
     259        if test -z "${MY_OPT_USE_WILDCARDS}";
    260260        then
    261261            echo '        <Folder Name="Headers"  Filters="*.h;*.hpp">' >> "${MY_FILE}"
     
    908908# src/VBox/HostServices
    909909my_generate_project "GuestCntl"     "src/VBox/HostServices/GuestControl"    --begin-incs "include" "src/VBox/HostServices/GuestControl"     --end-includes "src/VBox/HostServices/GuestControl"
     910my_generate_project "DragAndDrop"   "src/VBox/HostServices/DragAndDrop"     --begin-incs "include" "src/VBox/HostServices/DragAndDrop"      --end-includes "src/VBox/HostServices/DragAndDrop"
    910911my_generate_project "GuestProps"    "src/VBox/HostServices/GuestProperties" --begin-incs "include" "src/VBox/HostServices/GuestProperties"  --end-includes "src/VBox/HostServices/GuestProperties"
    911912my_generate_project "ShClip-HS"     "src/VBox/HostServices/SharedClipboard" --begin-incs "include" "src/VBox/HostServices/SharedClipboard"  --end-includes "src/VBox/HostServices/SharedClipboard"
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