[OLE32] Sync with Wine 3.0. CORE-14225

This commit is contained in:
Amine Khaldi 2018-01-20 12:57:25 +01:00
parent d4c87f7aa8
commit 2178977b54
12 changed files with 828 additions and 524 deletions

View file

@ -1702,12 +1702,6 @@ HWND apartment_getwindow(const struct apartment *apt)
return apt->win;
}
void apartment_joinmta(void)
{
apartment_addref(MTA);
COM_CurrentInfo()->apt = MTA;
}
static void COM_TlsDestroy(void)
{
struct oletls *info = NtCurrentTeb()->ReservedForOle;
@ -1812,6 +1806,40 @@ HRESULT WINAPI CoRevokeInitializeSpy(ULARGE_INTEGER cookie)
return S_OK;
}
HRESULT enter_apartment( struct oletls *info, DWORD model )
{
HRESULT hr = S_OK;
if (!info->apt)
{
if (!apartment_get_or_create( model ))
return E_OUTOFMEMORY;
}
else if (!apartment_is_model( info->apt, model ))
{
WARN( "Attempt to change threading model of this apartment from %s to %s\n",
info->apt->multi_threaded ? "multi-threaded" : "apartment threaded",
model & COINIT_APARTMENTTHREADED ? "apartment threaded" : "multi-threaded" );
return RPC_E_CHANGED_MODE;
}
else
hr = S_FALSE;
info->inits++;
return hr;
}
void leave_apartment( struct oletls *info )
{
if (!--info->inits)
{
if (info->ole_inits)
WARN( "Uninitializing apartment while Ole is still initialized\n" );
apartment_release( info->apt );
info->apt = NULL;
}
}
/******************************************************************************
* CoInitialize [OLE32.@]
@ -1870,8 +1898,7 @@ HRESULT WINAPI CoInitialize(LPVOID lpReserved)
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
{
struct oletls *info = COM_CurrentInfo();
HRESULT hr = S_OK;
APARTMENT *apt;
HRESULT hr;
TRACE("(%p, %x)\n", lpReserved, (int)dwCoInit);
@ -1900,24 +1927,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoIni
if (info->spy)
IInitializeSpy_PreInitialize(info->spy, dwCoInit, info->inits);
if (!(apt = info->apt))
{
apt = apartment_get_or_create(dwCoInit);
if (!apt) return E_OUTOFMEMORY;
}
else if (!apartment_is_model(apt, dwCoInit))
{
/* Changing the threading model after it's been set is illegal. If this warning is triggered by Wine
code then we are probably using the wrong threading model to implement that API. */
ERR("Attempt to change threading model of this apartment from %s to %s\n",
apt->multi_threaded ? "multi-threaded" : "apartment threaded",
dwCoInit & COINIT_APARTMENTTHREADED ? "apartment threaded" : "multi-threaded");
return RPC_E_CHANGED_MODE;
}
else
hr = S_FALSE;
info->inits++;
hr = enter_apartment( info, dwCoInit );
if (info->spy)
IInitializeSpy_PostInitialize(info->spy, hr, dwCoInit, info->inits);
@ -1964,13 +1974,7 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
return;
}
if (!--info->inits)
{
if (info->ole_inits)
WARN("uninitializing apartment while Ole is still initialized\n");
apartment_release(info->apt);
info->apt = NULL;
}
leave_apartment( info );
/*
* Decrease the reference count.

View file

@ -233,8 +233,8 @@ static inline HRESULT apartment_getoxid(const struct apartment *apt, OXID *oxid)
}
HRESULT apartment_createwindowifneeded(struct apartment *apt) DECLSPEC_HIDDEN;
HWND apartment_getwindow(const struct apartment *apt) DECLSPEC_HIDDEN;
void apartment_joinmta(void) DECLSPEC_HIDDEN;
HRESULT enter_apartment(struct oletls *info, DWORD model) DECLSPEC_HIDDEN;
void leave_apartment(struct oletls *info) DECLSPEC_HIDDEN;
/* DCOM messages used by the apartment window (not compatible with native) */
#define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */

View file

@ -64,7 +64,8 @@ typedef struct PresentationDataHeader
* DWORD length;
* CHAR format_name[length]; (null-terminated)
*/
DWORD unknown3; /* 4, possibly TYMED_ISTREAM */
DWORD tdSize; /* This is actually a truncated DVTARGETDEVICE, if tdSize > sizeof(DWORD)
then there are tdSize - sizeof(DWORD) more bytes before dvAspect */
DVASPECT dvAspect;
DWORD lindex;
DWORD advf;
@ -86,8 +87,6 @@ typedef struct DataCacheEntry
struct list entry;
/* format of this entry */
FORMATETC fmtetc;
/* the clipboard format of the data */
CLIPFORMAT data_cf;
/* cached data */
STGMEDIUM stgmedium;
/*
@ -295,10 +294,10 @@ static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FOR
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
{
/* FIXME: also compare DVTARGETDEVICEs */
if ((!cache_entry->fmtetc.cfFormat || !fmt.cfFormat || (fmt.cfFormat == cache_entry->fmtetc.cfFormat)) &&
if ((fmt.cfFormat == cache_entry->fmtetc.cfFormat) &&
(fmt.dwAspect == cache_entry->fmtetc.dwAspect) &&
(fmt.lindex == cache_entry->fmtetc.lindex) &&
(!cache_entry->fmtetc.tymed || !fmt.tymed || (fmt.tymed == cache_entry->fmtetc.tymed)))
((fmt.tymed == cache_entry->fmtetc.tymed) || !cache_entry->fmtetc.cfFormat)) /* tymed is ignored for view caching */
return cache_entry;
}
return NULL;
@ -307,19 +306,23 @@ static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FOR
/* checks that the clipformat and tymed are valid and returns an error if they
* aren't and CACHE_S_NOTSUPPORTED if they are valid, but can't be rendered by
* DataCache_Draw */
static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed)
static HRESULT check_valid_formatetc( const FORMATETC *fmt )
{
if (!cfFormat || !tymed ||
(cfFormat == CF_METAFILEPICT && tymed == TYMED_MFPICT) ||
(cfFormat == CF_BITMAP && tymed == TYMED_GDI) ||
(cfFormat == CF_DIB && tymed == TYMED_HGLOBAL) ||
(cfFormat == CF_ENHMETAFILE && tymed == TYMED_ENHMF))
/* DVASPECT_ICON must be CF_METAFILEPICT */
if (fmt->dwAspect == DVASPECT_ICON && fmt->cfFormat != CF_METAFILEPICT)
return DV_E_FORMATETC;
if (!fmt->cfFormat ||
(fmt->cfFormat == CF_METAFILEPICT && fmt->tymed == TYMED_MFPICT) ||
(fmt->cfFormat == CF_BITMAP && fmt->tymed == TYMED_GDI) ||
(fmt->cfFormat == CF_DIB && fmt->tymed == TYMED_HGLOBAL) ||
(fmt->cfFormat == CF_ENHMETAFILE && fmt->tymed == TYMED_ENHMF))
return S_OK;
else if (tymed == TYMED_HGLOBAL)
else if (fmt->tymed == TYMED_HGLOBAL)
return CACHE_S_FORMATETC_NOTSUPPORTED;
else
{
WARN("invalid clipformat/tymed combination: %d/%d\n", cfFormat, tymed);
WARN("invalid clipformat/tymed combination: %d/%d\n", fmt->cfFormat, fmt->tymed);
return DV_E_TYMED;
}
}
@ -332,7 +335,6 @@ static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD
hr = copy_formatetc(&entry->fmtetc, fmt);
if (FAILED(hr)) return FALSE;
entry->data_cf = 0;
entry->stgmedium.tymed = TYMED_NULL;
entry->stgmedium.pUnkForRelease = NULL;
entry->stream = NULL;
@ -353,7 +355,7 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc
DWORD id = automatic ? 1 : This->last_cache_id;
DataCacheEntry *entry;
hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed);
hr = check_valid_formatetc( formatetc );
if (FAILED(hr))
return hr;
if (hr == CACHE_S_FORMATETC_NOTSUPPORTED)
@ -454,6 +456,10 @@ static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat)
hr = IStream_Read(stream, &length, sizeof(length), &read);
if (hr != S_OK || read != sizeof(length))
return DV_E_CLIPFORMAT;
if (!length) {
/* No clipboard format present */
return S_OK;
}
if (length == -1)
{
DWORD cf;
@ -483,11 +489,16 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat)
{
DWORD length;
HRESULT hr;
char format_name[256];
if (clipformat < 0xc000)
length = -1;
else
length = GetClipboardFormatNameA(clipformat, NULL, 0);
{
length = GetClipboardFormatNameA(clipformat, format_name, sizeof(format_name));
/* If there is a clipboard format name, we need to include its terminating \0 */
if (length) length++;
}
hr = IStream_Write(stream, &length, sizeof(length), NULL);
if (FAILED(hr))
return hr;
@ -498,12 +509,7 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat)
}
else
{
char *format_name = HeapAlloc(GetProcessHeap(), 0, length);
if (!format_name)
return E_OUTOFMEMORY;
GetClipboardFormatNameA(clipformat, format_name, length);
hr = IStream_Write(stream, format_name, length, NULL);
HeapFree(GetProcessHeap(), 0, format_name);
}
return hr;
}
@ -618,7 +624,6 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
GlobalUnlock( hmfpict );
if (SUCCEEDED( hr ))
{
cache_entry->data_cf = cache_entry->fmtetc.cfFormat;
cache_entry->stgmedium.tymed = TYMED_MFPICT;
cache_entry->stgmedium.u.hMetaFilePict = hmfpict;
}
@ -703,7 +708,6 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
GlobalUnlock( hglobal );
cache_entry->data_cf = cache_entry->fmtetc.cfFormat;
cache_entry->stgmedium.tymed = TYMED_HGLOBAL;
cache_entry->stgmedium.u.hGlobal = hglobal;
@ -756,16 +760,240 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry)
return hr;
}
static HRESULT DataCacheEntry_CreateStream(DataCacheEntry *cache_entry,
IStorage *storage, IStream **stream)
static void init_stream_header(DataCacheEntry *entry, PresentationDataHeader *header)
{
WCHAR wszName[] = {2,'O','l','e','P','r','e','s',
if (entry->fmtetc.ptd)
FIXME("ptd not serialized\n");
header->tdSize = sizeof(header->tdSize);
header->dvAspect = entry->fmtetc.dwAspect;
header->lindex = entry->fmtetc.lindex;
header->advf = entry->advise_flags;
header->unknown7 = 0;
header->dwObjectExtentX = 0;
header->dwObjectExtentY = 0;
header->dwSize = 0;
}
static HRESULT save_dib(DataCacheEntry *entry, BOOL contents, IStream *stream)
{
HRESULT hr = S_OK;
int data_size = 0;
BITMAPINFO *bmi = NULL;
if (entry->stgmedium.tymed != TYMED_NULL)
{
data_size = GlobalSize(entry->stgmedium.u.hGlobal);
bmi = GlobalLock(entry->stgmedium.u.hGlobal);
}
if (!contents)
{
PresentationDataHeader header;
init_stream_header(entry, &header);
hr = write_clipformat(stream, entry->fmtetc.cfFormat);
if (FAILED(hr)) goto end;
if (data_size)
{
header.dwSize = data_size;
/* Size in units of 0.01mm (ie. MM_HIMETRIC) */
if (bmi->bmiHeader.biXPelsPerMeter != 0 && bmi->bmiHeader.biYPelsPerMeter != 0)
{
header.dwObjectExtentX = MulDiv(bmi->bmiHeader.biWidth, 100000, bmi->bmiHeader.biXPelsPerMeter);
header.dwObjectExtentY = MulDiv(bmi->bmiHeader.biHeight, 100000, bmi->bmiHeader.biYPelsPerMeter);
}
else
{
HDC hdc = GetDC(0);
header.dwObjectExtentX = MulDiv(bmi->bmiHeader.biWidth, 2540, GetDeviceCaps(hdc, LOGPIXELSX));
header.dwObjectExtentY = MulDiv(bmi->bmiHeader.biHeight, 2540, GetDeviceCaps(hdc, LOGPIXELSY));
ReleaseDC(0, hdc);
}
}
hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL);
if (hr == S_OK && data_size)
hr = IStream_Write(stream, bmi, data_size, NULL);
}
else if(data_size)
{
BITMAPFILEHEADER bmp_fhdr;
bmp_fhdr.bfType = 0x4d42;
bmp_fhdr.bfSize = data_size + sizeof(BITMAPFILEHEADER);
bmp_fhdr.bfReserved1 = bmp_fhdr.bfReserved2 = 0;
bmp_fhdr.bfOffBits = bitmap_info_size(bmi, DIB_RGB_COLORS) + sizeof(BITMAPFILEHEADER);
hr = IStream_Write(stream, &bmp_fhdr, sizeof(BITMAPFILEHEADER), NULL);
if (hr == S_OK)
hr = IStream_Write(stream, bmi, data_size, NULL);
}
end:
if (bmi) GlobalUnlock(entry->stgmedium.u.hGlobal);
return hr;
}
#include <pshpack2.h>
struct meta_placeable
{
DWORD key;
WORD hwmf;
WORD bounding_box[4];
WORD inch;
DWORD reserved;
WORD checksum;
};
#include <poppack.h>
static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream)
{
HRESULT hr = S_OK;
int data_size = 0;
void *data = NULL;
METAFILEPICT *mfpict = NULL;
if (!contents)
{
PresentationDataHeader header;
init_stream_header(entry, &header);
hr = write_clipformat(stream, entry->fmtetc.cfFormat);
if (FAILED(hr)) return hr;
if (entry->stgmedium.tymed != TYMED_NULL)
{
mfpict = GlobalLock(entry->stgmedium.u.hMetaFilePict);
if (!mfpict)
return DV_E_STGMEDIUM;
data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
header.dwObjectExtentX = mfpict->xExt;
header.dwObjectExtentY = mfpict->yExt;
header.dwSize = data_size;
data = HeapAlloc(GetProcessHeap(), 0, header.dwSize);
if (!data)
{
GlobalUnlock(entry->stgmedium.u.hMetaFilePict);
return E_OUTOFMEMORY;
}
GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data);
GlobalUnlock(entry->stgmedium.u.hMetaFilePict);
}
hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL);
if (hr == S_OK && data_size)
hr = IStream_Write(stream, data, data_size, NULL);
HeapFree(GetProcessHeap(), 0, data);
}
else if (entry->stgmedium.tymed != TYMED_NULL)
{
struct meta_placeable meta_place_rec;
WORD *check;
mfpict = GlobalLock(entry->stgmedium.u.hMetaFilePict);
if (!mfpict)
return DV_E_STGMEDIUM;
data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
data = HeapAlloc(GetProcessHeap(), 0, data_size);
if (!data)
{
GlobalUnlock(entry->stgmedium.u.hMetaFilePict);
return E_OUTOFMEMORY;
}
GetMetaFileBitsEx(mfpict->hMF, data_size, data);
/* units are in 1/8th of a point (1 point is 1/72th of an inch) */
meta_place_rec.key = 0x9ac6cdd7;
meta_place_rec.hwmf = 0;
meta_place_rec.inch = 576;
meta_place_rec.bounding_box[0] = 0;
meta_place_rec.bounding_box[1] = 0;
meta_place_rec.bounding_box[2] = 0;
meta_place_rec.bounding_box[3] = 0;
meta_place_rec.checksum = 0;
meta_place_rec.reserved = 0;
/* These values are rounded down so MulDiv won't do the right thing */
meta_place_rec.bounding_box[2] = (LONGLONG)mfpict->xExt * meta_place_rec.inch / 2540;
meta_place_rec.bounding_box[3] = (LONGLONG)mfpict->yExt * meta_place_rec.inch / 2540;
GlobalUnlock(entry->stgmedium.u.hMetaFilePict);
for (check = (WORD *)&meta_place_rec; check != (WORD *)&meta_place_rec.checksum; check++)
meta_place_rec.checksum ^= *check;
hr = IStream_Write(stream, &meta_place_rec, sizeof(struct meta_placeable), NULL);
if (hr == S_OK && data_size)
hr = IStream_Write(stream, data, data_size, NULL);
HeapFree(GetProcessHeap(), 0, data);
}
return hr;
}
static HRESULT save_emf(DataCacheEntry *entry, BOOL contents, IStream *stream)
{
HRESULT hr = S_OK;
int data_size = 0;
BYTE *data;
if (!contents)
{
PresentationDataHeader header;
METAFILEPICT *mfpict;
HDC hdc = GetDC(0);
init_stream_header(entry, &header);
hr = write_clipformat(stream, entry->fmtetc.cfFormat);
if (FAILED(hr))
{
ReleaseDC(0, hdc);
return hr;
}
data_size = GetWinMetaFileBits(entry->stgmedium.u.hEnhMetaFile, 0, NULL, MM_ANISOTROPIC, hdc);
header.dwSize = data_size;
data = HeapAlloc(GetProcessHeap(), 0, header.dwSize);
if (!data)
{
ReleaseDC(0, hdc);
return E_OUTOFMEMORY;
}
GetWinMetaFileBits(entry->stgmedium.u.hEnhMetaFile, header.dwSize, data, MM_ANISOTROPIC, hdc);
ReleaseDC(0, hdc);
mfpict = (METAFILEPICT *)data;
header.dwObjectExtentX = mfpict->xExt;
header.dwObjectExtentY = mfpict->yExt;
hr = IStream_Write(stream, &header, sizeof(PresentationDataHeader), NULL);
if (hr == S_OK && data_size)
hr = IStream_Write(stream, data, data_size, NULL);
HeapFree(GetProcessHeap(), 0, data);
}
else if (entry->stgmedium.tymed != TYMED_NULL)
{
data_size = GetEnhMetaFileBits(entry->stgmedium.u.hEnhMetaFile, 0, NULL);
data = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) + sizeof(ENHMETAHEADER) + data_size);
if (!data) return E_OUTOFMEMORY;
*((DWORD *)data) = sizeof(ENHMETAHEADER);
GetEnhMetaFileBits(entry->stgmedium.u.hEnhMetaFile, data_size, data + sizeof(DWORD) + sizeof(ENHMETAHEADER));
memcpy(data + sizeof(DWORD), data + sizeof(DWORD) + sizeof(ENHMETAHEADER), sizeof(ENHMETAHEADER));
data_size += sizeof(DWORD) + sizeof(ENHMETAHEADER);
hr = IStream_Write(stream, data, data_size, NULL);
HeapFree(GetProcessHeap(), 0, data);
}
return hr;
}
static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
static HRESULT create_stream(DataCacheEntry *cache_entry, IStorage *storage,
BOOL contents, IStream **stream)
{
WCHAR pres[] = {2,'O','l','e','P','r','e','s',
'0' + (cache_entry->stream_number / 100) % 10,
'0' + (cache_entry->stream_number / 10) % 10,
'0' + cache_entry->stream_number % 10, 0};
const WCHAR *name;
/* FIXME: cache the created stream in This? */
return IStorage_CreateStream(storage, wszName,
if (contents)
name = CONTENTS;
else
name = pres;
return IStorage_CreateStream(storage, name,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
0, 0, stream);
}
@ -773,95 +1001,32 @@ static HRESULT DataCacheEntry_CreateStream(DataCacheEntry *cache_entry,
static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storage,
BOOL same_as_load)
{
PresentationDataHeader header;
HRESULT hr;
IStream *pres_stream;
void *data = NULL;
IStream *stream;
BOOL contents = (cache_entry->id == 1);
TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->stream_number, debugstr_formatetc(&cache_entry->fmtetc));
hr = DataCacheEntry_CreateStream(cache_entry, storage, &pres_stream);
hr = create_stream(cache_entry, storage, contents, &stream);
if (FAILED(hr))
return hr;
hr = write_clipformat(pres_stream, cache_entry->data_cf);
if (FAILED(hr))
return hr;
if (cache_entry->fmtetc.ptd)
FIXME("ptd not serialized\n");
header.unknown3 = 4;
header.dvAspect = cache_entry->fmtetc.dwAspect;
header.lindex = cache_entry->fmtetc.lindex;
header.advf = cache_entry->advise_flags;
header.unknown7 = 0;
header.dwObjectExtentX = 0;
header.dwObjectExtentY = 0;
header.dwSize = 0;
/* size the data */
switch (cache_entry->data_cf)
switch (cache_entry->fmtetc.cfFormat)
{
case CF_METAFILEPICT:
{
if (cache_entry->stgmedium.tymed != TYMED_NULL)
{
const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict);
if (!mfpict)
{
IStream_Release(pres_stream);
return DV_E_STGMEDIUM;
}
header.dwObjectExtentX = mfpict->xExt;
header.dwObjectExtentY = mfpict->yExt;
header.dwSize = GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
}
break;
}
default:
break;
case CF_DIB:
hr = save_dib(cache_entry, contents, stream);
break;
case CF_METAFILEPICT:
hr = save_mfpict(cache_entry, contents, stream);
break;
case CF_ENHMETAFILE:
hr = save_emf(cache_entry, contents, stream);
break;
default:
FIXME("got unsupported clipboard format %x\n", cache_entry->fmtetc.cfFormat);
}
/*
* Write the header.
*/
hr = IStream_Write(pres_stream, &header, sizeof(PresentationDataHeader),
NULL);
if (FAILED(hr))
{
IStream_Release(pres_stream);
return hr;
}
/* get the data */
switch (cache_entry->data_cf)
{
case CF_METAFILEPICT:
{
if (cache_entry->stgmedium.tymed != TYMED_NULL)
{
const METAFILEPICT *mfpict = GlobalLock(cache_entry->stgmedium.u.hMetaFilePict);
if (!mfpict)
{
IStream_Release(pres_stream);
return DV_E_STGMEDIUM;
}
data = HeapAlloc(GetProcessHeap(), 0, header.dwSize);
GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data);
GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
}
break;
}
default:
break;
}
if (data)
hr = IStream_Write(pres_stream, data, header.dwSize, NULL);
HeapFree(GetProcessHeap(), 0, data);
IStream_Release(pres_stream);
IStream_Release(stream);
return hr;
}
@ -904,12 +1069,12 @@ static HRESULT copy_stg_medium(CLIPFORMAT cf, STGMEDIUM *dest_stgm,
return S_OK;
}
static HGLOBAL synthesize_dib( HBITMAP bm )
static HRESULT synthesize_dib( HBITMAP bm, STGMEDIUM *med )
{
HDC hdc = GetDC( 0 );
BITMAPINFOHEADER header;
BITMAPINFO *bmi;
HGLOBAL ret = 0;
HRESULT hr = E_FAIL;
DWORD header_size;
memset( &header, 0, sizeof(header) );
@ -917,34 +1082,64 @@ static HGLOBAL synthesize_dib( HBITMAP bm )
if (!GetDIBits( hdc, bm, 0, 0, NULL, (BITMAPINFO *)&header, DIB_RGB_COLORS )) goto done;
header_size = bitmap_info_size( (BITMAPINFO *)&header, DIB_RGB_COLORS );
if (!(ret = GlobalAlloc( GMEM_MOVEABLE, header_size + header.biSizeImage ))) goto done;
bmi = GlobalLock( ret );
if (!(med->u.hGlobal = GlobalAlloc( GMEM_MOVEABLE, header_size + header.biSizeImage ))) goto done;
bmi = GlobalLock( med->u.hGlobal );
memset( bmi, 0, header_size );
memcpy( bmi, &header, header.biSize );
GetDIBits( hdc, bm, 0, abs(header.biHeight), (char *)bmi + header_size, bmi, DIB_RGB_COLORS );
GlobalUnlock( ret );
GlobalUnlock( med->u.hGlobal );
med->tymed = TYMED_HGLOBAL;
med->pUnkForRelease = NULL;
hr = S_OK;
done:
ReleaseDC( 0, hdc );
return ret;
return hr;
}
static HBITMAP synthesize_bitmap( HGLOBAL dib )
static HRESULT synthesize_bitmap( HGLOBAL dib, STGMEDIUM *med )
{
HBITMAP ret = 0;
HRESULT hr = E_FAIL;
BITMAPINFO *bmi;
HDC hdc = GetDC( 0 );
if ((bmi = GlobalLock( dib )))
{
/* FIXME: validate data size */
ret = CreateDIBitmap( hdc, &bmi->bmiHeader, CBM_INIT,
(char *)bmi + bitmap_info_size( bmi, DIB_RGB_COLORS ),
bmi, DIB_RGB_COLORS );
med->u.hBitmap = CreateDIBitmap( hdc, &bmi->bmiHeader, CBM_INIT,
(char *)bmi + bitmap_info_size( bmi, DIB_RGB_COLORS ),
bmi, DIB_RGB_COLORS );
GlobalUnlock( dib );
med->tymed = TYMED_GDI;
med->pUnkForRelease = NULL;
hr = S_OK;
}
ReleaseDC( 0, hdc );
return ret;
return hr;
}
static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med )
{
METAFILEPICT *pict;
HRESULT hr = E_FAIL;
UINT size;
void *bits;
if (!(pict = GlobalLock( data ))) return hr;
size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
{
GetMetaFileBitsEx( pict->hMF, size, bits );
med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict );
HeapFree( GetProcessHeap(), 0, bits );
med->tymed = TYMED_ENHMF;
med->pUnkForRelease = NULL;
hr = S_OK;
}
GlobalUnlock( data );
return hr;
}
static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
@ -952,7 +1147,8 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
STGMEDIUM *stgmedium,
BOOL fRelease)
{
STGMEDIUM dib_copy;
STGMEDIUM copy;
HRESULT hr;
if ((!cache_entry->fmtetc.cfFormat && !formatetc->cfFormat) ||
(cache_entry->fmtetc.tymed == TYMED_NULL && formatetc->tymed == TYMED_NULL) ||
@ -964,15 +1160,21 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
cache_entry->dirty = TRUE;
ReleaseStgMedium(&cache_entry->stgmedium);
cache_entry->data_cf = cache_entry->fmtetc.cfFormat ? cache_entry->fmtetc.cfFormat : formatetc->cfFormat;
if (formatetc->cfFormat == CF_BITMAP)
{
dib_copy.tymed = TYMED_HGLOBAL;
dib_copy.u.hGlobal = synthesize_dib( stgmedium->u.hBitmap );
dib_copy.pUnkForRelease = NULL;
hr = synthesize_dib( stgmedium->u.hBitmap, &copy );
if (FAILED(hr)) return hr;
if (fRelease) ReleaseStgMedium(stgmedium);
stgmedium = &dib_copy;
stgmedium = &copy;
fRelease = TRUE;
}
else if (formatetc->cfFormat == CF_METAFILEPICT && cache_entry->fmtetc.cfFormat == CF_ENHMETAFILE)
{
hr = synthesize_emf( stgmedium->u.hMetaFilePict, &copy );
if (FAILED(hr)) return hr;
if (fRelease) ReleaseStgMedium(stgmedium);
stgmedium = &copy;
fRelease = TRUE;
}
@ -982,8 +1184,7 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
return S_OK;
}
else
return copy_stg_medium(cache_entry->data_cf,
&cache_entry->stgmedium, stgmedium);
return copy_stg_medium(cache_entry->fmtetc.cfFormat, &cache_entry->stgmedium, stgmedium);
}
static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fmt, STGMEDIUM *stgmedium)
@ -998,19 +1199,14 @@ static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fm
return OLE_E_BLANK;
if (fmt->cfFormat == CF_BITMAP)
{
stgmedium->tymed = TYMED_GDI;
stgmedium->u.hBitmap = synthesize_bitmap( cache_entry->stgmedium.u.hGlobal );
stgmedium->pUnkForRelease = NULL;
return S_OK;
}
return copy_stg_medium(cache_entry->data_cf, stgmedium, &cache_entry->stgmedium);
return synthesize_bitmap( cache_entry->stgmedium.u.hGlobal, stgmedium );
return copy_stg_medium(cache_entry->fmtetc.cfFormat, stgmedium, &cache_entry->stgmedium);
}
static inline HRESULT DataCacheEntry_DiscardData(DataCacheEntry *cache_entry)
{
ReleaseStgMedium(&cache_entry->stgmedium);
cache_entry->data_cf = cache_entry->fmtetc.cfFormat;
return S_OK;
}
@ -1108,7 +1304,10 @@ static HRESULT WINAPI DataCache_NDIUnknown_QueryInterface(
if (IsEqualIID(&IID_IUnknown, riid))
{
*ppvObject = iface;
if (this->outer_unk == iface) /* non-aggregated, return IUnknown from IOleCache2 */
*ppvObject = &this->IOleCache2_iface;
else
*ppvObject = iface;
}
else if (IsEqualIID(&IID_IDataObject, riid))
{
@ -1230,6 +1429,8 @@ static HRESULT WINAPI DataCache_GetData(
DataCache *This = impl_from_IDataObject(iface);
DataCacheEntry *cache_entry;
TRACE("(%p, %s, %p)\n", iface, debugstr_formatetc(pformatetcIn), pmedium);
memset(pmedium, 0, sizeof(*pmedium));
cache_entry = DataCache_GetEntryForFormatEtc(This, pformatetcIn);
@ -1561,8 +1762,6 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *s
return add_cache_entry( This, fmt, 0, stm, contents_stream );
}
static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
/************************************************************************
* DataCache_Load (IPersistStorage)
*
@ -1621,35 +1820,14 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg )
* our responsibility to copy the information when saving to a new
* storage.
*/
static HRESULT WINAPI DataCache_Save(
IPersistStorage* iface,
IStorage* pStg,
BOOL fSameAsLoad)
static HRESULT WINAPI DataCache_Save(IPersistStorage* iface, IStorage *stg, BOOL same_as_load)
{
DataCache *This = impl_from_IPersistStorage(iface);
DataCacheEntry *cache_entry;
BOOL dirty = FALSE;
HRESULT hr = S_OK;
unsigned short stream_number = 0;
TRACE("(%p, %p, %d)\n", iface, pStg, fSameAsLoad);
dirty = This->dirty;
if (!dirty)
{
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
{
dirty = cache_entry->dirty;
if (dirty)
break;
}
}
/* this is a shortcut if nothing changed */
if (!dirty && !fSameAsLoad && This->presentationStorage)
{
return IStorage_CopyTo(This->presentationStorage, 0, NULL, NULL, pStg);
}
TRACE("(%p, %p, %d)\n", iface, stg, same_as_load);
/* assign stream numbers to the cache entries */
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
@ -1665,17 +1843,17 @@ static HRESULT WINAPI DataCache_Save(
/* write out the cache entries */
LIST_FOR_EACH_ENTRY(cache_entry, &This->cache_list, DataCacheEntry, entry)
{
if (!fSameAsLoad || cache_entry->dirty)
if (!same_as_load || cache_entry->dirty)
{
hr = DataCacheEntry_Save(cache_entry, pStg, fSameAsLoad);
hr = DataCacheEntry_Save(cache_entry, stg, same_as_load);
if (FAILED(hr))
break;
cache_entry->dirty = FALSE;
if (same_as_load) cache_entry->dirty = FALSE;
}
}
This->dirty = FALSE;
if (same_as_load) This->dirty = FALSE;
return hr;
}
@ -1826,7 +2004,7 @@ static HRESULT WINAPI DataCache_Draw(
if (pfnContinue && !pfnContinue(dwContinue)) return E_ABORT;
switch (cache_entry->data_cf)
switch (cache_entry->fmtetc.cfFormat)
{
case CF_METAFILEPICT:
{
@ -2085,7 +2263,7 @@ static HRESULT WINAPI DataCache_GetExtent(
continue;
switch (cache_entry->data_cf)
switch (cache_entry->fmtetc.cfFormat)
{
case CF_METAFILEPICT:
{
@ -2231,6 +2409,13 @@ static HRESULT WINAPI DataCache_Cache(
fmt_cpy.tymed = TYMED_HGLOBAL;
}
/* View caching DVASPECT_ICON gets converted to CF_METAFILEPICT */
if (fmt_cpy.dwAspect == DVASPECT_ICON && fmt_cpy.cfFormat == 0)
{
fmt_cpy.cfFormat = CF_METAFILEPICT;
fmt_cpy.tymed = TYMED_MFPICT;
}
*pdwConnection = 0;
cache_entry = DataCache_GetEntryForFormatEtc(This, &fmt_cpy);
@ -2327,12 +2512,10 @@ fail:
return hr;
}
static HRESULT WINAPI DataCache_InitCache(
IOleCache2* iface,
IDataObject* pDataObject)
static HRESULT WINAPI DataCache_InitCache( IOleCache2 *iface, IDataObject *data )
{
FIXME("stub\n");
return E_NOTIMPL;
TRACE( "(%p %p)\n", iface, data );
return IOleCache2_UpdateCache( iface, data, UPDFCACHE_ALLBUTNODATACACHE, NULL );
}
static HRESULT WINAPI DataCache_IOleCache2_SetData(
@ -2364,14 +2547,102 @@ static HRESULT WINAPI DataCache_IOleCache2_SetData(
return OLE_E_BLANK;
}
static HRESULT WINAPI DataCache_UpdateCache(
IOleCache2* iface,
LPDATAOBJECT pDataObject,
DWORD grfUpdf,
LPVOID pReserved)
static BOOL entry_updatable( DataCacheEntry *entry, DWORD mode )
{
FIXME("(%p, 0x%x, %p): stub\n", pDataObject, grfUpdf, pReserved);
return E_NOTIMPL;
BOOL is_blank = entry->stgmedium.tymed == TYMED_NULL;
if ((mode & UPDFCACHE_ONLYIFBLANK) && !is_blank) return FALSE;
if ((mode & UPDFCACHE_NODATACACHE) && (entry->advise_flags & ADVF_NODATA)) return TRUE;
if ((mode & UPDFCACHE_ONSAVECACHE) && (entry->advise_flags & ADVFCACHE_ONSAVE)) return TRUE;
if ((mode & UPDFCACHE_ONSTOPCACHE) && (entry->advise_flags & ADVF_DATAONSTOP)) return TRUE;
if ((mode & UPDFCACHE_NORMALCACHE) && (entry->advise_flags == 0)) return TRUE;
if ((mode & UPDFCACHE_IFBLANK) && (is_blank && !(entry->advise_flags & ADVF_NODATA))) return TRUE;
return FALSE;
}
static HRESULT WINAPI DataCache_UpdateCache( IOleCache2 *iface, IDataObject *data,
DWORD mode, void *reserved )
{
DataCache *This = impl_from_IOleCache2(iface);
DataCacheEntry *cache_entry;
STGMEDIUM med;
HRESULT hr = S_OK;
CLIPFORMAT view_list[] = { CF_METAFILEPICT, CF_ENHMETAFILE, CF_DIB, CF_BITMAP };
FORMATETC fmt;
int i, slots = 0;
BOOL done_one = FALSE;
TRACE( "(%p %p %08x %p)\n", iface, data, mode, reserved );
LIST_FOR_EACH_ENTRY( cache_entry, &This->cache_list, DataCacheEntry, entry )
{
slots++;
if (!entry_updatable( cache_entry, mode ))
{
done_one = TRUE;
continue;
}
fmt = cache_entry->fmtetc;
if (fmt.cfFormat)
{
hr = IDataObject_GetData( data, &fmt, &med );
if (hr != S_OK && fmt.cfFormat == CF_DIB)
{
fmt.cfFormat = CF_BITMAP;
fmt.tymed = TYMED_GDI;
hr = IDataObject_GetData( data, &fmt, &med );
}
if (hr != S_OK && fmt.cfFormat == CF_ENHMETAFILE)
{
fmt.cfFormat = CF_METAFILEPICT;
fmt.tymed = TYMED_MFPICT;
hr = IDataObject_GetData( data, &fmt, &med );
}
if (hr == S_OK)
{
hr = DataCacheEntry_SetData( cache_entry, &fmt, &med, TRUE );
if (hr != S_OK) ReleaseStgMedium( &med );
else done_one = TRUE;
}
}
else
{
for (i = 0; i < sizeof(view_list) / sizeof(view_list[0]); i++)
{
fmt.cfFormat = view_list[i];
fmt.tymed = tymed_from_cf( fmt.cfFormat );
hr = IDataObject_QueryGetData( data, &fmt );
if (hr == S_OK)
{
hr = IDataObject_GetData( data, &fmt, &med );
if (hr == S_OK)
{
if (fmt.cfFormat == CF_BITMAP)
{
cache_entry->fmtetc.cfFormat = CF_DIB;
cache_entry->fmtetc.tymed = TYMED_HGLOBAL;
}
else
{
cache_entry->fmtetc.cfFormat = fmt.cfFormat;
cache_entry->fmtetc.tymed = fmt.tymed;
}
hr = DataCacheEntry_SetData( cache_entry, &fmt, &med, TRUE );
if (hr != S_OK) ReleaseStgMedium( &med );
else done_one = TRUE;
break;
}
}
}
}
}
return (!slots || done_one) ? S_OK : CACHE_E_NOCACHE_UPDATED;
}
static HRESULT WINAPI DataCache_DiscardCache(

View file

@ -30,8 +30,6 @@ struct tagEnumSTATPROPSETSTG_impl
struct list *current;
ULONG elem_size;
GUID riid;
IUnknown *parent;
enumx_copy_cb copy_cb;
};
/************************************************************************
@ -82,7 +80,6 @@ ULONG WINAPI enumx_Release(enumx_impl *This)
list_remove(x);
HeapFree(GetProcessHeap(), 0, x);
}
IUnknown_Release(This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
@ -104,10 +101,7 @@ HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
p = rgelt;
while (count < celt && This->current && This->current != &This->elements)
{
if (This->copy_cb)
This->copy_cb(This->parent, &This->current[1], p);
else
memcpy(p, &This->current[1], This->elem_size);
memcpy(p, &This->current[1], This->elem_size);
p += This->elem_size;
This->current = This->current->next;
count++;
@ -164,8 +158,7 @@ HRESULT WINAPI enumx_Clone(
*
* Allocate a generic enumerator
*/
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size,
IUnknown *parent, enumx_copy_cb copy_cb)
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
{
enumx_impl *enumx;
@ -177,11 +170,6 @@ enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size,
enumx->current = NULL;
enumx->elem_size = elem_size;
enumx->riid = *riid;
enumx->parent = parent;
enumx->copy_cb = copy_cb;
IUnknown_AddRef(parent);
list_init(&enumx->elements);
}

View file

@ -21,8 +21,6 @@
typedef struct tagEnumSTATPROPSETSTG_impl enumx_impl;
typedef void (*enumx_copy_cb)(IUnknown *parent, void *orig, void *dest);
extern HRESULT WINAPI enumx_QueryInterface(enumx_impl *, REFIID, void**) DECLSPEC_HIDDEN;
extern ULONG WINAPI enumx_AddRef(enumx_impl *) DECLSPEC_HIDDEN;
extern ULONG WINAPI enumx_Release(enumx_impl *) DECLSPEC_HIDDEN;
@ -30,8 +28,7 @@ extern HRESULT WINAPI enumx_Next(enumx_impl *, ULONG, void *, ULONG *) DECLSPEC_
extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG) DECLSPEC_HIDDEN;
extern HRESULT WINAPI enumx_Reset(enumx_impl *) DECLSPEC_HIDDEN;
extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **) DECLSPEC_HIDDEN;
extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG,
IUnknown *, enumx_copy_cb) DECLSPEC_HIDDEN;
extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG) DECLSPEC_HIDDEN;
extern void *enumx_add_element(enumx_impl *, const void *) DECLSPEC_HIDDEN;
#endif /* __OLE_ENUM_H__ */

View file

@ -5,7 +5,6 @@
* for streams contained supported by an HGLOBAL pointer.
*
* Copyright 1999 Francis Beaudet
* Copyright 2016 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -24,158 +23,7 @@
#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(hglobalstream);
struct handle_wrapper
{
LONG ref;
HGLOBAL hglobal;
ULONG size;
BOOL delete_on_release;
CRITICAL_SECTION lock;
};
static void handle_addref(struct handle_wrapper *handle)
{
InterlockedIncrement(&handle->ref);
}
static void handle_release(struct handle_wrapper *handle)
{
ULONG ref = InterlockedDecrement(&handle->ref);
if (!ref)
{
if (handle->delete_on_release)
{
GlobalFree(handle->hglobal);
handle->hglobal = NULL;
}
handle->lock.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&handle->lock);
HeapFree(GetProcessHeap(), 0, handle);
}
}
static ULONG handle_read(struct handle_wrapper *handle, ULONG *pos, void *dest, ULONG len)
{
void *source;
EnterCriticalSection(&handle->lock);
if (*pos < handle->size)
len = min(handle->size - *pos, len);
else
len = 0;
source = GlobalLock(handle->hglobal);
if (source)
{
memcpy(dest, (char *)source + *pos, len);
*pos += len;
GlobalUnlock(handle->hglobal);
}
else
{
WARN("read from invalid hglobal %p\n", handle->hglobal);
len = 0;
}
LeaveCriticalSection(&handle->lock);
return len;
}
static ULONG handle_write(struct handle_wrapper *handle, ULONG *pos, const void *source, ULONG len)
{
void *dest;
if (!len)
return 0;
EnterCriticalSection(&handle->lock);
if (*pos + len > handle->size)
{
HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, *pos + len, GMEM_MOVEABLE);
if (hglobal)
{
handle->hglobal = hglobal;
handle->size = *pos + len;
}
else
{
len = 0;
goto done;
}
}
dest = GlobalLock(handle->hglobal);
if (dest)
{
memcpy((char *)dest + *pos, source, len);
*pos += len;
GlobalUnlock(handle->hglobal);
}
else
{
WARN("write to invalid hglobal %p\n", handle->hglobal);
/* len = 0; */
}
done:
LeaveCriticalSection(&handle->lock);
return len;
}
static HGLOBAL handle_gethglobal(struct handle_wrapper *handle)
{
return handle->hglobal;
}
static HRESULT handle_setsize(struct handle_wrapper *handle, ULONG size)
{
HRESULT hr = S_OK;
EnterCriticalSection(&handle->lock);
if (handle->size != size)
{
HGLOBAL hglobal = GlobalReAlloc(handle->hglobal, size, GMEM_MOVEABLE);
if (hglobal)
{
handle->hglobal = hglobal;
handle->size = size;
}
else
hr = E_OUTOFMEMORY;
}
LeaveCriticalSection(&handle->lock);
return hr;
}
static ULONG handle_getsize(struct handle_wrapper *handle)
{
return handle->size;
}
static struct handle_wrapper *handle_create(HGLOBAL hglobal, BOOL delete_on_release)
{
struct handle_wrapper *handle;
handle = HeapAlloc(GetProcessHeap(), 0, sizeof(*handle));
if (handle)
{
handle->ref = 1;
handle->hglobal = hglobal;
handle->size = GlobalSize(hglobal);
handle->delete_on_release = delete_on_release;
InitializeCriticalSection(&handle->lock);
handle->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": handle_wrapper.lock");
}
return handle;
}
WINE_DEFAULT_DEBUG_CHANNEL(storage);
/****************************************************************************
* HGLOBALStreamImpl definition.
@ -188,7 +36,14 @@ typedef struct
IStream IStream_iface;
LONG ref;
struct handle_wrapper *handle;
/* support for the stream */
HGLOBAL supportHandle;
/* if TRUE the HGLOBAL is destroyed when the stream is finally released */
BOOL deleteOnRelease;
/* size of the stream */
ULARGE_INTEGER streamSize;
/* current position of the cursor */
ULARGE_INTEGER currentPosition;
@ -240,7 +95,12 @@ static ULONG WINAPI HGLOBALStreamImpl_Release(
if (!ref)
{
handle_release(This->handle);
if (This->deleteOnRelease)
{
GlobalFree(This->supportHandle);
This->supportHandle = NULL;
}
HeapFree(GetProcessHeap(), 0, This);
}
@ -263,12 +123,59 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
ULONG* pcbRead) /* [out] */
{
HGLOBALStreamImpl* This = impl_from_IStream(iface);
ULONG num_bytes;
TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbRead);
void* supportBuffer;
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
num_bytes = handle_read(This->handle, &This->currentPosition.u.LowPart, pv, cb);
if (pcbRead) *pcbRead = num_bytes;
TRACE("(%p, %p, %d, %p)\n", iface,
pv, cb, pcbRead);
/*
* If the caller is not interested in the number of bytes read,
* we use another buffer to avoid "if" statements in the code.
*/
if (pcbRead==0)
pcbRead = &bytesReadBuffer;
/*
* Using the known size of the stream, calculate the number of bytes
* to read from the block chain
*/
bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
/*
* Lock the buffer in position and copy the data.
*/
supportBuffer = GlobalLock(This->supportHandle);
if (!supportBuffer)
{
WARN("read from invalid hglobal %p\n", This->supportHandle);
*pcbRead = 0;
return S_OK;
}
memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
/*
* Move the current position to the new position
*/
This->currentPosition.u.LowPart+=bytesToReadFromBuffer;
/*
* Return the number of bytes read.
*/
*pcbRead = bytesToReadFromBuffer;
/*
* Cleanup
*/
GlobalUnlock(This->supportHandle);
/*
* Always returns S_OK even if the end of the stream is reached before the
* buffer is filled
*/
return S_OK;
}
@ -290,14 +197,71 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
ULONG* pcbWritten) /* [out] */
{
HGLOBALStreamImpl* This = impl_from_IStream(iface);
ULONG num_bytes;
void* supportBuffer;
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten);
num_bytes = handle_write(This->handle, &This->currentPosition.u.LowPart, pv, cb);
if (pcbWritten) *pcbWritten = num_bytes;
/*
* If the caller is not interested in the number of bytes written,
* we use another buffer to avoid "if" statements in the code.
*/
if (pcbWritten == 0)
pcbWritten = &bytesWritten;
return (num_bytes < cb) ? E_OUTOFMEMORY : S_OK;
if (cb == 0)
goto out;
*pcbWritten = 0;
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
/*
* Verify if we need to grow the stream
*/
if (newSize.u.LowPart > This->streamSize.u.LowPart)
{
/* grow stream */
HRESULT hr = IStream_SetSize(iface, newSize);
if (FAILED(hr))
{
ERR("IStream_SetSize failed with error 0x%08x\n", hr);
return hr;
}
}
/*
* Lock the buffer in position and copy the data.
*/
supportBuffer = GlobalLock(This->supportHandle);
if (!supportBuffer)
{
WARN("write to invalid hglobal %p\n", This->supportHandle);
return S_OK;
}
memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
/*
* Move the current position to the new position
*/
This->currentPosition.u.LowPart+=cb;
/*
* Cleanup
*/
GlobalUnlock(This->supportHandle);
out:
/*
* Return the number of bytes read.
*/
*pcbWritten = cb;
return S_OK;
}
/***
@ -335,7 +299,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
case STREAM_SEEK_CUR:
break;
case STREAM_SEEK_END:
newPosition.QuadPart = handle_getsize(This->handle);
newPosition = This->streamSize;
break;
default:
hr = STG_E_SEEKERROR;
@ -380,13 +344,29 @@ static HRESULT WINAPI HGLOBALStreamImpl_SetSize(
ULARGE_INTEGER libNewSize) /* [in] */
{
HGLOBALStreamImpl* This = impl_from_IStream(iface);
HGLOBAL supportHandle;
TRACE("(%p, %d)\n", iface, libNewSize.u.LowPart);
/*
* HighPart is ignored as shown in tests
*/
return handle_setsize(This->handle, libNewSize.u.LowPart);
if (This->streamSize.u.LowPart == libNewSize.u.LowPart)
return S_OK;
/*
* Re allocate the HGlobal to fit the new size of the stream.
*/
supportHandle = GlobalReAlloc(This->supportHandle, libNewSize.u.LowPart, 0);
if (supportHandle == 0)
return E_OUTOFMEMORY;
This->supportHandle = supportHandle;
This->streamSize.u.LowPart = libNewSize.u.LowPart;
return S_OK;
}
/***
@ -534,49 +514,24 @@ static HRESULT WINAPI HGLOBALStreamImpl_Stat(
pstatstg->pwcsName = NULL;
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.QuadPart = handle_getsize(This->handle);
pstatstg->cbSize = This->streamSize;
return S_OK;
}
static const IStreamVtbl HGLOBALStreamImplVtbl;
static HGLOBALStreamImpl *HGLOBALStreamImpl_Create(void)
{
HGLOBALStreamImpl *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
if (This)
{
This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl;
This->ref = 1;
}
return This;
}
static HRESULT WINAPI HGLOBALStreamImpl_Clone(
IStream* iface,
IStream** ppstm) /* [out] */
{
HGLOBALStreamImpl* This = impl_from_IStream(iface);
HGLOBALStreamImpl* clone;
ULARGE_INTEGER dummy;
LARGE_INTEGER offset;
HRESULT hr;
if (!ppstm) return E_INVALIDARG;
*ppstm = NULL;
TRACE(" Cloning %p (seek position=%d)\n", iface, This->currentPosition.u.LowPart);
clone = HGLOBALStreamImpl_Create();
if (!clone) return E_OUTOFMEMORY;
*ppstm = &clone->IStream_iface;
handle_addref(This->handle);
clone->handle = This->handle;
TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart);
hr = CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm);
if(FAILED(hr))
return hr;
offset.QuadPart = (LONGLONG)This->currentPosition.QuadPart;
IStream_Seek(*ppstm, offset, STREAM_SEEK_SET, &dummy);
return S_OK;
@ -613,19 +568,28 @@ HRESULT WINAPI CreateStreamOnHGlobal(
if (!ppstm)
return E_INVALIDARG;
This = HGLOBALStreamImpl_Create();
This = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
if (!This) return E_OUTOFMEMORY;
/* allocate a handle if one is not supplied */
if (!hGlobal)
hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0);
This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl;
This->ref = 1;
This->handle = handle_create(hGlobal, fDeleteOnRelease);
/* initialize the support */
This->supportHandle = hGlobal;
This->deleteOnRelease = fDeleteOnRelease;
/* allocate a handle if one is not supplied */
if (!This->supportHandle)
This->supportHandle = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0);
/* start at the beginning */
This->currentPosition.u.HighPart = 0;
This->currentPosition.u.LowPart = 0;
/* initialize the size of the stream to the size of the handle */
This->streamSize.u.HighPart = 0;
This->streamSize.u.LowPart = GlobalSize(This->supportHandle);
*ppstm = &This->IStream_iface;
return S_OK;
@ -638,16 +602,16 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
{
HGLOBALStreamImpl* pStream;
if (!pstm || !phglobal)
if (pstm == NULL)
return E_INVALIDARG;
pStream = impl_from_IStream(pstm);
pStream = (HGLOBALStreamImpl*) pstm;
/*
* Verify that the stream object was created with CreateStreamOnHGlobal.
*/
if (pStream->IStream_iface.lpVtbl == &HGLOBALStreamImplVtbl)
*phglobal = handle_gethglobal(pStream->handle);
*phglobal = pStream->supportHandle;
else
{
*phglobal = 0;

View file

@ -1474,16 +1474,17 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
else
{
BOOL joined = FALSE;
if (!COM_CurrentInfo()->apt)
struct oletls *info = COM_CurrentInfo();
if (!info->apt)
{
apartment_joinmta();
enter_apartment(info, COINIT_MULTITHREADED);
joined = TRUE;
}
RPC_ExecuteCall(params);
if (joined)
{
apartment_release(COM_CurrentInfo()->apt);
COM_CurrentInfo()->apt = NULL;
leave_apartment(info);
}
}

View file

@ -1004,18 +1004,15 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
if (This->codePage != CP_UNICODE)
ptr[cbEntry - 1] = '\0';
else
((LPWSTR)ptr)[cbEntry - 1] = 0;
*((LPWSTR)ptr + cbEntry / sizeof(WCHAR)) = '\0';
hr = PropertyStorage_StoreNameWithId(This, (char*)ptr, This->codePage, propid);
if (This->codePage == CP_UNICODE)
{
/* cbEntry is the number of characters */
cbEntry *= 2;
/* Unicode entries are padded to DWORD boundaries */
if (cbEntry % sizeof(DWORD))
ptr += sizeof(DWORD) - (cbEntry % sizeof(DWORD));
}
ptr += cbEntry;
ptr += sizeof(DWORD) + cbEntry;
}
return hr;
}
@ -1056,10 +1053,6 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data,
prop->u.bVal = *data;
TRACE("Read byte 0x%x\n", prop->u.bVal);
break;
case VT_BOOL:
StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.boolVal);
TRACE("Read bool %d\n", prop->u.boolVal);
break;
case VT_I2:
StorageUtl_ReadWord(data, 0, (WORD*)&prop->u.iVal);
TRACE("Read short %d\n", prop->u.iVal);
@ -1078,18 +1071,6 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data,
StorageUtl_ReadDWord(data, 0, &prop->u.ulVal);
TRACE("Read ulong %d\n", prop->u.ulVal);
break;
case VT_I8:
StorageUtl_ReadULargeInteger(data, 0, (ULARGE_INTEGER *)&prop->u.hVal);
TRACE("Read long long %s\n", wine_dbgstr_longlong(prop->u.hVal.QuadPart));
break;
case VT_UI8:
StorageUtl_ReadULargeInteger(data, 0, &prop->u.uhVal);
TRACE("Read ulong long %s\n", wine_dbgstr_longlong(prop->u.uhVal.QuadPart));
break;
case VT_R8:
memcpy(&prop->u.dblVal, data, sizeof(double));
TRACE("Read double %f\n", prop->u.dblVal);
break;
case VT_LPSTR:
{
DWORD count;
@ -2383,9 +2364,7 @@ static HRESULT create_EnumSTATPROPSETSTG(
enumx = enumx_allocate(&IID_IEnumSTATPROPSETSTG,
&IEnumSTATPROPSETSTG_Vtbl,
sizeof (STATPROPSETSTG),
(IUnknown*)&This->base.IStorage_iface,
NULL);
sizeof (STATPROPSETSTG));
/* add all the property set elements into a list */
r = IStorage_EnumElements(stg, 0, NULL, 0, &penum);
@ -2478,27 +2457,6 @@ static HRESULT WINAPI IEnumSTATPROPSTG_fnClone(
return enumx_Clone((enumx_impl*)iface, (enumx_impl**)ppenum);
}
static void prop_enum_copy_cb(IUnknown *parent, void *orig, void *dest)
{
PropertyStorage_impl *storage = impl_from_IPropertyStorage((IPropertyStorage*)parent);
STATPROPSTG *src_prop = orig;
STATPROPSTG *dest_prop = dest;
LPWSTR name;
dest_prop->propid = src_prop->propid;
dest_prop->vt = src_prop->vt;
dest_prop->lpwstrName = NULL;
if (dictionary_find(storage->propid_to_name, UlongToPtr(src_prop->propid), (void**)&name))
{
DWORD size = (strlenW(name) + 1) * sizeof(WCHAR);
dest_prop->lpwstrName = CoTaskMemAlloc(size);
if (!dest_prop->lpwstrName) return;
memcpy(dest_prop->lpwstrName, name, size);
}
}
static BOOL prop_enum_stat(const void *k, const void *v, void *extra, void *arg)
{
enumx_impl *enumx = arg;
@ -2525,9 +2483,7 @@ static HRESULT create_EnumSTATPROPSTG(
enumx = enumx_allocate(&IID_IEnumSTATPROPSTG,
&IEnumSTATPROPSTG_Vtbl,
sizeof (STATPROPSTG),
(IUnknown*)&This->IPropertyStorage_iface,
prop_enum_copy_cb);
sizeof (STATPROPSTG));
dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx);

View file

@ -2067,7 +2067,7 @@ static HRESULT WINAPI StorageBaseImpl_SetClass(
HRESULT hRes;
DirEntry currentEntry;
TRACE("(%p, %p)\n", iface, clsid);
TRACE("(%p, %s)\n", iface, wine_dbgstr_guid(clsid));
if (This->reverted)
return STG_E_REVERTED;
@ -7249,6 +7249,8 @@ BlockChainStream* BlockChainStream_Construct(
BlockChainStream* newStream;
newStream = HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream));
if(!newStream)
return NULL;
newStream->parentStorage = parentStorage;
newStream->headOfStreamPlaceHolder = headOfStreamPlaceHolder;

View file

@ -517,20 +517,25 @@ StgStreamImpl* StgStreamImpl_Construct(
/******************************************************************************
* Endian conversion macros
*/
#undef htole32
#undef htole16
#ifdef WORDS_BIGENDIAN
#ifndef htole32
#define htole32(x) RtlUlongByteSwap(x)
#endif
#ifndef htole16
#define htole16(x) RtlUshortByteSwap(x)
#endif
#define lendian32toh(x) RtlUlongByteSwap(x)
#define lendian16toh(x) RtlUshortByteSwap(x)
#else
#ifndef htole32
#define htole32(x) (x)
#endif
#ifndef htole16
#define htole16(x) (x)
#endif
#define lendian32toh(x) (x)
#define lendian16toh(x) (x)

View file

@ -80,11 +80,11 @@ static const char* debugstr_user_flags(ULONG *pFlags)
* the first parameter is an unsigned long.
* This function is only intended to be called by the RPC runtime.
*/
ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG StartingSize, CLIPFORMAT *pCF)
ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF)
{
ULONG size = StartingSize;
TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), size, pCF);
TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, pCF);
ALIGN_LENGTH(size, 3);
size += 8;
@ -129,6 +129,8 @@ unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *
{
TRACE("(%s, %p, &0x%04x\n", debugstr_user_flags(pFlags), pBuffer, *pCF);
ALIGN_POINTER(pBuffer, 3);
/* only need to marshal the name if it is not a pre-defined type and
* we are going remote */
if ((*pCF >= 0xc000) && (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE))
@ -191,6 +193,8 @@ unsigned char * __RPC_USER CLIPFORMAT_UserUnmarshal(ULONG *pFlags, unsigned char
TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, pCF);
ALIGN_POINTER(pBuffer, 3);
fContext = *(DWORD *)pBuffer;
pBuffer += 4;
@ -264,18 +268,23 @@ static ULONG handle_UserSize(ULONG *pFlags, ULONG StartingSize, HANDLE *handle)
RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
return StartingSize;
}
ALIGN_LENGTH(StartingSize, 3);
return StartingSize + sizeof(RemotableHandle);
}
static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
{
RemotableHandle *remhandle = (RemotableHandle *)pBuffer;
RemotableHandle *remhandle;
if (LOWORD(*pFlags) == MSHCTX_DIFFERENTMACHINE)
{
ERR("can't remote a local handle\n");
RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
return pBuffer;
}
ALIGN_POINTER(pBuffer, 3);
remhandle = (RemotableHandle *)pBuffer;
remhandle->fContext = WDT_INPROC_CALL;
remhandle->u.hInproc = (LONG_PTR)*handle;
return pBuffer + sizeof(RemotableHandle);
@ -283,7 +292,10 @@ static unsigned char * handle_UserMarshal(ULONG *pFlags, unsigned char *pBuffer,
static unsigned char * handle_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HANDLE *handle)
{
RemotableHandle *remhandle = (RemotableHandle *)pBuffer;
RemotableHandle *remhandle;
ALIGN_POINTER(pBuffer, 3);
remhandle = (RemotableHandle *)pBuffer;
if (remhandle->fContext != WDT_INPROC_CALL)
RaiseException(RPC_X_BAD_STUB_DATA, 0, 0, NULL);
*handle = (HANDLE)(LONG_PTR)remhandle->u.hInproc;
@ -566,10 +578,28 @@ void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
* the first parameter is a ULONG.
* This function is only intended to be called by the RPC runtime.
*/
ULONG __RPC_USER HBITMAP_UserSize(ULONG *pFlags, ULONG StartingSize, HBITMAP *phBmp)
ULONG __RPC_USER HBITMAP_UserSize(ULONG *flags, ULONG size, HBITMAP *bmp)
{
FIXME(":stub\n");
return StartingSize;
TRACE("(%s, %d, %p)\n", debugstr_user_flags(flags), size, *bmp);
ALIGN_LENGTH(size, 3);
size += sizeof(ULONG);
if (LOWORD(*flags) == MSHCTX_INPROC)
size += sizeof(ULONG);
else
{
size += sizeof(ULONG);
if (*bmp)
{
size += sizeof(ULONG);
size += FIELD_OFFSET(userBITMAP, cbSize);
size += GetBitmapBits(*bmp, 0, NULL);
}
}
return size;
}
/******************************************************************************
@ -591,10 +621,45 @@ ULONG __RPC_USER HBITMAP_UserSize(ULONG *pFlags, ULONG StartingSize, HBITMAP *ph
* the first parameter is a ULONG.
* This function is only intended to be called by the RPC runtime.
*/
unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *pFlags, unsigned char *pBuffer, HBITMAP *phBmp)
unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
{
FIXME(":stub\n");
return pBuffer;
TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, *bmp);
ALIGN_POINTER(buffer, 3);
if (LOWORD(*flags) == MSHCTX_INPROC)
{
*(ULONG *)buffer = WDT_INPROC_CALL;
buffer += sizeof(ULONG);
*(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp;
buffer += sizeof(ULONG);
}
else
{
*(ULONG *)buffer = WDT_REMOTE_CALL;
buffer += sizeof(ULONG);
*(ULONG *)buffer = (ULONG)(ULONG_PTR)*bmp;
buffer += sizeof(ULONG);
if (*bmp)
{
static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize);
BITMAP bitmap;
ULONG bitmap_size;
bitmap_size = GetBitmapBits(*bmp, 0, NULL);
*(ULONG *)buffer = bitmap_size;
buffer += sizeof(ULONG);
GetObjectW(*bmp, sizeof(BITMAP), &bitmap);
memcpy(buffer, &bitmap, header_size);
buffer += header_size;
GetBitmapBits(*bmp, bitmap_size, buffer);
buffer += bitmap_size;
}
}
return buffer;
}
/******************************************************************************
@ -616,10 +681,56 @@ unsigned char * __RPC_USER HBITMAP_UserMarshal(ULONG *pFlags, unsigned char *pBu
* the first parameter is an ULONG.
* This function is only intended to be called by the RPC runtime.
*/
unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *pFlags, unsigned char *pBuffer, HBITMAP *phBmp)
unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *flags, unsigned char *buffer, HBITMAP *bmp)
{
FIXME(":stub\n");
return pBuffer;
ULONG context;
TRACE("(%s, %p, %p)\n", debugstr_user_flags(flags), buffer, bmp);
ALIGN_POINTER(buffer, 3);
context = *(ULONG *)buffer;
buffer += sizeof(ULONG);
if (context == WDT_INPROC_CALL)
{
*bmp = *(HBITMAP *)buffer;
buffer += sizeof(*bmp);
}
else if (context == WDT_REMOTE_CALL)
{
ULONG handle = *(ULONG *)buffer;
buffer += sizeof(ULONG);
if (handle)
{
static const ULONG header_size = FIELD_OFFSET(userBITMAP, cbSize);
BITMAP bitmap;
ULONG bitmap_size;
unsigned char *bits;
bitmap_size = *(ULONG *)buffer;
buffer += sizeof(ULONG);
bits = HeapAlloc(GetProcessHeap(), 0, bitmap_size);
memcpy(&bitmap, buffer, header_size);
buffer += header_size;
memcpy(bits, buffer, bitmap_size);
buffer += bitmap_size;
bitmap.bmBits = bits;
*bmp = CreateBitmapIndirect(&bitmap);
HeapFree(GetProcessHeap(), 0, bits);
}
else
*bmp = NULL;
}
else
RaiseException(RPC_S_INVALID_TAG, 0, 0, NULL);
return buffer;
}
/******************************************************************************
@ -640,9 +751,12 @@ unsigned char * __RPC_USER HBITMAP_UserUnmarshal(ULONG *pFlags, unsigned char *p
* which the first parameter is a ULONG.
* This function is only intended to be called by the RPC runtime.
*/
void __RPC_USER HBITMAP_UserFree(ULONG *pFlags, HBITMAP *phBmp)
void __RPC_USER HBITMAP_UserFree(ULONG *flags, HBITMAP *bmp)
{
FIXME(":stub\n");
TRACE("(%s, %p)\n", debugstr_user_flags(flags), *bmp);
if (LOWORD(*flags) != MSHCTX_INPROC)
DeleteObject(*bmp);
}
/******************************************************************************
@ -963,11 +1077,11 @@ void __RPC_USER HMETAFILE_UserFree(ULONG *pFlags, HMETAFILE *phmf)
* the first parameter is a ULONG.
* This function is only intended to be called by the RPC runtime.
*/
ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG StartingSize, HENHMETAFILE *phEmf)
ULONG __RPC_USER HENHMETAFILE_UserSize(ULONG *pFlags, ULONG size, HENHMETAFILE *phEmf)
{
ULONG size = StartingSize;
TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), size, *phEmf);
TRACE("(%s, %d, %p\n", debugstr_user_flags(pFlags), StartingSize, *phEmf);
ALIGN_LENGTH(size, 3);
size += sizeof(ULONG);
if (LOWORD(*pFlags) == MSHCTX_INPROC)
@ -1012,6 +1126,8 @@ unsigned char * __RPC_USER HENHMETAFILE_UserMarshal(ULONG *pFlags, unsigned char
{
TRACE("(%s, %p, &%p\n", debugstr_user_flags(pFlags), pBuffer, *phEmf);
ALIGN_POINTER(pBuffer, 3);
if (LOWORD(*pFlags) == MSHCTX_INPROC)
{
if (sizeof(*phEmf) == 8)
@ -1070,6 +1186,8 @@ unsigned char * __RPC_USER HENHMETAFILE_UserUnmarshal(ULONG *pFlags, unsigned ch
TRACE("(%s, %p, %p\n", debugstr_user_flags(pFlags), pBuffer, phEmf);
ALIGN_POINTER(pBuffer, 3);
fContext = *(ULONG *)pBuffer;
pBuffer += sizeof(ULONG);
@ -1155,11 +1273,11 @@ void __RPC_USER HENHMETAFILE_UserFree(ULONG *pFlags, HENHMETAFILE *phEmf)
* the first parameter is a ULONG.
* This function is only intended to be called by the RPC runtime.
*/
ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *pFlags, ULONG StartingSize, HMETAFILEPICT *phMfp)
ULONG __RPC_USER HMETAFILEPICT_UserSize(ULONG *pFlags, ULONG size, HMETAFILEPICT *phMfp)
{
ULONG size = StartingSize;
TRACE("(%s, %d, &%p)\n", debugstr_user_flags(pFlags), size, *phMfp);
TRACE("(%s, %d, &%p)\n", debugstr_user_flags(pFlags), StartingSize, *phMfp);
ALIGN_LENGTH(size, 3);
size += sizeof(ULONG);
@ -1209,6 +1327,8 @@ unsigned char * __RPC_USER HMETAFILEPICT_UserMarshal(ULONG *pFlags, unsigned cha
{
TRACE("(%s, %p, &%p)\n", debugstr_user_flags(pFlags), pBuffer, *phMfp);
ALIGN_POINTER(pBuffer, 3);
if (LOWORD(*pFlags) == MSHCTX_INPROC)
{
if (sizeof(HMETAFILEPICT) == 8)
@ -1272,6 +1392,8 @@ unsigned char * __RPC_USER HMETAFILEPICT_UserUnmarshal(ULONG *pFlags, unsigned c
TRACE("(%s, %p, %p)\n", debugstr_user_flags(pFlags), pBuffer, phMfp);
ALIGN_POINTER(pBuffer, 3);
fContext = *(ULONG *)pBuffer;
pBuffer += sizeof(ULONG);
@ -1602,9 +1724,7 @@ ULONG __RPC_USER STGMEDIUM_UserSize(ULONG *pFlags, ULONG StartingSize, STGMEDIUM
case TYMED_GDI:
TRACE("TYMED_GDI\n");
if (pStgMedium->u.hBitmap)
{
FIXME("not implemented for GDI object %p\n", pStgMedium->u.hBitmap);
}
size = HBITMAP_UserSize(pFlags, size, &pStgMedium->u.hBitmap);
break;
case TYMED_MFPICT:
TRACE("TYMED_MFPICT\n");
@ -1714,9 +1834,7 @@ unsigned char * __RPC_USER STGMEDIUM_UserMarshal(ULONG *pFlags, unsigned char *p
case TYMED_GDI:
TRACE("TYMED_GDI\n");
if (pStgMedium->u.hBitmap)
{
FIXME("not implemented for GDI object %p\n", pStgMedium->u.hBitmap);
}
pBuffer = HBITMAP_UserMarshal(pFlags, pBuffer, &pStgMedium->u.hBitmap);
break;
case TYMED_MFPICT:
TRACE("TYMED_MFPICT\n");
@ -1852,9 +1970,7 @@ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char
case TYMED_GDI:
TRACE("TYMED_GDI\n");
if (content)
{
FIXME("not implemented for GDI object\n");
}
pBuffer = HBITMAP_UserUnmarshal(pFlags, pBuffer, &pStgMedium->u.hBitmap);
else
pStgMedium->u.hBitmap = NULL;
break;

View file

@ -139,7 +139,7 @@ reactos/dll/win32/ntdsapi # Synced to WineStaging-2.9
reactos/dll/win32/objsel # Synced to WineStaging-2.9
reactos/dll/win32/odbc32 # Synced to WineStaging-2.9. Depends on port of Linux ODBC.
reactos/dll/win32/odbccp32 # Synced to WineStaging-2.9
reactos/dll/win32/ole32 # Synced to WineStaging-2.16
reactos/dll/win32/ole32 # Synced to Wine-3.0
reactos/dll/win32/oleacc # Synced to WineStaging-2.9
reactos/dll/win32/oleaut32 # Synced to WineStaging-2.16
reactos/dll/win32/olecli32 # Synced to WineStaging-2.9