Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
b75caee2
Commit
b75caee2
authored
Mar 25, 2009
by
Huw Davies
Committed by
Alexandre Julliard
Mar 25, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32/tests: Tests for the 'Ole Private Data' clipboard format.
parent
3383db61
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
209 additions
and
24 deletions
+209
-24
clipboard.c
dlls/ole32/tests/clipboard.c
+209
-24
No files found.
dlls/ole32/tests/clipboard.c
View file @
b75caee2
...
...
@@ -45,6 +45,8 @@ typedef struct DataObjectImpl {
UINT
fmtetc_cnt
;
HANDLE
text
;
IStream
*
stm
;
IStorage
*
stg
;
}
DataObjectImpl
;
typedef
struct
EnumFormatImpl
{
...
...
@@ -60,6 +62,8 @@ typedef struct EnumFormatImpl {
static
BOOL
expect_DataObjectImpl_QueryGetData
=
TRUE
;
static
ULONG
DataObjectImpl_GetData_calls
=
0
;
static
UINT
cf_stream
,
cf_storage
,
cf_another
,
cf_onemore
;
static
HRESULT
EnumFormatImpl_Create
(
FORMATETC
*
fmtetc
,
UINT
size
,
LPENUMFORMATETC
*
lplpformatetc
);
static
HRESULT
WINAPI
EnumFormatImpl_QueryInterface
(
IEnumFORMATETC
*
iface
,
REFIID
riid
,
LPVOID
*
ppvObj
)
...
...
@@ -99,15 +103,21 @@ static HRESULT WINAPI EnumFormatImpl_Next(IEnumFORMATETC *iface, ULONG celt,
FORMATETC
*
rgelt
,
ULONG
*
pceltFetched
)
{
EnumFormatImpl
*
This
=
(
EnumFormatImpl
*
)
iface
;
ULONG
count
=
0
;
ULONG
count
,
i
;
if
(
!
rgelt
)
return
E_INVALIDARG
;
count
=
min
(
celt
,
This
->
fmtetc_cnt
-
This
->
cur
);
if
(
count
>
0
)
{
memcpy
(
rgelt
,
This
->
fmtetc
+
This
->
cur
,
count
*
sizeof
(
FORMATETC
));
This
->
cur
+=
count
;
count
=
min
(
celt
,
This
->
fmtetc_cnt
-
This
->
cur
);
for
(
i
=
0
;
i
<
count
;
i
++
,
This
->
cur
++
,
rgelt
++
)
{
*
rgelt
=
This
->
fmtetc
[
This
->
cur
];
if
(
rgelt
->
ptd
)
{
DWORD
size
=
This
->
fmtetc
[
This
->
cur
].
ptd
->
tdSize
;
rgelt
->
ptd
=
CoTaskMemAlloc
(
size
);
memcpy
(
rgelt
->
ptd
,
This
->
fmtetc
[
This
->
cur
].
ptd
,
size
);
}
}
if
(
pceltFetched
)
*
pceltFetched
=
count
;
...
...
@@ -184,9 +194,15 @@ static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
DataObjectImpl
*
This
=
(
DataObjectImpl
*
)
iface
;
ULONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
if
(
!
ref
)
{
if
(
!
ref
)
{
int
i
;
if
(
This
->
text
)
GlobalFree
(
This
->
text
);
if
(
This
->
fmtetc
)
GlobalFree
(
This
->
fmtetc
);
for
(
i
=
0
;
i
<
This
->
fmtetc_cnt
;
i
++
)
HeapFree
(
GetProcessHeap
(),
0
,
This
->
fmtetc
[
i
].
ptd
);
HeapFree
(
GetProcessHeap
(),
0
,
This
->
fmtetc
);
if
(
This
->
stm
)
IStream_Release
(
This
->
stm
);
if
(
This
->
stg
)
IStorage_Release
(
This
->
stg
);
HeapFree
(
GetProcessHeap
(),
0
,
This
);
}
...
...
@@ -196,24 +212,36 @@ static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
static
HRESULT
WINAPI
DataObjectImpl_GetData
(
IDataObject
*
iface
,
FORMATETC
*
pformatetc
,
STGMEDIUM
*
pmedium
)
{
DataObjectImpl
*
This
=
(
DataObjectImpl
*
)
iface
;
UINT
i
;
BOOL
foundFormat
=
FALSE
;
DataObjectImpl_GetData_calls
++
;
if
(
pformatetc
->
lindex
!=
-
1
)
return
DV_E_FORMATETC
;
if
(
!
(
pformatetc
->
tymed
&
TYMED_HGLOBAL
))
return
DV_E_TYMED
;
if
(
This
->
text
&&
pformatetc
->
cfFormat
==
CF_TEXT
)
U
(
*
pmedium
).
hGlobal
=
This
->
text
;
else
return
DV_E_FORMATETC
;
for
(
i
=
0
;
i
<
This
->
fmtetc_cnt
;
i
++
)
{
if
(
This
->
fmtetc
[
i
].
cfFormat
==
pformatetc
->
cfFormat
)
{
foundFormat
=
TRUE
;
if
(
This
->
fmtetc
[
i
].
tymed
&
pformatetc
->
tymed
)
{
pmedium
->
pUnkForRelease
=
(
LPUNKNOWN
)
iface
;
IUnknown_AddRef
(
pmedium
->
pUnkForRelease
);
if
(
pformatetc
->
cfFormat
==
CF_TEXT
)
U
(
*
pmedium
).
hGlobal
=
This
->
text
;
else
if
(
pformatetc
->
cfFormat
==
cf_stream
)
U
(
*
pmedium
).
pstm
=
This
->
stm
;
else
if
(
pformatetc
->
cfFormat
==
cf_storage
)
U
(
*
pmedium
).
pstg
=
This
->
stg
;
return
S_OK
;
}
}
}
pmedium
->
tymed
=
TYMED_HGLOBAL
;
pmedium
->
pUnkForRelease
=
(
LPUNKNOWN
)
iface
;
IUnknown_AddRef
(
pmedium
->
pUnkForRelease
);
return
S_OK
;
return
foundFormat
?
DV_E_TYMED
:
DV_E_FORMATETC
;
}
static
HRESULT
WINAPI
DataObjectImpl_GetDataHere
(
IDataObject
*
iface
,
FORMATETC
*
pformatetc
,
STGMEDIUM
*
pmedium
)
...
...
@@ -315,6 +343,8 @@ static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
obj
->
text
=
GlobalAlloc
(
GMEM_MOVEABLE
,
strlen
(
text
)
+
1
);
strcpy
(
GlobalLock
(
obj
->
text
),
text
);
GlobalUnlock
(
obj
->
text
);
obj
->
stm
=
NULL
;
obj
->
stg
=
NULL
;
obj
->
fmtetc_cnt
=
1
;
obj
->
fmtetc
=
HeapAlloc
(
GetProcessHeap
(),
0
,
obj
->
fmtetc_cnt
*
sizeof
(
FORMATETC
));
...
...
@@ -324,6 +354,55 @@ static HRESULT DataObjectImpl_CreateText(LPCSTR text, LPDATAOBJECT *lplpdataobj)
return
S_OK
;
}
static
HRESULT
DataObjectImpl_CreateComplex
(
LPDATAOBJECT
*
lplpdataobj
)
{
DataObjectImpl
*
obj
;
const
char
*
stm_data
=
"complex stream"
;
const
char
*
text_data
=
"complex text"
;
ILockBytes
*
lbs
;
static
const
WCHAR
devname
[]
=
{
'm'
,
'y'
,
'd'
,
'e'
,
'v'
,
0
};
DEVMODEW
dm
;
obj
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DataObjectImpl
));
obj
->
lpVtbl
=
&
VT_DataObjectImpl
;
obj
->
ref
=
1
;
obj
->
text
=
GlobalAlloc
(
GMEM_MOVEABLE
,
strlen
(
text_data
)
+
1
);
strcpy
(
GlobalLock
(
obj
->
text
),
text_data
);
GlobalUnlock
(
obj
->
text
);
CreateStreamOnHGlobal
(
NULL
,
TRUE
,
&
obj
->
stm
);
IStream_Write
(
obj
->
stm
,
stm_data
,
strlen
(
stm_data
),
NULL
);
CreateILockBytesOnHGlobal
(
NULL
,
TRUE
,
&
lbs
);
StgCreateDocfileOnILockBytes
(
lbs
,
STGM_CREATE
|
STGM_SHARE_EXCLUSIVE
|
STGM_READWRITE
,
0
,
&
obj
->
stg
);
ILockBytes_Release
(
lbs
);
obj
->
fmtetc_cnt
=
5
;
/* zeroing here since FORMATETC has a hole in it, and it's confusing to have this uninitialised. */
obj
->
fmtetc
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
obj
->
fmtetc_cnt
*
sizeof
(
FORMATETC
));
InitFormatEtc
(
obj
->
fmtetc
[
0
],
CF_TEXT
,
TYMED_HGLOBAL
);
InitFormatEtc
(
obj
->
fmtetc
[
1
],
cf_stream
,
TYMED_ISTREAM
);
InitFormatEtc
(
obj
->
fmtetc
[
2
],
cf_storage
,
TYMED_ISTORAGE
);
InitFormatEtc
(
obj
->
fmtetc
[
3
],
cf_another
,
TYMED_ISTORAGE
|
TYMED_ISTREAM
|
TYMED_HGLOBAL
);
memset
(
&
dm
,
0
,
sizeof
(
dm
));
dm
.
dmSize
=
sizeof
(
dm
);
dm
.
dmDriverExtra
=
0
;
lstrcpyW
(
dm
.
dmDeviceName
,
devname
);
obj
->
fmtetc
[
3
].
ptd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
DVTARGETDEVICE
)
+
sizeof
(
devname
)
+
dm
.
dmSize
+
dm
.
dmDriverExtra
);
obj
->
fmtetc
[
3
].
ptd
->
tdSize
=
sizeof
(
DVTARGETDEVICE
)
+
sizeof
(
devname
)
+
dm
.
dmSize
+
dm
.
dmDriverExtra
;
obj
->
fmtetc
[
3
].
ptd
->
tdDriverNameOffset
=
sizeof
(
DVTARGETDEVICE
);
obj
->
fmtetc
[
3
].
ptd
->
tdDeviceNameOffset
=
0
;
obj
->
fmtetc
[
3
].
ptd
->
tdPortNameOffset
=
0
;
obj
->
fmtetc
[
3
].
ptd
->
tdExtDevmodeOffset
=
sizeof
(
DVTARGETDEVICE
)
+
sizeof
(
devname
);
lstrcpyW
((
WCHAR
*
)
obj
->
fmtetc
[
3
].
ptd
->
tdData
,
devname
);
memcpy
(
obj
->
fmtetc
[
3
].
ptd
->
tdData
+
sizeof
(
devname
),
&
dm
,
dm
.
dmSize
+
dm
.
dmDriverExtra
);
InitFormatEtc
(
obj
->
fmtetc
[
4
],
cf_stream
,
0xfffff
);
obj
->
fmtetc
[
4
].
dwAspect
=
DVASPECT_ICON
;
*
lplpdataobj
=
(
LPDATAOBJECT
)
obj
;
return
S_OK
;
}
static
void
test_get_clipboard
(
void
)
{
HRESULT
hr
;
...
...
@@ -423,11 +502,12 @@ static void test_get_clipboard(void)
IDataObject_Release
(
data_obj
);
}
static
void
test_cf_dataobject
(
BOOL
dataobject_active
)
static
void
test_cf_dataobject
(
IDataObject
*
data
)
{
UINT
cf
=
0
;
UINT
cf_dataobject
=
RegisterClipboardFormatA
(
"DataObject"
);
BOOL
found_dataobject
=
FALSE
;
UINT
cf_ole_priv_data
=
RegisterClipboardFormatA
(
"Ole Private Data"
);
BOOL
found_dataobject
=
FALSE
,
found_priv_data
=
FALSE
;
OpenClipboard
(
NULL
);
do
...
...
@@ -442,22 +522,115 @@ static void test_cf_dataobject(BOOL dataobject_active)
found_dataobject
=
TRUE
;
ok
(
size
>=
sizeof
(
*
ptr
),
"size %d
\n
"
,
size
);
if
(
data
object_active
)
if
(
data
)
ok
(
*
ptr
==
clip_owner
,
"hwnd %p clip_owner %p
\n
"
,
*
ptr
,
clip_owner
);
else
/* ole clipboard flushed */
ok
(
*
ptr
==
NULL
,
"hwnd %p
\n
"
,
*
ptr
);
GlobalUnlock
(
h
);
}
else
if
(
cf
==
cf_ole_priv_data
)
{
found_priv_data
=
TRUE
;
if
(
data
)
{
HGLOBAL
h
=
GetClipboardData
(
cf
);
DWORD
*
ptr
=
GlobalLock
(
h
);
DWORD
size
=
GlobalSize
(
h
);
if
(
size
!=
ptr
[
1
])
win_skip
(
"Ole Private Data in win9x format
\n
"
);
else
{
HRESULT
hr
;
IEnumFORMATETC
*
enum_fmt
;
DWORD
count
=
0
;
FORMATETC
fmt
;
struct
formatetcetc
{
FORMATETC
fmt
;
BOOL
first_use_of_cf
;
DWORD
res
[
2
];
}
*
fmt_ptr
;
struct
priv_data
{
DWORD
res1
;
DWORD
size
;
DWORD
res2
;
DWORD
count
;
DWORD
res3
[
2
];
struct
formatetcetc
fmts
[
1
];
}
*
priv
=
(
struct
priv_data
*
)
ptr
;
CLIPFORMAT
cfs_seen
[
10
];
hr
=
IDataObject_EnumFormatEtc
(
data
,
DATADIR_GET
,
&
enum_fmt
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
fmt_ptr
=
priv
->
fmts
;
while
(
IEnumFORMATETC_Next
(
enum_fmt
,
1
,
&
fmt
,
NULL
)
==
S_OK
)
{
int
i
;
BOOL
seen_cf
=
FALSE
;
ok
(
fmt_ptr
->
fmt
.
cfFormat
==
fmt
.
cfFormat
,
"got %08x expected %08x
\n
"
,
fmt_ptr
->
fmt
.
cfFormat
,
fmt
.
cfFormat
);
ok
(
fmt_ptr
->
fmt
.
dwAspect
==
fmt
.
dwAspect
,
"got %08x expected %08x
\n
"
,
fmt_ptr
->
fmt
.
dwAspect
,
fmt
.
dwAspect
);
ok
(
fmt_ptr
->
fmt
.
lindex
==
fmt
.
lindex
,
"got %08x expected %08x
\n
"
,
fmt_ptr
->
fmt
.
lindex
,
fmt
.
lindex
);
ok
(
fmt_ptr
->
fmt
.
tymed
==
fmt
.
tymed
,
"got %08x expected %08x
\n
"
,
fmt_ptr
->
fmt
.
tymed
,
fmt
.
tymed
);
for
(
i
=
0
;
i
<
count
;
i
++
)
if
(
fmt_ptr
->
fmt
.
cfFormat
==
cfs_seen
[
i
])
{
seen_cf
=
TRUE
;
break
;
}
cfs_seen
[
count
]
=
fmt
.
cfFormat
;
ok
(
fmt_ptr
->
first_use_of_cf
==
seen_cf
?
FALSE
:
TRUE
,
"got %08x expected %08x
\n
"
,
fmt_ptr
->
first_use_of_cf
,
!
seen_cf
);
ok
(
fmt_ptr
->
res
[
0
]
==
0
,
"got %08x
\n
"
,
fmt_ptr
->
res
[
1
]);
ok
(
fmt_ptr
->
res
[
1
]
==
0
,
"got %08x
\n
"
,
fmt_ptr
->
res
[
2
]);
if
(
fmt
.
ptd
)
{
DVTARGETDEVICE
*
target
;
ok
(
fmt_ptr
->
fmt
.
ptd
!=
NULL
,
"target device offset zero
\n
"
);
target
=
(
DVTARGETDEVICE
*
)((
char
*
)
priv
+
(
DWORD
)
fmt_ptr
->
fmt
.
ptd
);
ok
(
!
memcmp
(
target
,
fmt
.
ptd
,
fmt
.
ptd
->
tdSize
),
"target devices differ
\n
"
);
CoTaskMemFree
(
fmt
.
ptd
);
}
fmt_ptr
++
;
count
++
;
}
ok
(
priv
->
res1
==
0
,
"got %08x
\n
"
,
priv
->
res1
);
ok
(
priv
->
res2
==
1
,
"got %08x
\n
"
,
priv
->
res2
);
ok
(
priv
->
count
==
count
,
"got %08x expected %08x
\n
"
,
priv
->
count
,
count
);
ok
(
priv
->
res3
[
0
]
==
0
,
"got %08x
\n
"
,
priv
->
res3
[
0
]);
ok
(
priv
->
res3
[
1
]
==
0
,
"got %08x
\n
"
,
priv
->
res3
[
1
]);
GlobalUnlock
(
h
);
IEnumFORMATETC_Release
(
enum_fmt
);
}
}
}
}
while
(
cf
);
CloseClipboard
();
ok
(
found_dataobject
,
"didn't find cf_dataobject
\n
"
);
todo_wine
ok
(
found_priv_data
,
"didn't find cf_ole_priv_data
\n
"
);
}
static
void
test_set_clipboard
(
void
)
{
HRESULT
hr
;
ULONG
ref
;
LPDATAOBJECT
data1
,
data2
;
LPDATAOBJECT
data1
,
data2
,
data_cmpl
;
cf_stream
=
RegisterClipboardFormatA
(
"stream format"
);
cf_storage
=
RegisterClipboardFormatA
(
"storage format"
);
cf_another
=
RegisterClipboardFormatA
(
"another format"
);
cf_onemore
=
RegisterClipboardFormatA
(
"one more format"
);
hr
=
DataObjectImpl_CreateText
(
"data1"
,
&
data1
);
ok
(
SUCCEEDED
(
hr
),
"Failed to create data1 object: 0x%08x
\n
"
,
hr
);
if
(
FAILED
(
hr
))
...
...
@@ -466,6 +639,10 @@ static void test_set_clipboard(void)
ok
(
SUCCEEDED
(
hr
),
"Failed to create data2 object: 0x%08x
\n
"
,
hr
);
if
(
FAILED
(
hr
))
return
;
hr
=
DataObjectImpl_CreateComplex
(
&
data_cmpl
);
ok
(
SUCCEEDED
(
hr
),
"Failed to create complex data object: 0x%08x
\n
"
,
hr
);
if
(
FAILED
(
hr
))
return
;
hr
=
OleSetClipboard
(
data1
);
ok
(
hr
==
CO_E_NOTINITIALIZED
,
"OleSetClipboard should have failed with CO_E_NOTINITIALIZED instead of 0x%08x
\n
"
,
hr
);
...
...
@@ -484,7 +661,7 @@ static void test_set_clipboard(void)
hr
=
OleSetClipboard
(
data1
);
ok
(
hr
==
S_OK
,
"failed to set clipboard to data1, hr = 0x%08x
\n
"
,
hr
);
test_cf_dataobject
(
TRUE
);
test_cf_dataobject
(
data1
);
hr
=
OleIsCurrentClipboard
(
data1
);
ok
(
hr
==
S_OK
,
"expected current clipboard to be data1, hr = 0x%08x
\n
"
,
hr
);
...
...
@@ -513,7 +690,13 @@ static void test_set_clipboard(void)
hr
=
OleIsCurrentClipboard
(
NULL
);
ok
(
hr
==
S_FALSE
,
"expect S_FALSE, hr = 0x%08x
\n
"
,
hr
);
test_cf_dataobject
(
FALSE
);
test_cf_dataobject
(
NULL
);
ok
(
OleSetClipboard
(
NULL
)
==
S_OK
,
"failed to clear clipboard, hr = 0x%08x
\n
"
,
hr
);
hr
=
OleSetClipboard
(
data_cmpl
);
ok
(
hr
==
S_OK
,
"failed to set clipboard to complex data, hr = 0x%08x
\n
"
,
hr
);
test_cf_dataobject
(
data_cmpl
);
ok
(
OleSetClipboard
(
NULL
)
==
S_OK
,
"failed to clear clipboard, hr = 0x%08x
\n
"
,
hr
);
...
...
@@ -521,6 +704,8 @@ static void test_set_clipboard(void)
ok
(
ref
==
0
,
"expected data1 ref=0, got %d
\n
"
,
ref
);
ref
=
IDataObject_Release
(
data2
);
ok
(
ref
==
0
,
"expected data2 ref=0, got %d
\n
"
,
ref
);
ref
=
IDataObject_Release
(
data_cmpl
);
ok
(
ref
==
0
,
"expected data_cmpl ref=0, got %d
\n
"
,
ref
);
OleUninitialize
();
}
...
...
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