Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Alexey Alyaev
wine
Commits
b75caee2
Commit
b75caee2
authored
16 years ago
by
Huw Davies
Committed by
Alexandre Julliard
16 years ago
Browse files
Options
Downloads
Patches
Plain Diff
ole32/tests: Tests for the 'Ole Private Data' clipboard format.
parent
3383db61
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
dlls/ole32/tests/clipboard.c
+209
-24
209 additions, 24 deletions
dlls/ole32/tests/clipboard.c
with
209 additions
and
24 deletions
dlls/ole32/tests/clipboard.c
+
209
−
24
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
d
ata
o
bject
_active
)
static
void
test_cf_dataobject
(
ID
ata
O
bject
*
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,28 +522,125 @@ 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
))
return
;
hr
=
DataObjectImpl_CreateText
(
"data2"
,
&
data2
);
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
;
...
...
@@ -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
();
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment