Merge branch 'wine-heap-fix'
Wine heap fix and other global memory-related cleanup. See https://github.com/wxWidgets/wxWidgets/pull/2030
This commit is contained in:
@@ -773,6 +773,15 @@ public:
|
|||||||
void *Get() const { return m_ptr; }
|
void *Get() const { return m_ptr; }
|
||||||
operator void *() const { return m_ptr; }
|
operator void *() const { return m_ptr; }
|
||||||
|
|
||||||
|
size_t GetSize() const
|
||||||
|
{
|
||||||
|
const size_t size = ::GlobalSize(m_hGlobal);
|
||||||
|
if ( !size )
|
||||||
|
wxLogLastError(wxT("GlobalSize"));
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HGLOBAL m_hGlobal;
|
HGLOBAL m_hGlobal;
|
||||||
void *m_ptr;
|
void *m_ptr;
|
||||||
|
@@ -245,9 +245,12 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
abs(ds.dsBmih.biHeight);
|
abs(ds.dsBmih.biHeight);
|
||||||
HANDLE hMem;
|
HANDLE hMem;
|
||||||
hMem = ::GlobalAlloc(GHND, ds.dsBmih.biSize + numColors*sizeof(RGBQUAD) + bmpSize);
|
hMem = ::GlobalAlloc(GHND, ds.dsBmih.biSize + numColors*sizeof(RGBQUAD) + bmpSize);
|
||||||
if ( hMem )
|
if ( !hMem )
|
||||||
|
break;
|
||||||
|
|
||||||
{
|
{
|
||||||
char* pDst = (char*)::GlobalLock(hMem);
|
GlobalPtrLock ptr(hMem);
|
||||||
|
char* pDst = (char*)ptr.Get();
|
||||||
memcpy(pDst, &ds.dsBmih, ds.dsBmih.biSize);
|
memcpy(pDst, &ds.dsBmih, ds.dsBmih.biSize);
|
||||||
pDst += ds.dsBmih.biSize;
|
pDst += ds.dsBmih.biSize;
|
||||||
if ( numColors > 0 )
|
if ( numColors > 0 )
|
||||||
@@ -259,9 +262,9 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
pDst += numColors*sizeof(RGBQUAD);
|
pDst += numColors*sizeof(RGBQUAD);
|
||||||
}
|
}
|
||||||
memcpy(pDst, dib.GetData(), bmpSize);
|
memcpy(pDst, dib.GetData(), bmpSize);
|
||||||
::GlobalUnlock(hMem);
|
} // unlock hMem
|
||||||
handle = ::SetClipboardData(CF_DIB, hMem);
|
|
||||||
}
|
handle = ::SetClipboardData(CF_DIB, hMem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -276,14 +279,16 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
{
|
{
|
||||||
wxMetafile *wxMF = (wxMetafile *)data;
|
wxMetafile *wxMF = (wxMetafile *)data;
|
||||||
HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
|
HANDLE data = GlobalAlloc(GHND, sizeof(METAFILEPICT) + 1);
|
||||||
METAFILEPICT *mf = (METAFILEPICT *)GlobalLock(data);
|
{
|
||||||
|
GlobalPtrLock ptr(data);
|
||||||
|
METAFILEPICT *mf = (METAFILEPICT *)data.Get();
|
||||||
|
|
||||||
mf->mm = wxMF->GetWindowsMappingMode();
|
mf->mm = wxMF->GetWindowsMappingMode();
|
||||||
mf->xExt = width;
|
mf->xExt = width;
|
||||||
mf->yExt = height;
|
mf->yExt = height;
|
||||||
mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
|
mf->hMF = (HMETAFILE) wxMF->GetHMETAFILE();
|
||||||
GlobalUnlock(data);
|
wxMF->SetHMETAFILE((WXHANDLE) NULL);
|
||||||
wxMF->SetHMETAFILE((WXHANDLE) NULL);
|
} // unlock data
|
||||||
|
|
||||||
handle = SetClipboardData(CF_METAFILEPICT, data);
|
handle = SetClipboardData(CF_METAFILEPICT, data);
|
||||||
break;
|
break;
|
||||||
@@ -326,11 +331,7 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
|
HANDLE hGlobalMemory = GlobalAlloc(GHND, l);
|
||||||
if ( hGlobalMemory )
|
if ( hGlobalMemory )
|
||||||
{
|
{
|
||||||
LPSTR lpGlobalMemory = (LPSTR)GlobalLock(hGlobalMemory);
|
memcpy(GlobalPtrLock(hGlobalMemory), s, l);
|
||||||
|
|
||||||
memcpy(lpGlobalMemory, s, l);
|
|
||||||
|
|
||||||
GlobalUnlock(hGlobalMemory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = SetClipboardData(dataFormat, hGlobalMemory);
|
handle = SetClipboardData(dataFormat, hGlobalMemory);
|
||||||
@@ -344,9 +345,7 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
HANDLE hGlobalMemory = ::GlobalAlloc(GHND, size);
|
HANDLE hGlobalMemory = ::GlobalAlloc(GHND, size);
|
||||||
if ( hGlobalMemory )
|
if ( hGlobalMemory )
|
||||||
{
|
{
|
||||||
LPWSTR lpGlobalMemory = (LPWSTR)::GlobalLock(hGlobalMemory);
|
memcpy(GlobalPtrLock(hGlobalMemory), s, size);
|
||||||
memcpy(lpGlobalMemory, s, size);
|
|
||||||
::GlobalUnlock(hGlobalMemory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = ::SetClipboardData(CF_UNICODETEXT, hGlobalMemory);
|
handle = ::SetClipboardData(CF_UNICODETEXT, hGlobalMemory);
|
||||||
@@ -407,9 +406,7 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
HGLOBAL hText = GlobalAlloc(GMEM_MOVEABLE |GMEM_DDESHARE, strlen(buf)+4);
|
HGLOBAL hText = GlobalAlloc(GMEM_MOVEABLE |GMEM_DDESHARE, strlen(buf)+4);
|
||||||
|
|
||||||
// Put your string in the global memory...
|
// Put your string in the global memory...
|
||||||
ptr = (char *)GlobalLock(hText);
|
strcpy((char*)GlobalPtrLock(hText).Get(), buf);
|
||||||
strcpy(ptr, buf);
|
|
||||||
GlobalUnlock(hText);
|
|
||||||
|
|
||||||
handle = ::SetClipboardData(gs_htmlcfid, hText);
|
handle = ::SetClipboardData(gs_htmlcfid, hText);
|
||||||
|
|
||||||
@@ -861,11 +858,9 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
if ( hMem )
|
if ( hMem )
|
||||||
{
|
{
|
||||||
wxTextDataObject& textDataObject = (wxTextDataObject &)data;
|
wxTextDataObject& textDataObject = (wxTextDataObject &)data;
|
||||||
const void* buf = ::GlobalLock(hMem);
|
|
||||||
DWORD size = ::GlobalSize(hMem);
|
GlobalPtrLock ptr(hMem);
|
||||||
bool ok = textDataObject.SetData(size, buf);
|
return textDataObject.SetData(ptr.GetSize(), ptr);
|
||||||
::GlobalUnlock(hMem);
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -885,11 +880,9 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
if ( hMem )
|
if ( hMem )
|
||||||
{
|
{
|
||||||
wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
|
wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
|
||||||
const void* buf = ::GlobalLock(hMem);
|
|
||||||
DWORD size = ::GlobalSize(hMem);
|
GlobalPtrLock ptr(hMem);
|
||||||
bool ok = bitmapDataObject.SetData(size, buf);
|
return bitmapDataObject.SetData(ptr.GetSize(), ptr);
|
||||||
::GlobalUnlock(hMem);
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -901,11 +894,9 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
if ( hMem )
|
if ( hMem )
|
||||||
{
|
{
|
||||||
wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
|
wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
|
||||||
const void* buf = ::GlobalLock(hMem);
|
|
||||||
DWORD size = ::GlobalSize(hMem);
|
GlobalPtrLock ptr(hMem);
|
||||||
bool ok = metaFileDataObject.SetData(wxDF_METAFILE, size, buf);
|
return metaFileDataObject.SetData(wxDF_METAFILE, ptr.GetSize(), ptr);
|
||||||
::GlobalUnlock(hMem);
|
|
||||||
return ok;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -266,14 +266,17 @@ static bool wxGetDefaultDeviceName(wxString& deviceName, wxString& portName)
|
|||||||
|
|
||||||
if (pd.hDevNames)
|
if (pd.hDevNames)
|
||||||
{
|
{
|
||||||
lpDevNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
|
{
|
||||||
lpszDeviceName = (LPTSTR)lpDevNames + lpDevNames->wDeviceOffset;
|
GlobalPtrLock ptr(pd.hDevNames);
|
||||||
lpszPortName = (LPTSTR)lpDevNames + lpDevNames->wOutputOffset;
|
|
||||||
|
|
||||||
deviceName = lpszDeviceName;
|
lpDevNames = (LPDEVNAMES)ptr.Get();
|
||||||
portName = lpszPortName;
|
lpszDeviceName = (LPTSTR)lpDevNames + lpDevNames->wDeviceOffset;
|
||||||
|
lpszPortName = (LPTSTR)lpDevNames + lpDevNames->wOutputOffset;
|
||||||
|
|
||||||
|
deviceName = lpszDeviceName;
|
||||||
|
portName = lpszPortName;
|
||||||
|
} // unlock pd.hDevNames
|
||||||
|
|
||||||
GlobalUnlock(pd.hDevNames);
|
|
||||||
GlobalFree(pd.hDevNames);
|
GlobalFree(pd.hDevNames);
|
||||||
pd.hDevNames=NULL;
|
pd.hDevNames=NULL;
|
||||||
}
|
}
|
||||||
|
@@ -95,16 +95,15 @@ HGLOBAL wxGlobalClone(HGLOBAL hglobIn)
|
|||||||
{
|
{
|
||||||
HGLOBAL hglobOut = NULL;
|
HGLOBAL hglobOut = NULL;
|
||||||
|
|
||||||
LPVOID pvIn = GlobalLock(hglobIn);
|
GlobalPtrLock ptrIn(hglobIn);
|
||||||
if (pvIn)
|
if (ptrIn)
|
||||||
{
|
{
|
||||||
SIZE_T cb = GlobalSize(hglobIn);
|
SIZE_T cb = ptrIn.GetSize();
|
||||||
hglobOut = GlobalAlloc(GMEM_FIXED, cb);
|
hglobOut = GlobalAlloc(GMEM_FIXED, cb);
|
||||||
if (hglobOut)
|
if (hglobOut)
|
||||||
{
|
{
|
||||||
CopyMemory(hglobOut, pvIn, cb);
|
CopyMemory(hglobOut, ptrIn, cb);
|
||||||
}
|
}
|
||||||
GlobalUnlock(hglobIn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hglobOut;
|
return hglobOut;
|
||||||
@@ -637,27 +636,18 @@ STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc,
|
|||||||
case TYMED_HGLOBAL:
|
case TYMED_HGLOBAL:
|
||||||
{
|
{
|
||||||
// copy data
|
// copy data
|
||||||
HGLOBAL hGlobal = pmedium->hGlobal;
|
GlobalPtrLock ptr(pmedium->hGlobal);
|
||||||
void *pBuf = GlobalLock(hGlobal);
|
if ( !ptr )
|
||||||
if ( pBuf == NULL ) {
|
|
||||||
wxLogLastError(wxT("GlobalLock"));
|
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
wxDataFormat format = pformatetc->cfFormat;
|
wxDataFormat format = pformatetc->cfFormat;
|
||||||
|
|
||||||
// possibly put the size in the beginning of the buffer
|
// possibly put the size in the beginning of the buffer
|
||||||
pBuf = m_pDataObject->SetSizeInBuffer
|
void* const pBuf =
|
||||||
(
|
m_pDataObject->SetSizeInBuffer(ptr, ptr.GetSize(), format);
|
||||||
pBuf,
|
|
||||||
::GlobalSize(hGlobal),
|
|
||||||
format
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( !m_pDataObject->GetDataHere(format, pBuf) )
|
if ( !m_pDataObject->GetDataHere(format, pBuf) )
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
GlobalUnlock(hGlobal);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -713,12 +703,9 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copy data
|
// copy data
|
||||||
const void *pBuf = GlobalLock(pmedium->hGlobal);
|
GlobalPtrLock ptr(pmedium->hGlobal);
|
||||||
if ( pBuf == NULL ) {
|
if ( !ptr )
|
||||||
wxLogLastError(wxT("GlobalLock"));
|
|
||||||
|
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
// we've got a problem with SetData() here because the base
|
// we've got a problem with SetData() here because the base
|
||||||
// class version requires the size parameter which we don't
|
// class version requires the size parameter which we don't
|
||||||
@@ -731,14 +718,14 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
|
|||||||
case wxDF_HTML:
|
case wxDF_HTML:
|
||||||
case CF_TEXT:
|
case CF_TEXT:
|
||||||
case CF_OEMTEXT:
|
case CF_OEMTEXT:
|
||||||
size = strlen((const char *)pBuf);
|
size = strlen((const char *)ptr.Get());
|
||||||
break;
|
break;
|
||||||
#if !(defined(__BORLANDC__) && (__BORLANDC__ < 0x500))
|
#if !(defined(__BORLANDC__) && (__BORLANDC__ < 0x500))
|
||||||
case CF_UNICODETEXT:
|
case CF_UNICODETEXT:
|
||||||
#if ( defined(__BORLANDC__) && (__BORLANDC__ > 0x530) )
|
#if ( defined(__BORLANDC__) && (__BORLANDC__ > 0x530) )
|
||||||
size = std::wcslen((const wchar_t *)pBuf) * sizeof(wchar_t);
|
size = std::wcslen((const wchar_t *)ptr.Get()) * sizeof(wchar_t);
|
||||||
#else
|
#else
|
||||||
size = wxWcslen((const wchar_t *)pBuf) * sizeof(wchar_t);
|
size = wxWcslen((const wchar_t *)ptr.Get()) * sizeof(wchar_t);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -758,19 +745,24 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
|
|||||||
case CF_METAFILEPICT:
|
case CF_METAFILEPICT:
|
||||||
size = sizeof(METAFILEPICT);
|
size = sizeof(METAFILEPICT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pBuf = m_pDataObject->
|
size = ptr.GetSize();
|
||||||
GetSizeFromBuffer(pBuf, &size, format);
|
|
||||||
size -= m_pDataObject->GetBufferOffset(format);
|
// Account for the possible offset.
|
||||||
|
const size_t
|
||||||
|
ofs = m_pDataObject->GetBufferOffset(format);
|
||||||
|
|
||||||
|
// Check that it has a reasonable value to avoid
|
||||||
|
// overflow.
|
||||||
|
if ( ofs > size )
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
|
size -= ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = m_pDataObject->SetData(format, size, pBuf);
|
if ( !m_pDataObject->SetData(format, size, ptr.Get()) )
|
||||||
|
|
||||||
GlobalUnlock(pmedium->hGlobal);
|
|
||||||
|
|
||||||
if ( !ok ) {
|
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -975,14 +967,10 @@ const void *wxDataObject::GetSizeFromBuffer(const void *buffer,
|
|||||||
size_t *size,
|
size_t *size,
|
||||||
const wxDataFormat& WXUNUSED(format))
|
const wxDataFormat& WXUNUSED(format))
|
||||||
{
|
{
|
||||||
// hack: the third parameter is declared non-const in Wine's headers so
|
const size_t realsz = ::GlobalSize(::GlobalHandle(buffer));
|
||||||
// cast away the const
|
if ( !realsz )
|
||||||
const size_t realsz = ::HeapSize(::GetProcessHeap(), 0,
|
|
||||||
const_cast<void*>(buffer));
|
|
||||||
if ( realsz == (size_t)-1 )
|
|
||||||
{
|
{
|
||||||
// note that HeapSize() does not set last error
|
wxLogLastError(wxT("GlobalSize"));
|
||||||
wxLogApiError(wxT("HeapSize"), 0);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -147,7 +147,9 @@ wxCreateDevNames(const wxString& driverName,
|
|||||||
( driverName.length() + 1 +
|
( driverName.length() + 1 +
|
||||||
printerName.length() + 1 +
|
printerName.length() + 1 +
|
||||||
portName.length()+1 ) * sizeof(wxChar) );
|
portName.length()+1 ) * sizeof(wxChar) );
|
||||||
LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(hDev);
|
|
||||||
|
GlobalPtrLock ptr(hDev);
|
||||||
|
LPDEVNAMES lpDev = (LPDEVNAMES)ptr.Get();
|
||||||
lpDev->wDriverOffset = sizeof(WORD) * 4 / sizeof(wxChar);
|
lpDev->wDriverOffset = sizeof(WORD) * 4 / sizeof(wxChar);
|
||||||
wxStrcpy((wxChar*)lpDev + lpDev->wDriverOffset, driverName);
|
wxStrcpy((wxChar*)lpDev + lpDev->wDriverOffset, driverName);
|
||||||
|
|
||||||
@@ -160,8 +162,6 @@ wxCreateDevNames(const wxString& driverName,
|
|||||||
wxStrcpy((wxChar*)lpDev + lpDev->wOutputOffset, portName);
|
wxStrcpy((wxChar*)lpDev + lpDev->wOutputOffset, portName);
|
||||||
|
|
||||||
lpDev->wDefault = 0;
|
lpDev->wDefault = 0;
|
||||||
|
|
||||||
GlobalUnlock(hDev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hDev;
|
return hDev;
|
||||||
|
Reference in New Issue
Block a user