[OLE32] Sync with Wine Staging 3.3. CORE-14434

This commit is contained in:
Amine Khaldi 2018-03-20 12:38:17 +01:00
parent 4ca633cc2a
commit c0f9087299
42 changed files with 1057 additions and 435 deletions

View file

@ -18,7 +18,19 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "objbase.h"
#include "wine/debug.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -18,7 +18,18 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "objbase.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -19,7 +19,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wine/debug.h"
#include "ole2.h"
#include "wine/unicode.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -58,9 +58,28 @@
*
*/
#include "precomp.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winnls.h"
#include "ole2.h"
#include "wine/debug.h"
#include "olestd.h"
#include "storage32.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* Structure of 'Ole Private Data' clipboard format */

View file

@ -18,7 +18,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <string.h>
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "ole2.h"
#include "comcat.h"
#include "compobj_private.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -36,10 +36,38 @@
*
*/
#include "precomp.h"
#include "config.h"
#include <ctxtcall.h>
#include <dde.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "winuser.h"
#define USE_COM_CONTEXT_DEF
#include "objbase.h"
#include "ole2.h"
#include "ole2ver.h"
#include "ctxtcall.h"
#include "dde.h"
#include "servprov.h"
#ifndef __REACTOS__
#include "initguid.h"
#endif
#include "compobj_private.h"
#include "moniker.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@ -4445,6 +4473,8 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
APARTMENT *apt = COM_CurrentApt();
BOOL message_loop = apt && !apt->multi_threaded;
BOOL check_apc = (dwFlags & COWAIT_ALERTABLE) != 0;
BOOL post_quit = FALSE;
UINT exit_code;
TRACE("(0x%08x, 0x%08x, %d, %p, %p)\n", dwFlags, dwTimeout, cHandles,
pHandles, lpdwindex);
@ -4525,20 +4555,27 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
}
}
if (!apt->win)
{
/* If window is NULL on apartment, peek at messages so that it will not trigger
* MsgWaitForMultipleObjects next time. */
PeekMessageW(NULL, NULL, 0, 0, PM_QS_POSTMESSAGE | PM_NOREMOVE | PM_NOYIELD);
}
/* some apps (e.g. Visio 2010) don't handle WM_PAINT properly and loop forever,
* so after processing 100 messages we go back to checking the wait handles */
while (count++ < 100 && COM_PeekMessage(apt, &msg))
{
TRACE("received message whilst waiting for RPC: 0x%04x\n", msg.message);
TranslateMessage(&msg);
DispatchMessageW(&msg);
if (msg.message == WM_QUIT)
{
TRACE("resending WM_QUIT to outer message loop\n");
PostQuitMessage(msg.wParam);
/* no longer need to process messages */
message_loop = FALSE;
break;
TRACE("received WM_QUIT message\n");
post_quit = TRUE;
exit_code = msg.wParam;
}
else
{
TRACE("received message whilst waiting for RPC: 0x%04x\n", msg.message);
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
continue;
@ -4567,6 +4604,7 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
}
break;
}
if (post_quit) PostQuitMessage(exit_code);
TRACE("-- 0x%08x\n", hr);
return hr;
}

View file

@ -27,6 +27,18 @@
/* All private prototype functions used by OLE will be added to this header file */
#include <stdarg.h>
#include "wine/list.h"
#include "wine/heap.h"
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "dcom.h"
#include "winreg.h"
#include "winternl.h"
struct apartment;
typedef struct apartment APARTMENT;
typedef struct LocalServer LocalServer;
@ -248,7 +260,7 @@ void leave_apartment(struct oletls *info) DECLSPEC_HIDDEN;
static inline struct oletls *COM_CurrentInfo(void)
{
if (!NtCurrentTeb()->ReservedForOle)
NtCurrentTeb()->ReservedForOle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct oletls));
NtCurrentTeb()->ReservedForOle = heap_alloc_zero(sizeof(struct oletls));
return NtCurrentTeb()->ReservedForOle;
}
@ -312,16 +324,6 @@ extern BOOL actctx_get_miscstatus(const CLSID*, DWORD, DWORD*) DECLSPEC_HIDDEN;
extern const char *debugstr_formatetc(const FORMATETC *formatetc) DECLSPEC_HIDDEN;
static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t len)
{
return HeapAlloc(GetProcessHeap(), 0, len);
}
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
}
static inline HRESULT copy_formatetc(FORMATETC *dst, const FORMATETC *src)
{
*dst = *src;

View file

@ -18,7 +18,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "ole2.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -44,7 +44,22 @@
* was stored and the aspect, but that's about it.
*/
#include "precomp.h"
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "ole2.h"
#include "compobj_private.h"
#include "wine/unicode.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@ -75,12 +90,8 @@ typedef struct PresentationDataHeader
DWORD dwSize;
} PresentationDataHeader;
enum stream_type
{
no_stream,
pres_stream,
contents_stream
};
#define STREAM_NUMBER_NOT_SET -2
#define STREAM_NUMBER_CONTENTS -1 /* CONTENTS stream */
typedef struct DataCacheEntry
{
@ -89,19 +100,16 @@ typedef struct DataCacheEntry
FORMATETC fmtetc;
/* cached data */
STGMEDIUM stgmedium;
/*
* This stream pointer is set through a call to
* IPersistStorage_Load. This is where the visual
* representation of the object is stored.
*/
IStream *stream;
enum stream_type stream_type;
/* connection ID */
DWORD id;
/* dirty flag */
BOOL dirty;
/* stream number (-1 if not set ) */
unsigned short stream_number;
/* stream number that the entry was loaded from.
This is used to defer loading until the data is actually needed. */
int load_stream_num;
/* stream number that the entry will be saved to.
This may differ from above if cache entries have been Uncache()d for example. */
int save_stream_num;
/* sink id set when object is running */
DWORD sink_id;
/* Advise sink flags */
@ -147,6 +155,9 @@ struct DataCache
IAdviseSink *sinkInterface;
CLSID clsid;
/* Is the clsid one of the CLSID_Picture classes */
BOOL clsid_static;
IStorage *presentationStorage;
/* list of cache entries */
@ -242,8 +253,6 @@ static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
static void DataCacheEntry_Destroy(DataCache *cache, DataCacheEntry *cache_entry)
{
list_remove(&cache_entry->entry);
if (cache_entry->stream)
IStream_Release(cache_entry->stream);
CoTaskMemFree(cache_entry->fmtetc.ptd);
ReleaseStgMedium(&cache_entry->stgmedium);
if(cache_entry->sink_id)
@ -303,6 +312,29 @@ static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FOR
return NULL;
}
/* Returns the cache entry associated with a static CLSID.
This will be first in the list with connection id == 1 */
static HRESULT get_static_entry( DataCache *cache, DataCacheEntry **cache_entry )
{
DataCacheEntry *entry;
struct list *head = list_head( &cache->cache_list );
HRESULT hr = E_FAIL;
*cache_entry = NULL;
if (head)
{
entry = LIST_ENTRY( head, DataCacheEntry, entry );
if (entry->id == 1)
{
*cache_entry = entry;
hr = S_OK;
}
}
return hr;
}
/* 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 */
@ -337,11 +369,10 @@ static BOOL init_cache_entry(DataCacheEntry *entry, const FORMATETC *fmt, DWORD
entry->stgmedium.tymed = TYMED_NULL;
entry->stgmedium.pUnkForRelease = NULL;
entry->stream = NULL;
entry->stream_type = no_stream;
entry->id = id;
entry->dirty = TRUE;
entry->stream_number = -1;
entry->load_stream_num = STREAM_NUMBER_NOT_SET;
entry->save_stream_num = STREAM_NUMBER_NOT_SET;
entry->sink_id = 0;
entry->advise_flags = advf;
@ -428,23 +459,6 @@ static void DataCache_FireOnViewChange(
}
}
/* Helper for DataCacheEntry_OpenPresStream */
static BOOL DataCache_IsPresentationStream(const STATSTG *elem)
{
/* The presentation streams have names of the form "\002OlePresXXX",
* where XXX goes from 000 to 999. */
static const WCHAR OlePres[] = { 2,'O','l','e','P','r','e','s' };
LPCWSTR name = elem->pwcsName;
return (elem->type == STGTY_STREAM)
&& (strlenW(name) == 11)
&& (strncmpW(name, OlePres, 8) == 0)
&& (name[8] >= '0') && (name[8] <= '9')
&& (name[9] >= '0') && (name[9] <= '9')
&& (name[10] >= '0') && (name[10] <= '9');
}
static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat)
{
DWORD length;
@ -491,7 +505,9 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat)
HRESULT hr;
char format_name[256];
if (clipformat < 0xc000)
if (clipformat == 0)
length = 0;
else if (clipformat < 0xc000)
length = -1;
else
{
@ -500,8 +516,9 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat)
if (length) length++;
}
hr = IStream_Write(stream, &length, sizeof(length), NULL);
if (FAILED(hr))
if (FAILED(hr) || clipformat == 0)
return hr;
if (clipformat < 0xc000)
{
DWORD cf = clipformat;
@ -514,55 +531,22 @@ static HRESULT write_clipformat(IStream *stream, CLIPFORMAT clipformat)
return hr;
}
/************************************************************************
* DataCacheEntry_OpenPresStream
*
* This method will find the stream for the given presentation. It makes
* no attempt at fallback.
*
* Param:
* this - Pointer to the DataCache object
* drawAspect - The aspect of the object that we wish to draw.
* pStm - A returned stream. It points to the beginning of the
* - presentation data, including the header.
*
* Errors:
* S_OK The requested stream has been opened.
* OLE_E_BLANK The requested stream could not be found.
* Quite a few others I'm too lazy to map correctly.
*
* Notes:
* Algorithm: Scan the elements of the presentation storage, looking
* for presentation streams. For each presentation stream,
* load the header and check to see if the aspect matches.
*
* If a fallback is desired, just opening the first presentation stream
* is a possibility.
*/
static HRESULT DataCacheEntry_OpenPresStream(DataCacheEntry *cache_entry, IStream **ppStm)
static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
static HRESULT open_pres_stream( IStorage *stg, int stream_number, IStream **stm )
{
HRESULT hr;
LARGE_INTEGER offset;
WCHAR pres[] = {2,'O','l','e','P','r','e','s',
'0' + (stream_number / 100) % 10,
'0' + (stream_number / 10) % 10,
'0' + stream_number % 10, 0};
const WCHAR *name = pres;
if (cache_entry->stream)
{
/* Rewind the stream before returning it. */
offset.QuadPart = 0;
if (stream_number == STREAM_NUMBER_NOT_SET) return E_FAIL;
if (stream_number == STREAM_NUMBER_CONTENTS) name = CONTENTS;
hr = IStream_Seek( cache_entry->stream, offset, STREAM_SEEK_SET, NULL );
if (SUCCEEDED( hr ))
{
*ppStm = cache_entry->stream;
IStream_AddRef( cache_entry->stream );
}
}
else
hr = OLE_E_BLANK;
return hr;
return IStorage_OpenStream( stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
}
static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
{
HRESULT hr;
@ -576,9 +560,9 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
static const LARGE_INTEGER offset_zero;
ULONG read;
if (cache_entry->stream_type != pres_stream)
if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS)
{
FIXME( "Unimplemented for stream type %d\n", cache_entry->stream_type );
FIXME( "Unimplemented for CONTENTS stream\n" );
return E_FAIL;
}
@ -645,9 +629,9 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
BITMAPFILEHEADER file;
BITMAPINFOHEADER *info;
if (cache_entry->stream_type != contents_stream)
if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
{
FIXME( "Unimplemented for stream type %d\n", cache_entry->stream_type );
FIXME( "Unimplemented for presentation stream\n" );
return E_FAIL;
}
@ -733,12 +717,13 @@ fail:
* This method returns a metafile handle if it is successful.
* it will return 0 if not.
*/
static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry)
static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry, IStorage *stg)
{
HRESULT hr;
IStream *stm;
hr = DataCacheEntry_OpenPresStream( cache_entry, &stm );
if (!stg) return OLE_E_BLANK;
hr = open_pres_stream( stg, cache_entry->load_stream_num, &stm );
if (FAILED(hr)) return hr;
switch (cache_entry->fmtetc.cfFormat)
@ -978,14 +963,26 @@ static HRESULT save_emf(DataCacheEntry *entry, BOOL contents, IStream *stream)
return hr;
}
static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0};
static HRESULT save_view_cache(DataCacheEntry *entry, IStream *stream)
{
HRESULT hr;
PresentationDataHeader header;
init_stream_header(entry, &header);
hr = write_clipformat(stream, entry->fmtetc.cfFormat);
if (SUCCEEDED(hr))
hr = IStream_Write(stream, &header, FIELD_OFFSET(PresentationDataHeader, unknown7), NULL);
return hr;
}
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};
'0' + (cache_entry->save_stream_num / 100) % 10,
'0' + (cache_entry->save_stream_num / 10) % 10,
'0' + cache_entry->save_stream_num % 10, 0};
const WCHAR *name;
if (contents)
@ -1005,7 +1002,7 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag
IStream *stream;
BOOL contents = (cache_entry->id == 1);
TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->stream_number, debugstr_formatetc(&cache_entry->fmtetc));
TRACE("stream_number = %d, fmtetc = %s\n", cache_entry->save_stream_num, debugstr_formatetc(&cache_entry->fmtetc));
hr = create_stream(cache_entry, storage, contents, &stream);
if (FAILED(hr))
@ -1022,6 +1019,9 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag
case CF_ENHMETAFILE:
hr = save_emf(cache_entry, contents, stream);
break;
case 0:
hr = save_view_cache(cache_entry, stream);
break;
default:
FIXME("got unsupported clipboard format %x\n", cache_entry->fmtetc.cfFormat);
}
@ -1187,11 +1187,11 @@ static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
return copy_stg_medium(cache_entry->fmtetc.cfFormat, &cache_entry->stgmedium, stgmedium);
}
static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, FORMATETC *fmt, STGMEDIUM *stgmedium)
static HRESULT DataCacheEntry_GetData(DataCacheEntry *cache_entry, IStorage *stg, FORMATETC *fmt, STGMEDIUM *stgmedium)
{
if (cache_entry->stgmedium.tymed == TYMED_NULL && cache_entry->stream)
if (cache_entry->stgmedium.tymed == TYMED_NULL && cache_entry->load_stream_num != STREAM_NUMBER_NOT_SET)
{
HRESULT hr = DataCacheEntry_LoadData(cache_entry);
HRESULT hr = DataCacheEntry_LoadData(cache_entry, stg);
if (FAILED(hr))
return hr;
}
@ -1210,15 +1210,6 @@ static inline HRESULT DataCacheEntry_DiscardData(DataCacheEntry *cache_entry)
return S_OK;
}
static inline void DataCacheEntry_HandsOffStorage(DataCacheEntry *cache_entry)
{
if (cache_entry->stream)
{
IStream_Release(cache_entry->stream);
cache_entry->stream = NULL;
}
}
static inline DWORD tymed_from_cf( DWORD cf )
{
switch( cf )
@ -1273,9 +1264,13 @@ static HRESULT create_automatic_entry(DataCache *cache, const CLSID *clsid)
while (ptr->clsid)
{
if (IsEqualCLSID( clsid, ptr->clsid ))
{
cache->clsid_static = TRUE;
return DataCache_CreateEntry( cache, &ptr->fmt, 0, TRUE, NULL );
}
ptr++;
}
cache->clsid_static = FALSE;
return S_OK;
}
@ -1437,7 +1432,7 @@ static HRESULT WINAPI DataCache_GetData(
if (!cache_entry)
return OLE_E_BLANK;
return DataCacheEntry_GetData(cache_entry, pformatetcIn, pmedium);
return DataCacheEntry_GetData(cache_entry, This->presentationStorage, pformatetcIn, pmedium);
}
static HRESULT WINAPI DataCache_GetDataHere(
@ -1670,8 +1665,7 @@ static HRESULT WINAPI DataCache_InitNew(
}
static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD advf, IStream *stm,
enum stream_type type )
static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD advf, int stream_number )
{
DataCacheEntry *cache_entry;
HRESULT hr = S_OK;
@ -1684,82 +1678,68 @@ static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, DWORD adv
if (SUCCEEDED( hr ))
{
DataCacheEntry_DiscardData( cache_entry );
if (cache_entry->stream) IStream_Release( cache_entry->stream );
cache_entry->stream = stm;
IStream_AddRef( stm );
cache_entry->stream_type = type;
cache_entry->load_stream_num = stream_number;
cache_entry->save_stream_num = stream_number;
cache_entry->dirty = FALSE;
}
return hr;
}
static HRESULT parse_pres_streams( DataCache *This, IStorage *stg )
static HRESULT parse_pres_streams( DataCache *cache, IStorage *stg )
{
HRESULT hr;
IEnumSTATSTG *stat_enum;
STATSTG stat;
IStream *stm;
PresentationDataHeader header;
ULONG actual_read;
CLIPFORMAT clipformat;
FORMATETC fmtetc;
int stream_number = 0;
hr = IStorage_EnumElements( stg, 0, NULL, 0, &stat_enum );
if (FAILED( hr )) return hr;
while ((hr = IEnumSTATSTG_Next( stat_enum, 1, &stat, NULL )) == S_OK)
do
{
if (DataCache_IsPresentationStream( &stat ))
hr = open_pres_stream( stg, stream_number, &stm );
if (FAILED(hr)) break;
hr = read_clipformat( stm, &clipformat );
if (hr == S_OK) hr = IStream_Read( stm, &header, sizeof(header), &actual_read );
if (hr == S_OK && actual_read == sizeof(header))
{
hr = IStorage_OpenStream( stg, stat.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
0, &stm );
if (SUCCEEDED( hr ))
{
hr = read_clipformat( stm, &clipformat );
fmtetc.cfFormat = clipformat;
fmtetc.ptd = NULL; /* FIXME */
fmtetc.dwAspect = header.dvAspect;
fmtetc.lindex = header.lindex;
fmtetc.tymed = tymed_from_cf( clipformat );
if (hr == S_OK)
hr = IStream_Read( stm, &header, sizeof(header), &actual_read );
if (hr == S_OK && actual_read == sizeof(header))
{
fmtetc.cfFormat = clipformat;
fmtetc.ptd = NULL; /* FIXME */
fmtetc.dwAspect = header.dvAspect;
fmtetc.lindex = header.lindex;
fmtetc.tymed = tymed_from_cf( clipformat );
add_cache_entry( This, &fmtetc, header.advf, stm, pres_stream );
}
IStream_Release( stm );
}
add_cache_entry( cache, &fmtetc, header.advf, stream_number );
}
CoTaskMemFree( stat.pwcsName );
}
IEnumSTATSTG_Release( stat_enum );
IStream_Release( stm );
stream_number++;
} while (hr == S_OK);
return S_OK;
}
static const FORMATETC static_dib_fmt = { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *stm )
static HRESULT parse_contents_stream( DataCache *cache, IStorage *stg )
{
HRESULT hr;
STATSTG stat;
const FORMATETC *fmt;
IStream *stm;
DataCacheEntry *cache_entry;
hr = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
hr = open_pres_stream( stg, STREAM_NUMBER_CONTENTS, &stm );
if (FAILED( hr )) return hr;
if (IsEqualCLSID( &stat.clsid, &CLSID_Picture_Dib ))
fmt = &static_dib_fmt;
else
hr = get_static_entry( cache, &cache_entry );
if (hr == S_OK)
{
FIXME("unsupported format %s\n", debugstr_guid( &stat.clsid ));
return E_FAIL;
cache_entry->load_stream_num = STREAM_NUMBER_CONTENTS;
cache_entry->save_stream_num = STREAM_NUMBER_CONTENTS;
cache_entry->dirty = FALSE;
}
return add_cache_entry( This, fmt, 0, stm, contents_stream );
IStream_Release( stm );
return hr;
}
/************************************************************************
@ -1770,42 +1750,38 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *s
* and it will load the presentation information when the
* IDataObject_GetData or IViewObject2_Draw methods are called.
*/
static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg )
static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *stg )
{
DataCache *This = impl_from_IPersistStorage(iface);
HRESULT hr;
IStream *stm;
CLSID clsid;
DataCacheEntry *entry, *cursor2;
TRACE("(%p, %p)\n", iface, pStg);
TRACE("(%p, %p)\n", iface, stg);
IPersistStorage_HandsOffStorage( iface );
LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry )
DataCacheEntry_Destroy( This, entry );
ReadClassStg( pStg, &clsid );
ReadClassStg( stg, &clsid );
hr = create_automatic_entry( This, &clsid );
if (FAILED( hr )) return hr;
This->clsid = clsid;
hr = IStorage_OpenStream( pStg, CONTENTS, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE,
0, &stm );
if (SUCCEEDED( hr ))
if (This->clsid_static)
{
hr = parse_contents_stream( This, pStg, stm );
IStream_Release( stm );
hr = parse_contents_stream( This, stg );
if (FAILED(hr)) hr = parse_pres_streams( This, stg );
}
if (FAILED(hr))
hr = parse_pres_streams( This, pStg );
else
hr = parse_pres_streams( This, stg );
if (SUCCEEDED( hr ))
{
This->dirty = FALSE;
This->presentationStorage = pStg;
This->presentationStorage = stg;
IStorage_AddRef( This->presentationStorage );
}
@ -1825,17 +1801,17 @@ static HRESULT WINAPI DataCache_Save(IPersistStorage* iface, IStorage *stg, BOOL
DataCache *This = impl_from_IPersistStorage(iface);
DataCacheEntry *cache_entry;
HRESULT hr = S_OK;
unsigned short stream_number = 0;
int stream_number = 0;
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)
{
if (cache_entry->stream_number != stream_number)
if (cache_entry->save_stream_num != stream_number)
{
cache_entry->dirty = TRUE; /* needs to be written out again */
cache_entry->stream_number = stream_number;
cache_entry->save_stream_num = stream_number;
}
stream_number++;
}
@ -1889,7 +1865,6 @@ static HRESULT WINAPI DataCache_HandsOffStorage(
IPersistStorage* iface)
{
DataCache *this = impl_from_IPersistStorage(iface);
DataCacheEntry *cache_entry;
TRACE("(%p)\n", iface);
@ -1899,9 +1874,6 @@ static HRESULT WINAPI DataCache_HandsOffStorage(
this->presentationStorage = NULL;
}
LIST_FOR_EACH_ENTRY(cache_entry, &this->cache_list, DataCacheEntry, entry)
DataCacheEntry_HandsOffStorage(cache_entry);
return S_OK;
}
@ -1991,9 +1963,9 @@ static HRESULT WINAPI DataCache_Draw(
continue;
/* if the data hasn't been loaded yet, do it now */
if ((cache_entry->stgmedium.tymed == TYMED_NULL) && cache_entry->stream)
if ((cache_entry->stgmedium.tymed == TYMED_NULL) && (cache_entry->load_stream_num != STREAM_NUMBER_NOT_SET))
{
hres = DataCacheEntry_LoadData(cache_entry);
hres = DataCacheEntry_LoadData(cache_entry, This->presentationStorage);
if (FAILED(hres))
continue;
}
@ -2251,9 +2223,9 @@ static HRESULT WINAPI DataCache_GetExtent(
continue;
/* if the data hasn't been loaded yet, do it now */
if ((cache_entry->stgmedium.tymed == TYMED_NULL) && cache_entry->stream)
if ((cache_entry->stgmedium.tymed == TYMED_NULL) && (cache_entry->load_stream_num != STREAM_NUMBER_NOT_SET))
{
hres = DataCacheEntry_LoadData(cache_entry);
hres = DataCacheEntry_LoadData(cache_entry, This->presentationStorage);
if (FAILED(hres))
continue;
}
@ -2426,6 +2398,8 @@ static HRESULT WINAPI DataCache_Cache(
return CACHE_S_SAMECACHE;
}
if (This->clsid_static && fmt_cpy.dwAspect != DVASPECT_ICON) return DV_E_FORMATETC;
hr = DataCache_CreateEntry(This, &fmt_cpy, advf, FALSE, &cache_entry);
if (SUCCEEDED(hr))
@ -2944,6 +2918,7 @@ static DataCache* DataCache_Construct(
newObject->sinkAdviseFlag = 0;
newObject->sinkInterface = 0;
newObject->clsid = CLSID_NULL;
newObject->clsid_static = FALSE;
newObject->presentationStorage = NULL;
list_init(&newObject->cache_list);
newObject->last_cache_id = 2;

View file

@ -45,10 +45,24 @@
* - All the methods related to notification and advise sinks are
* in place but no notifications are sent to the sinks yet.
*/
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include "precomp.h"
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "ole2.h"
#include "compobj_private.h"
#include "storage32.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
enum storage_state

View file

@ -17,8 +17,12 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "dictionary.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);

View file

@ -22,6 +22,10 @@
#ifndef __DICTIONARY_H__
#define __DICTIONARY_H__
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
struct dictionary;
/* Returns whether key a is less than, equal to, or greater than key b, in

View file

@ -18,7 +18,18 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#define COBJMACROS
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "enumx.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@ -30,6 +41,8 @@ struct tagEnumSTATPROPSETSTG_impl
struct list *current;
ULONG elem_size;
GUID riid;
IUnknown *parent;
enumx_copy_cb copy_cb;
};
/************************************************************************
@ -80,6 +93,7 @@ ULONG WINAPI enumx_Release(enumx_impl *This)
list_remove(x);
HeapFree(GetProcessHeap(), 0, x);
}
IUnknown_Release(This->parent);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
@ -101,7 +115,10 @@ HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
p = rgelt;
while (count < celt && This->current && This->current != &This->elements)
{
memcpy(p, &This->current[1], This->elem_size);
if (This->copy_cb)
This->copy_cb(This->parent, &This->current[1], p);
else
memcpy(p, &This->current[1], This->elem_size);
p += This->elem_size;
This->current = This->current->next;
count++;
@ -158,7 +175,8 @@ HRESULT WINAPI enumx_Clone(
*
* Allocate a generic enumerator
*/
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size,
IUnknown *parent, enumx_copy_cb copy_cb)
{
enumx_impl *enumx;
@ -170,6 +188,11 @@ 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,6 +21,8 @@
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;
@ -28,7 +30,8 @@ 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) DECLSPEC_HIDDEN;
extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG,
IUnknown *, enumx_copy_cb) DECLSPEC_HIDDEN;
extern void *enumx_add_element(enumx_impl *, const void *) DECLSPEC_HIDDEN;
#endif /* __OLE_ENUM_H__ */
#endif

View file

@ -23,7 +23,21 @@
* TEB at offset 0xf80.
*/
#include "precomp.h"
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "oleauto.h"
#include "winerror.h"
#include "wine/unicode.h"
#include "compobj_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -20,9 +20,29 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "objbase.h"
#include "ole2.h"
#include "storage32.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);
typedef struct FileLockBytesImpl

View file

@ -19,7 +19,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "objbase.h"
#include "moniker.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -18,7 +18,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "objbase.h"
#include "wine/debug.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -24,7 +24,21 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "compobj_private.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -5,6 +5,7 @@
* 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
@ -21,9 +22,179 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "winternl.h"
#include "wine/debug.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;
}
/****************************************************************************
* HGLOBALStreamImpl definition.
@ -36,14 +207,7 @@ typedef struct
IStream IStream_iface;
LONG ref;
/* 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;
struct handle_wrapper *handle;
/* current position of the cursor */
ULARGE_INTEGER currentPosition;
@ -95,12 +259,7 @@ static ULONG WINAPI HGLOBALStreamImpl_Release(
if (!ref)
{
if (This->deleteOnRelease)
{
GlobalFree(This->supportHandle);
This->supportHandle = NULL;
}
handle_release(This->handle);
HeapFree(GetProcessHeap(), 0, This);
}
@ -123,59 +282,12 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
ULONG* pcbRead) /* [out] */
{
HGLOBALStreamImpl* This = impl_from_IStream(iface);
ULONG num_bytes;
void* supportBuffer;
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbRead);
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
*/
num_bytes = handle_read(This->handle, &This->currentPosition.u.LowPart, pv, cb);
if (pcbRead) *pcbRead = num_bytes;
return S_OK;
}
@ -197,71 +309,14 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
ULONG* pcbWritten) /* [out] */
{
HGLOBALStreamImpl* This = impl_from_IStream(iface);
void* supportBuffer;
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
ULONG num_bytes;
TRACE("(%p, %p, %d, %p)\n", iface, pv, cb, pcbWritten);
/*
* 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;
num_bytes = handle_write(This->handle, &This->currentPosition.u.LowPart, pv, cb);
if (pcbWritten) *pcbWritten = num_bytes;
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;
return (num_bytes < cb) ? E_OUTOFMEMORY : S_OK;
}
/***
@ -299,7 +354,7 @@ static HRESULT WINAPI HGLOBALStreamImpl_Seek(
case STREAM_SEEK_CUR:
break;
case STREAM_SEEK_END:
newPosition = This->streamSize;
newPosition.QuadPart = handle_getsize(This->handle);
break;
default:
hr = STG_E_SEEKERROR;
@ -344,29 +399,13 @@ 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
*/
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;
return handle_setsize(This->handle, libNewSize.u.LowPart);
}
/***
@ -514,24 +553,49 @@ static HRESULT WINAPI HGLOBALStreamImpl_Stat(
pstatstg->pwcsName = NULL;
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize = This->streamSize;
pstatstg->cbSize.QuadPart = handle_getsize(This->handle);
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;
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;
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;
offset.QuadPart = (LONGLONG)This->currentPosition.QuadPart;
IStream_Seek(*ppstm, offset, STREAM_SEEK_SET, &dummy);
return S_OK;
@ -568,28 +632,19 @@ HRESULT WINAPI CreateStreamOnHGlobal(
if (!ppstm)
return E_INVALIDARG;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(HGLOBALStreamImpl));
This = HGLOBALStreamImpl_Create();
if (!This) return E_OUTOFMEMORY;
This->IStream_iface.lpVtbl = &HGLOBALStreamImplVtbl;
This->ref = 1;
/* 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);
if (!hGlobal)
hGlobal = GlobalAlloc(GMEM_MOVEABLE|GMEM_NODISCARD|GMEM_SHARE, 0);
This->handle = handle_create(hGlobal, fDeleteOnRelease);
/* 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;
@ -602,16 +657,16 @@ HRESULT WINAPI GetHGlobalFromStream(IStream* pstm, HGLOBAL* phglobal)
{
HGLOBALStreamImpl* pStream;
if (pstm == NULL)
if (!pstm || !phglobal)
return E_INVALIDARG;
pStream = (HGLOBALStreamImpl*) pstm;
pStream = impl_from_IStream(pstm);
/*
* Verify that the stream object was created with CreateStreamOnHGlobal.
*/
if (pStream->IStream_iface.lpVtbl == &HGLOBALStreamImplVtbl)
*phglobal = pStream->supportHandle;
*phglobal = handle_gethglobal(pStream->handle);
else
{
*phglobal = 0;

View file

@ -18,7 +18,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "winerror.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(olemalloc);

View file

@ -18,7 +18,22 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/debug.h"
#include "ole2.h"
#include "wine/unicode.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -20,7 +20,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "wine/unicode.h"
#include "compobj_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -19,7 +19,23 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -21,12 +21,30 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include "wine/port.h"
#include <winsvc.h>
#include <wine/exception.h>
#include <stdarg.h>
#include <string.h>
#include <irot.h>
#define COBJMACROS
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winsvc.h"
#include "wtypes.h"
#include "ole2.h"
#include "wine/list.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/exception.h"
#include "compobj_private.h"
#include "moniker.h"
#include "irot.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -23,9 +23,33 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "ole2.h"
#include "ole2ver.h"
#include "wine/unicode.h"
#include "compobj_private.h"
#include "olestd.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
WINE_DECLARE_DEBUG_CHANNEL(accel);

View file

@ -18,7 +18,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/debug.h"
#include "ole2.h"
#include "olestd.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -19,7 +19,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "objidl.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -18,7 +18,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "objbase.h"
#include "ole2.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -18,17 +18,17 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
//#include "windef.h"
//#include "winbase.h"
//#include "winuser.h"
//#include "winnls.h"
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#include "olestd.h"
#define WINE_FILENAME_STR "ole32.dll"
#define WINE_EXTRAVALUES VALUE "OLESelfRegister",""
#include <wine/wine_common_ver.rc>
#include "wine/wine_common_ver.rc"
/*
* Everything that does not depend on language,

View file

@ -19,7 +19,21 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/debug.h"
#include "ole2.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -19,7 +19,27 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "rpc.h"
#include "compobj_private.h"
#include "moniker.h"
#include "comcat.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -19,7 +19,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winuser.h"
#include "objbase.h"
#include "oleidl.h"
#include "wine/debug.h"
#include "moniker.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -1,7 +1,8 @@
#ifndef _OLE32_PCH_
#define _OLE32_PCH_
#include <config.h>
#include <wine/config.h>
#include <assert.h>
#include <stdarg.h>
@ -36,4 +37,4 @@
#include "enumx.h"
#include "moniker.h"
#endif /* _OLE32_PCH_ */
#endif /* !_OLE32_PCH_ */

View file

@ -20,9 +20,30 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include "config.h"
#include "wine/port.h"
#include <winsvc.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winsvc.h"
#include "objbase.h"
#include "ole2.h"
#include "rpc.h"
#include "winerror.h"
#include "winreg.h"
#include "servprov.h"
#include "wine/unicode.h"
#include "compobj_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -36,8 +36,28 @@
* PropertyStorage_ReadFromStream
*/
#include "precomp.h"
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "dictionary.h"
#include "storage32.h"
#include "enumx.h"
#include "oleauto.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);
@ -1004,15 +1024,18 @@ static HRESULT PropertyStorage_ReadDictionary(PropertyStorage_impl *This,
if (This->codePage != CP_UNICODE)
ptr[cbEntry - 1] = '\0';
else
*((LPWSTR)ptr + cbEntry / sizeof(WCHAR)) = '\0';
((LPWSTR)ptr)[cbEntry - 1] = 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 += sizeof(DWORD) + cbEntry;
ptr += cbEntry;
}
return hr;
}
@ -1053,6 +1076,10 @@ 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);
@ -1071,6 +1098,18 @@ 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;
@ -2364,7 +2403,9 @@ static HRESULT create_EnumSTATPROPSETSTG(
enumx = enumx_allocate(&IID_IEnumSTATPROPSETSTG,
&IEnumSTATPROPSETSTG_Vtbl,
sizeof (STATPROPSETSTG));
sizeof (STATPROPSETSTG),
(IUnknown*)&This->base.IStorage_iface,
NULL);
/* add all the property set elements into a list */
r = IStorage_EnumElements(stg, 0, NULL, 0, &penum);
@ -2457,6 +2498,27 @@ 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;
@ -2483,7 +2545,9 @@ static HRESULT create_EnumSTATPROPSTG(
enumx = enumx_allocate(&IID_IEnumSTATPROPSTG,
&IEnumSTATPROPSTG_Vtbl,
sizeof (STATPROPSTG));
sizeof (STATPROPSTG),
(IUnknown*)&This->IPropertyStorage_iface,
prop_enum_copy_cb);
dictionary_enumerate(This->propid_to_prop, prop_enum_stat, enumx);

View file

@ -23,7 +23,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winternl.h"
#include "wine/debug.h"
#include "storage32.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);
@ -590,7 +603,6 @@ static HRESULT WINAPI StgStreamImpl_Clone(
IStream** ppstm) /* [out] */
{
StgStreamImpl* This = impl_from_IStream(iface);
HRESULT hres;
StgStreamImpl* new_stream;
LARGE_INTEGER seek_pos;
@ -616,11 +628,7 @@ static HRESULT WINAPI StgStreamImpl_Clone(
seek_pos.QuadPart = This->currentPosition.QuadPart;
hres = IStream_Seek(*ppstm, seek_pos, STREAM_SEEK_SET, NULL);
assert (SUCCEEDED(hres));
return S_OK;
return IStream_Seek(*ppstm, seek_pos, STREAM_SEEK_SET, NULL);
}
/*

View file

@ -30,10 +30,28 @@
* residing in a compound file object.
*/
#include "precomp.h"
#include "storage32.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wine/wingdi16.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "storage32.h"
#include "ole2.h" /* For Write/ReadClassStm */
#include "winreg.h"
#include "wine/wingdi16.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(storage);

View file

@ -27,10 +27,19 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __STORAGE32_H__
#define __STORAGE32_H__
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "objbase.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/list.h"
/*
* Definitions for the file format offsets.
*/

View file

@ -23,12 +23,26 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#define COBJMACROS
#include <wine/exception.h>
#include <assert.h>
#include <stdarg.h>
#include <limits.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "objbase.h"
#include "rpc.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "compobj_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* generates an ipid in the following format (similar to native version):
* Data1 = apartment-local ipid counter
* Data2 = apartment creator thread ID

View file

@ -18,7 +18,25 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "precomp.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "ole2.h"
#include "oleauto.h"
#include "rpcproxy.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

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