Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
587ba291
Commit
587ba291
authored
Dec 01, 2006
by
Rob Shearman
Committed by
Alexandre Julliard
Dec 04, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Implement saving of the data cache.
Document a few of the unknown fields in the presentation data header.
parent
e5c82d3a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
155 additions
and
17 deletions
+155
-17
datacache.c
dlls/ole32/datacache.c
+152
-10
ole2.c
dlls/ole32/tests/ole2.c
+3
-7
No files found.
dlls/ole32/datacache.c
View file @
587ba291
...
...
@@ -73,12 +73,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
typedef
struct
PresentationDataHeader
{
DWORD
unknown1
;
/* -1 */
DWORD
unknown2
;
/* 3, possibly CF_METAFILEPICT */
DWORD
clipformat
;
DWORD
unknown3
;
/* 4, possibly TYMED_ISTREAM */
DVASPECT
dvAspect
;
DWORD
unknown5
;
/* -1 */
DWORD
unknown6
;
DWORD
lindex
;
DWORD
tymed
;
DWORD
unknown7
;
/* 0 */
DWORD
dwObjectExtentX
;
DWORD
dwObjectExtentY
;
...
...
@@ -102,6 +101,8 @@ typedef struct DataCacheEntry
DWORD
id
;
/* dirty flag */
BOOL
dirty
;
/* stream number (-1 if not set ) */
unsigned
short
stream_number
;
}
DataCacheEntry
;
/****************************************************************************
...
...
@@ -186,6 +187,12 @@ static inline DataCache *impl_from_IOleCacheControl( IOleCacheControl *iface )
return
(
DataCache
*
)((
char
*
)
iface
-
FIELD_OFFSET
(
DataCache
,
lpvtblIOleCacheControl
));
}
static
void
dump_FORMATETC
(
const
FORMATETC
*
formatetc
)
{
TRACE
(
"{ cfFormat = 0x%x, ptd = %p, dwAspect = %d, lindex = %d, tymed = %d }"
,
formatetc
->
cfFormat
,
formatetc
->
ptd
,
formatetc
->
dwAspect
,
formatetc
->
lindex
,
formatetc
->
tymed
);
}
/*
* Prototypes for the methods of the DataCache class.
...
...
@@ -259,6 +266,7 @@ static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc
(
*
cache_entry
)
->
storage
=
NULL
;
(
*
cache_entry
)
->
id
=
This
->
last_cache_id
++
;
(
*
cache_entry
)
->
dirty
=
TRUE
;
(
*
cache_entry
)
->
stream_number
=
-
1
;
list_add_tail
(
&
This
->
cache_list
,
&
(
*
cache_entry
)
->
entry
);
return
S_OK
;
}
...
...
@@ -517,6 +525,117 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *This)
return
hres
;
}
static
HRESULT
DataCacheEntry_CreateStream
(
DataCacheEntry
*
This
,
IStorage
*
storage
,
IStream
**
stream
)
{
HRESULT
hr
;
WCHAR
wszName
[]
=
{
2
,
'O'
,
'l'
,
'e'
,
'P'
,
'r'
,
'e'
,
's'
,
'0'
+
(
This
->
stream_number
/
100
)
%
10
,
'0'
+
(
This
->
stream_number
/
10
)
%
10
,
'0'
+
This
->
stream_number
%
10
,
0
};
/* FIXME: cache the created stream in This? */
hr
=
IStorage_CreateStream
(
storage
,
wszName
,
STGM_READWRITE
|
STGM_SHARE_EXCLUSIVE
|
STGM_CREATE
,
0
,
0
,
stream
);
return
hr
;
}
static
HRESULT
DataCacheEntry_Save
(
DataCacheEntry
*
This
,
IStorage
*
storage
,
BOOL
same_as_load
)
{
PresentationDataHeader
header
;
HRESULT
hr
;
IStream
*
pres_stream
;
void
*
data
=
NULL
;
TRACE
(
"stream_number = %d, fmtetc = "
,
This
->
stream_number
);
dump_FORMATETC
(
&
This
->
fmtetc
);
TRACE
(
"
\n
"
);
hr
=
DataCacheEntry_CreateStream
(
This
,
storage
,
&
pres_stream
);
if
(
FAILED
(
hr
))
return
hr
;
/* custom clipformat */
if
(
This
->
fmtetc
.
cfFormat
>
0xc000
)
FIXME
(
"custom clipboard format not serialized properly
\n
"
);
header
.
unknown1
=
-
1
;
header
.
clipformat
=
This
->
fmtetc
.
cfFormat
;
if
(
This
->
fmtetc
.
ptd
)
FIXME
(
"ptd not serialized
\n
"
);
header
.
unknown3
=
4
;
header
.
dvAspect
=
This
->
fmtetc
.
dwAspect
;
header
.
lindex
=
This
->
fmtetc
.
lindex
;
header
.
tymed
=
This
->
fmtetc
.
tymed
;
header
.
unknown7
=
0
;
header
.
dwObjectExtentX
=
0
;
header
.
dwObjectExtentY
=
0
;
header
.
dwSize
=
0
;
/* size the data */
switch
(
This
->
fmtetc
.
cfFormat
)
{
case
CF_METAFILEPICT
:
{
if
(
This
->
stgmedium
.
tymed
!=
TYMED_NULL
)
{
const
METAFILEPICT
*
mfpict
=
GlobalLock
(
This
->
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
(
This
->
stgmedium
.
u
.
hMetaFilePict
);
}
break
;
}
default:
break
;
}
/*
* 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
(
This
->
fmtetc
.
cfFormat
)
{
case
CF_METAFILEPICT
:
{
if
(
This
->
stgmedium
.
tymed
!=
TYMED_NULL
)
{
const
METAFILEPICT
*
mfpict
=
GlobalLock
(
This
->
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
(
This
->
stgmedium
.
u
.
hMetaFilePict
);
}
break
;
}
default:
break
;
}
if
(
data
)
hr
=
IStream_Write
(
pres_stream
,
data
,
header
.
dwSize
,
NULL
);
IStream_Release
(
pres_stream
);
return
hr
;
}
/* helper for copying STGMEDIUM of type bitmap, MF, EMF or HGLOBAL.
* does no checking of whether src_stgm has a supported tymed, so this should be
* done in the caller */
...
...
@@ -1153,11 +1272,13 @@ static HRESULT WINAPI DataCache_Load(
DataCacheEntry
*
cache_entry
;
FORMATETC
fmtetc
;
fmtetc
.
cfFormat
=
header
.
unknown2
;
fmtetc
.
cfFormat
=
header
.
clipformat
;
fmtetc
.
ptd
=
NULL
;
/* FIXME */
fmtetc
.
dwAspect
=
header
.
dvAspect
;
fmtetc
.
lindex
=
header
.
unknown5
;
fmtetc
.
tymed
=
header
.
unknown6
;
fmtetc
.
lindex
=
header
.
lindex
;
fmtetc
.
tymed
=
header
.
tymed
;
TRACE
(
"loading entry with formatetc: "
);
dump_FORMATETC
(
&
fmtetc
);
TRACE
(
"
\n
"
);
cache_entry
=
DataCache_GetEntryForFormatEtc
(
This
,
&
fmtetc
);
if
(
!
cache_entry
)
...
...
@@ -1205,6 +1326,8 @@ static HRESULT WINAPI DataCache_Save(
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
);
...
...
@@ -1225,14 +1348,32 @@ static HRESULT WINAPI DataCache_Save(
return
IStorage_CopyTo
(
This
->
presentationStorage
,
0
,
NULL
,
NULL
,
pStg
);
}
/* 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
)
{
cache_entry
->
dirty
=
TRUE
;
/* needs to be written out again */
cache_entry
->
stream_number
=
stream_number
;
}
stream_number
++
;
}
/* write out the cache entries */
LIST_FOR_EACH_ENTRY
(
cache_entry
,
&
This
->
cache_list
,
DataCacheEntry
,
entry
)
{
/* FIXME: actually do the save here */
cache_entry
->
dirty
=
FALSE
;
if
(
!
fSameAsLoad
||
cache_entry
->
dirty
)
{
hr
=
DataCacheEntry_Save
(
cache_entry
,
pStg
,
fSameAsLoad
);
if
(
FAILED
(
hr
))
break
;
cache_entry
->
dirty
=
FALSE
;
}
}
This
->
dirty
=
FALSE
;
return
S_OK
;
return
hr
;
}
/************************************************************************
...
...
@@ -1737,6 +1878,7 @@ static HRESULT WINAPI DataCache_Cache(
HRESULT
hr
;
TRACE
(
"(%p, 0x%x, %p)
\n
"
,
pformatetc
,
advf
,
pdwConnection
);
TRACE
(
"pformatetc = "
);
dump_FORMATETC
(
pformatetc
);
TRACE
(
"
\n
"
);
*
pdwConnection
=
0
;
...
...
dlls/ole32/tests/ole2.c
View file @
587ba291
...
...
@@ -1205,9 +1205,7 @@ static void test_data_cache(void)
fmtetc
.
ptd
=
NULL
;
fmtetc
.
tymed
=
TYMED_MFPICT
;
hr
=
IOleCache_Cache
(
pOleCache
,
&
fmtetc
,
0
,
&
dwConnection
);
todo_wine
{
ok
(
hr
==
CACHE_S_SAMECACHE
,
"IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x
\n
"
,
hr
);
}
rcBounds
.
left
=
0
;
rcBounds
.
top
=
0
;
...
...
@@ -1216,9 +1214,7 @@ static void test_data_cache(void)
hdcMem
=
CreateCompatibleDC
(
NULL
);
hr
=
IViewObject_Draw
(
pViewObject
,
DVASPECT_ICON
,
-
1
,
NULL
,
NULL
,
NULL
,
hdcMem
,
&
rcBounds
,
NULL
,
draw_continue
,
0xdeadbeef
);
todo_wine
{
ok_ole_success
(
hr
,
"IViewObject_Draw"
);
}
hr
=
IViewObject_Draw
(
pViewObject
,
DVASPECT_CONTENT
,
-
1
,
NULL
,
NULL
,
NULL
,
hdcMem
,
&
rcBounds
,
NULL
,
draw_continue
,
0xdeadbeef
);
ok
(
hr
==
OLE_E_BLANK
,
"IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x
\n
"
,
hr
);
...
...
@@ -1227,21 +1223,21 @@ static void test_data_cache(void)
hr
=
IOleCache2_DiscardCache
(
pOleCache
,
DISCARDCACHE_NOSAVE
);
todo_wine
{
ok_ole_success
(
hr
,
"IOleCache2_DiscardCache"
);
}
hr
=
IViewObject_Draw
(
pViewObject
,
DVASPECT_ICON
,
-
1
,
NULL
,
NULL
,
NULL
,
hdcMem
,
&
rcBounds
,
NULL
,
draw_continue
,
0xdeadbeef
);
ok_ole_success
(
hr
,
"IViewObject_Draw"
);
}
/* unload the cached storage object, but don't allow it to be reloaded */
hr
=
IPersistStorage_HandsOffStorage
(
pPS
);
ok_ole_success
(
hr
,
"IPersistStorage_HandsOffStorage"
);
todo_wine
{
hr
=
IViewObject_Draw
(
pViewObject
,
DVASPECT_ICON
,
-
1
,
NULL
,
NULL
,
NULL
,
hdcMem
,
&
rcBounds
,
NULL
,
draw_continue
,
0xdeadbeef
);
ok_ole_success
(
hr
,
"IViewObject_Draw"
);
todo_wine
{
hr
=
IOleCache2_DiscardCache
(
pOleCache
,
DISCARDCACHE_NOSAVE
);
ok_ole_success
(
hr
,
"IOleCache2_DiscardCache"
);
}
hr
=
IViewObject_Draw
(
pViewObject
,
DVASPECT_ICON
,
-
1
,
NULL
,
NULL
,
NULL
,
hdcMem
,
&
rcBounds
,
NULL
,
draw_continue
,
0xdeadbeef
);
ok
(
hr
==
OLE_E_BLANK
,
"IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x
\n
"
,
hr
);
}
DeleteDC
(
hdcMem
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment