VirtualBox

Changeset 95836 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 26, 2022 4:16:02 PM (2 years ago)
Author:
vboxsync
Message:

DnD/VBoxTray: Resolved some @todos (use dedicated init functions) + fixed a memory leak in VBoxDnDDataObject. Added missing documentation. bugref:10267

Location:
trunk/src/VBox/Additions/WINNT/VBoxTray
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDataObject.cpp

    r95824 r95836  
    3333#include "VBoxDnD.h"
    3434
    35 #ifdef DEBUG
    36   /* Enable the following line to get much more debug output about
    37    * (un)known clipboard formats. */
    38 //# define VBOX_DND_DEBUG_FORMATS
    39 #endif
    4035
    4136/** @todo Implement IDataObjectAsyncCapability interface? */
     
    5146    , m_cbData(0)
    5247{
    53 
    54     /*
    55      * Allocate arrays for format related stuff.
    56      */
    57     /** @todo r=bird: Use an init function */
    58     int   rc = VERR_NO_MEMORY;
    59     ULONG cFixedFormats = 1;
    60     ULONG cAllFormats   = cFormats + cFixedFormats;
    61     m_paFormatEtc = (LPFORMATETC)RTMemAllocZ(sizeof(m_paFormatEtc[0]) * cAllFormats);
    62     if (m_paFormatEtc)
    63     {
    64         m_paStgMedium = (LPSTGMEDIUM)RTMemAllocZ(sizeof(m_paStgMedium[0]) * cAllFormats);
    65         if (m_EvtDropped)
    66         {
    67 
    68             /*
    69              * Registration of dynamic formats needed?
    70              */
    71             LogFlowFunc(("%RU32 dynamic formats\n", cFormats));
    72             if (cFormats)
    73             {
    74                 AssertPtr(pFormatEtc);
    75                 AssertPtr(pStgMed);
    76 
    77                 for (ULONG i = 0; i < cFormats; i++)
    78                 {
    79                     LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n",
    80                                  i, pFormatEtc[i].cfFormat, pFormatEtc[i].tymed, pFormatEtc[i].dwAspect));
    81                     m_paFormatEtc[i] = pFormatEtc[i];
    82                     m_paStgMedium[i] = pStgMed[i];
    83                 }
    84             }
    85 
    86             rc = RTSemEventCreate(&m_EvtDropped);
    87             AssertRCStmt(rc, m_EvtDropped = NIL_RTSEMEVENT);
    88 
    89             /*
    90              * Register fixed formats.
    91              */
    92 #if 0
    93             /* CF_HDROP. */
    94             RegisterFormat(&mpFormatEtc[cFormats], CF_HDROP);
    95             mpStgMedium[cFormats++].tymed = TYMED_HGLOBAL;
    96 
    97             /* IStream. */
    98             RegisterFormat(&mpFormatEtc[cFormats++],
    99                            RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR));
    100             RegisterFormat(&mpFormatEtc[cFormats++],
    101                            RegisterClipboardFormat(CFSTR_FILECONTENTS),
    102                            TYMED_ISTREAM, 0 /* lIndex */);
    103 
    104             /* Required for e.g. Windows Media Player. */
    105             RegisterFormat(&mpFormatEtc[cFormats++],
    106                            RegisterClipboardFormat(CFSTR_FILENAME));
    107             RegisterFormat(&mpFormatEtc[cFormats++],
    108                            RegisterClipboardFormat(CFSTR_FILENAMEW));
    109             RegisterFormat(&mpFormatEtc[cFormats++],
    110                            RegisterClipboardFormat(CFSTR_SHELLIDLIST));
    111             RegisterFormat(&mpFormatEtc[cFormats++],
    112                            RegisterClipboardFormat(CFSTR_SHELLIDLISTOFFSET));
    113 #endif
    114             m_cFormats  = cFormats;
    115             m_enmStatus = Status_Initialized;
    116         }
    117     }
    118     LogFlowFunc(("cFormats=%RU32 - %Rrc!\n", cFormats, rc));
     48    int rc2 = Init(pFormatEtc, pStgMed, cFormats);
     49    AssertRC(rc2);
    11950}
    12051
    12152VBoxDnDDataObject::~VBoxDnDDataObject(void)
    12253{
    123     if (m_paFormatEtc)
    124     {
    125         RTMemFree(m_paFormatEtc);
    126         m_paFormatEtc = NULL;
    127     }
    128 
    129     if (m_paStgMedium)
    130     {
    131         RTMemFree(m_paStgMedium);
    132         m_paStgMedium = NULL;
    133     }
    134 
    135     if (m_pvData)
    136     {
    137         RTMemFree(m_pvData);
    138         m_pvData = NULL;
    139     }
    140 
    141     LogFlowFunc(("mRefCount=%RI32\n", m_cRefs));
     54    int rc2 = Destroy();
     55    AssertRC(rc2);
    14256}
    14357
     
    14862STDMETHODIMP_(ULONG) VBoxDnDDataObject::AddRef(void)
    14963{
     64    AssertReturn(m_cRefs < 32, m_cRefs); /* Paranoia. */
    15065    return InterlockedIncrement(&m_cRefs);
    15166}
     
    15368STDMETHODIMP_(ULONG) VBoxDnDDataObject::Release(void)
    15469{
     70    AssertReturn(m_cRefs > 0, 0);
    15571    LONG lCount = InterlockedDecrement(&m_cRefs);
    15672    if (lCount == 0)
     
    477393 * Own stuff.
    478394 */
     395
     396int VBoxDnDDataObject::Init(LPFORMATETC pFormatEtc, LPSTGMEDIUM pStgMed, ULONG cFormats)
     397{
     398    AssertReturn(m_enmStatus == Status_Uninitialized, VERR_WRONG_ORDER);
     399
     400    int rc = RTSemEventCreate(&m_EvtDropped);
     401    AssertRCReturn(rc, rc);
     402
     403    /*
     404     * Allocate arrays for format related stuff.
     405     */
     406    ULONG cFixedFormats = 1;
     407    ULONG cAllFormats   = cFormats + cFixedFormats;
     408    m_paFormatEtc = (LPFORMATETC)RTMemAllocZ(sizeof(m_paFormatEtc[0]) * cAllFormats);
     409    if (m_paFormatEtc)
     410    {
     411        m_paStgMedium = (LPSTGMEDIUM)RTMemAllocZ(sizeof(m_paStgMedium[0]) * cAllFormats);
     412        if (m_EvtDropped)
     413        {
     414            /*
     415             * Registration of dynamic formats needed?
     416             */
     417            LogFlowFunc(("%RU32 dynamic formats\n", cFormats));
     418            if (cFormats)
     419            {
     420                AssertPtr(pFormatEtc);
     421                AssertPtr(pStgMed);
     422
     423                for (ULONG i = 0; i < cFormats; i++)
     424                {
     425                    LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n",
     426                                 i, pFormatEtc[i].cfFormat, pFormatEtc[i].tymed, pFormatEtc[i].dwAspect));
     427                    m_paFormatEtc[i] = pFormatEtc[i];
     428                    m_paStgMedium[i] = pStgMed[i];
     429                }
     430            }
     431
     432            /*
     433             * Register fixed formats.
     434             */
     435#if 0
     436            /* CF_HDROP. */
     437            RegisterFormat(&mpFormatEtc[cFormats], CF_HDROP);
     438            mpStgMedium[cFormats++].tymed = TYMED_HGLOBAL;
     439
     440            /* IStream. */
     441            RegisterFormat(&mpFormatEtc[cFormats++],
     442                           RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR));
     443            RegisterFormat(&mpFormatEtc[cFormats++],
     444                           RegisterClipboardFormat(CFSTR_FILECONTENTS),
     445                           TYMED_ISTREAM, 0 /* lIndex */);
     446
     447            /* Required for e.g. Windows Media Player. */
     448            RegisterFormat(&mpFormatEtc[cFormats++],
     449                           RegisterClipboardFormat(CFSTR_FILENAME));
     450            RegisterFormat(&mpFormatEtc[cFormats++],
     451                           RegisterClipboardFormat(CFSTR_FILENAMEW));
     452            RegisterFormat(&mpFormatEtc[cFormats++],
     453                           RegisterClipboardFormat(CFSTR_SHELLIDLIST));
     454            RegisterFormat(&mpFormatEtc[cFormats++],
     455                           RegisterClipboardFormat(CFSTR_SHELLIDLISTOFFSET));
     456#endif
     457            m_cFormats  = cFormats;
     458            m_enmStatus = Status_Initialized;
     459        }
     460        else
     461            rc = VERR_NO_MEMORY;
     462    }
     463    else
     464        rc = VERR_NO_MEMORY;
     465
     466    LogFlowFunc(("cFormats=%RU32 - %Rrc\n", cFormats, rc));
     467    return rc;
     468}
     469
     470int VBoxDnDDataObject::Destroy(void)
     471{
     472    if (m_enmStatus == Status_Uninitialized)
     473        return VINF_SUCCESS;
     474
     475    AssertReturn(m_cRefs == 0, VERR_WRONG_ORDER);
     476
     477    if (m_paFormatEtc)
     478    {
     479        RTMemFree(m_paFormatEtc);
     480        m_paFormatEtc = NULL;
     481    }
     482
     483    if (m_paStgMedium)
     484    {
     485        RTMemFree(m_paStgMedium);
     486        m_paStgMedium = NULL;
     487    }
     488
     489    if (m_pvData)
     490    {
     491        RTMemFree(m_pvData);
     492        m_pvData = NULL;
     493    }
     494
     495    int rc = RTSemEventDestroy(m_EvtDropped);
     496    AssertRCReturn(rc, rc);
     497    m_EvtDropped = NIL_RTSEMEVENT;
     498
     499    m_enmStatus = Status_Uninitialized;
     500
     501    return VINF_SUCCESS;
     502}
    479503
    480504/**
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDEnumFormat.cpp

    r95734 r95836  
    3131
    3232
    33 VBoxDnDEnumFormatEtc::VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats)
     33VBoxDnDEnumFormatEtc::VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal)
    3434    : m_cRefs(1)
    3535    , m_uIdxCur(0)
     
    3838
    3939{
    40     LogFlowFunc(("pFormatEtc=%p, cFormats=%RU32\n", pFormatEtc, cFormats));
    41     /** @todo r=bird: Use an init() function! */
    42     m_paFormatEtc = (LPFORMATETC)RTMemAllocZ(sizeof(*m_paFormatEtc) * cFormats);
    43     if (m_paFormatEtc)
    44     {
    45         for (ULONG i = 0; i < cFormats; i++)
    46         {
    47             LogFlowFunc(("Format %RU32: cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n",
    48                          i, pFormatEtc[i].cfFormat, VBoxDnDDataObject::ClipboardFormatToString(pFormatEtc[i].cfFormat),
    49                          pFormatEtc[i].tymed, pFormatEtc[i].dwAspect));
    50             VBoxDnDEnumFormatEtc::CopyFormat(&m_paFormatEtc[i], &pFormatEtc[i]);
    51         }
    52         m_cFormats = cFormats;
    53     }
    54     else
    55         Log(("Failed to allocate memory for %u formats!\n"));
     40    int rc2 = Init(pFormatEtc, uIdx, cToCopy, cTotal);
     41    AssertRC(rc2);
    5642}
    5743
     
    7460}
    7561
     62/**
     63 * Initializes the class by copying the required formats.
     64 *
     65 * @returns VBox status code.
     66 * @param   pFormatEtc          Format Etc to use for initialization.
     67 * @param   uIdx                Index (zero-based) of format
     68 * @param   cToCopy             Number of formats \a pFormatEtc to copy, starting from \a uIdx.
     69 * @param   cTotal              Number of total formats \a pFormatEtc holds.
     70 */
     71int VBoxDnDEnumFormatEtc::Init(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal)
     72{
     73    AssertPtrReturn(pFormatEtc,            VERR_INVALID_POINTER);
     74    AssertReturn(uIdx <= cTotal,           VERR_INVALID_PARAMETER);
     75    AssertReturn(uIdx + cToCopy <= cTotal, VERR_INVALID_PARAMETER);
     76    /* cFormats can be 0. */
     77
     78    if (!cToCopy)
     79        return VINF_SUCCESS;
     80
     81    AssertReturn(m_paFormatEtc == NULL && m_cFormats == 0, VERR_WRONG_ORDER);
     82
     83    int rc = VINF_SUCCESS;
     84
     85    m_paFormatEtc = (LPFORMATETC)RTMemAllocZ(sizeof(FORMATETC) * cToCopy);
     86    if (m_paFormatEtc)
     87    {
     88        for (ULONG i = 0; i < cToCopy; i++)
     89        {
     90            LPFORMATETC const pFormatCur = &pFormatEtc[uIdx + i];
     91
     92            LogFlowFunc(("Format %RU32 (index %RU32): cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n",
     93                         i, uIdx + i, pFormatCur->cfFormat, VBoxDnDDataObject::ClipboardFormatToString(pFormatCur->cfFormat),
     94                         pFormatCur->tymed, pFormatCur->dwAspect));
     95            VBoxDnDEnumFormatEtc::CopyFormat(&m_paFormatEtc[i], pFormatCur);
     96        }
     97
     98        m_cFormats = cToCopy;
     99    }
     100    else
     101        rc = VERR_NO_MEMORY;
     102    return rc;
     103}
     104
    76105/*
    77106 * IUnknown methods.
     
    153182}
    154183
     184/**
     185 * Copies a format etc from \a pSource to \a aDest (deep copy).
     186 *
     187 * @returns VBox status code.
     188 * @param   pDest               Where to copy \a pSource to.
     189 * @param   pSource             Source to copy.
     190 */
    155191/* static */
    156 void VBoxDnDEnumFormatEtc::CopyFormat(LPFORMATETC pDest, LPFORMATETC pSource)
    157 {
    158     AssertPtrReturnVoid(pDest);
    159     AssertPtrReturnVoid(pSource);
     192int VBoxDnDEnumFormatEtc::CopyFormat(LPFORMATETC pDest, LPFORMATETC pSource)
     193{
     194    AssertPtrReturn(pDest  , VERR_INVALID_POINTER);
     195    AssertPtrReturn(pSource, VERR_INVALID_POINTER);
    160196
    161197    *pDest = *pSource;
     
    164200    {
    165201        pDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
     202        AssertPtrReturn(pDest->ptd, VERR_NO_MEMORY);
    166203        *(pDest->ptd) = *(pSource->ptd);
    167204    }
    168 }
    169 
     205
     206    return VINF_SUCCESS;
     207}
     208
     209/**
     210 * Creates an IEnumFormatEtc interface from a given format etc structure.
     211 *
     212 * @returns HRESULT
     213 * @param   nNumFormats         Number of formats to copy from \a pFormatEtc.
     214 * @param   pFormatEtc          Format etc to use for creation.
     215 * @param   ppEnumFormatEtc     Where to return the created IEnumFormatEtc interface on success.
     216 */
    170217/* static */
    171218HRESULT VBoxDnDEnumFormatEtc::CreateEnumFormatEtc(UINT nNumFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc)
    172219{
    173     AssertReturn(nNumFormats, E_INVALIDARG);
     220    /* cNumFormats can be 0. */
    174221    AssertPtrReturn(pFormatEtc, E_INVALIDARG);
    175222    AssertPtrReturn(ppEnumFormatEtc, E_INVALIDARG);
    176223
    177224#ifdef RT_EXCEPTIONS_ENABLED
    178     try { *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc, nNumFormats); }
     225    try { *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc,
     226                                                      0 /* uIdx */,  nNumFormats /* cToCopy */, nNumFormats /* cTotal */); }
    179227    catch (std::bad_alloc &)
    180228#else
    181     *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc, nNumFormats);
     229    *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc,
     230                                                0 /* uIdx */, nNumFormats /* cToCopy */, nNumFormats /* cTotal */);
    182231    if (!*ppEnumFormatEtc)
    183232#endif
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