2 * OLE DB Marshaling Tests
4 * Copyright 2009 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include "wine/test.h"
35 #define RELEASEMARSHALDATA WM_USER
37 #define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
39 struct host_object_data
44 MSHLFLAGS marshal_flags
;
46 IMessageFilter
*filter
;
49 static DWORD CALLBACK
host_object_proc(LPVOID p
)
51 struct host_object_data
*data
= p
;
55 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
59 IMessageFilter
* prev_filter
= NULL
;
60 hr
= CoRegisterMessageFilter(data
->filter
, &prev_filter
);
61 if (prev_filter
) IMessageFilter_Release(prev_filter
);
62 ok_ole_success(hr
, CoRegisterMessageFilter
);
65 hr
= CoMarshalInterface(data
->stream
, &data
->iid
, data
->object
, MSHCTX_INPROC
, NULL
, data
->marshal_flags
);
66 ok_ole_success(hr
, CoMarshalInterface
);
68 /* force the message queue to be created before signaling parent thread */
69 PeekMessageW(&msg
, NULL
, WM_USER
, WM_USER
, PM_NOREMOVE
);
71 SetEvent(data
->marshal_event
);
73 while (GetMessageW(&msg
, NULL
, 0, 0))
75 if (msg
.hwnd
== NULL
&& msg
.message
== RELEASEMARSHALDATA
)
77 CoReleaseMarshalData(data
->stream
);
78 SetEvent((HANDLE
)msg
.lParam
);
81 DispatchMessageW(&msg
);
84 HeapFree(GetProcessHeap(), 0, data
);
91 static DWORD
start_host_object2(IStream
*stream
, REFIID riid
, IUnknown
*object
, MSHLFLAGS marshal_flags
, IMessageFilter
*filter
, HANDLE
*thread
)
94 HANDLE marshal_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
95 struct host_object_data
*data
= HeapAlloc(GetProcessHeap(), 0, sizeof(*data
));
97 data
->stream
= stream
;
99 data
->object
= object
;
100 data
->marshal_flags
= marshal_flags
;
101 data
->marshal_event
= marshal_event
;
102 data
->filter
= filter
;
104 *thread
= CreateThread(NULL
, 0, host_object_proc
, data
, 0, &tid
);
106 /* wait for marshaling to complete before returning */
107 ok( !WaitForSingleObject(marshal_event
, 10000), "wait timed out\n" );
108 CloseHandle(marshal_event
);
113 static DWORD
start_host_object(IStream
*stream
, REFIID riid
, IUnknown
*object
, MSHLFLAGS marshal_flags
, HANDLE
*thread
)
115 return start_host_object2(stream
, riid
, object
, marshal_flags
, NULL
, thread
);
118 static void end_host_object(DWORD tid
, HANDLE thread
)
120 BOOL ret
= PostThreadMessageW(tid
, WM_QUIT
, 0, 0);
121 ok(ret
, "PostThreadMessageW failed with error %d\n", GetLastError());
122 /* be careful of races - don't return until hosting thread has terminated */
123 ok( !WaitForSingleObject(thread
, 10000), "wait timed out\n" );
127 #define TEST_PROPID 0xdead
128 static const WCHAR wszDBPropertyTestString
[] = {'D','B','P','r','o','p','e','r','t','y','T','e','s','t','S','t','r','i','n','g',0};
129 static const WCHAR wszDBPropertyColumnName
[] = {'C','o','l','u','m','n',0};
131 static HRESULT WINAPI
Test_DBProperties_QueryInterface(
132 IDBProperties
* iface
,
136 if (IsEqualIID(riid
, &IID_IUnknown
) ||
137 IsEqualIID(riid
, &IID_IDBProperties
))
143 return E_NOINTERFACE
;
146 static ULONG WINAPI
Test_DBProperties_AddRef(
147 IDBProperties
* iface
)
152 static ULONG WINAPI
Test_DBProperties_Release(
153 IDBProperties
* iface
)
158 /*** IDBProperties methods ***/
159 static HRESULT WINAPI
Test_DBProperties_GetProperties(
160 IDBProperties
* iface
,
161 ULONG cPropertyIDSets
,
162 const DBPROPIDSET rgPropertyIDSets
[],
163 ULONG
*pcPropertySets
,
164 DBPROPSET
**prgPropertySets
)
166 ok(cPropertyIDSets
== 0, "Expected cPropertyIDSets to be 0 instead of %d\n", cPropertyIDSets
);
167 ok(*pcPropertySets
== 0, "Expected *pcPropertySets to be 0 instead of %d\n", *pcPropertySets
);
169 *prgPropertySets
= CoTaskMemAlloc(sizeof(DBPROPSET
));
170 (*prgPropertySets
)[0].rgProperties
= CoTaskMemAlloc(sizeof(DBPROP
));
171 (*prgPropertySets
)[0].rgProperties
[0].dwPropertyID
= TEST_PROPID
;
172 (*prgPropertySets
)[0].rgProperties
[0].dwOptions
= DBPROPOPTIONS_REQUIRED
;
173 (*prgPropertySets
)[0].rgProperties
[0].dwStatus
= S_OK
;
174 (*prgPropertySets
)[0].rgProperties
[0].colid
.eKind
= DBKIND_GUID_NAME
;
176 (*prgPropertySets
)[0].rgProperties
[0].colid
.uGuid
.guid
= IID_IDBProperties
;
177 (*prgPropertySets
)[0].rgProperties
[0].colid
.uName
.pwszName
= CoTaskMemAlloc(sizeof(wszDBPropertyColumnName
));
178 memcpy((*prgPropertySets
)[0].rgProperties
[0].colid
.uName
.pwszName
, wszDBPropertyColumnName
, sizeof(wszDBPropertyColumnName
));
179 /* vValue contents */
180 V_VT(&(*prgPropertySets
)[0].rgProperties
[0].vValue
) = VT_BSTR
;
181 V_BSTR(&(*prgPropertySets
)[0].rgProperties
[0].vValue
) = SysAllocString(wszDBPropertyTestString
);
182 (*prgPropertySets
)[0].cProperties
= 1;
183 (*prgPropertySets
)[0].guidPropertySet
= IID_IDBProperties
;
188 static HRESULT WINAPI
Test_DBProperties_GetPropertyInfo(
189 IDBProperties
* iface
,
190 ULONG cPropertyIDSets
,
191 const DBPROPIDSET rgPropertyIDSets
[],
192 ULONG
*pcPropertyInfoSets
,
193 DBPROPINFOSET
**prgPropertyInfoSets
,
194 OLECHAR
**ppDescBuffer
)
199 static HRESULT WINAPI
Test_DBProperties_SetProperties(
200 IDBProperties
* iface
,
202 DBPROPSET rgPropertySets
[])
207 static const IDBPropertiesVtbl Test_DBProperties_Vtbl
=
209 Test_DBProperties_QueryInterface
,
210 Test_DBProperties_AddRef
,
211 Test_DBProperties_Release
,
212 Test_DBProperties_GetProperties
,
213 Test_DBProperties_GetPropertyInfo
,
214 Test_DBProperties_SetProperties
,
217 static IDBProperties Test_DBProperties
=
219 &Test_DBProperties_Vtbl
222 static void test_IDBProperties(void)
225 IStream
*pStream
= NULL
;
226 IDBProperties
*pProxy
= NULL
;
229 static const LARGE_INTEGER ullZero
;
231 DBPROPSET
*propsets
= NULL
;
233 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
234 ok_ole_success(hr
, "CreateStreamOnHGlobal");
235 tid
= start_host_object(pStream
, &IID_IDBProperties
, (IUnknown
*)&Test_DBProperties
, MSHLFLAGS_NORMAL
, &thread
);
237 IStream_Seek(pStream
, ullZero
, STREAM_SEEK_SET
, NULL
);
238 hr
= CoUnmarshalInterface(pStream
, &IID_IDBProperties
, (void **)&pProxy
);
239 ok_ole_success(hr
, "CoUnmarshalInterface");
240 IStream_Release(pStream
);
243 hr
= IDBProperties_GetProperties(pProxy
, 0, NULL
, &propset_count
, &propsets
);
244 ok(hr
== S_OK
, "IDBProperties_GetProperties failed with error 0x%08x\n", hr
);
246 ok(propset_count
== 1, "Expected propset_count of 1 but got %d\n", propset_count
);
247 ok(propsets
->rgProperties
[0].dwPropertyID
== TEST_PROPID
, "Expected property ID of 0x%x, but got 0x%x\n", TEST_PROPID
, propsets
->rgProperties
[0].dwPropertyID
);
248 ok(propsets
->rgProperties
[0].dwOptions
== DBPROPOPTIONS_REQUIRED
, "Expected property options of 0x%x, but got 0x%x\n", DBPROPOPTIONS_REQUIRED
, propsets
->rgProperties
[0].dwOptions
);
249 ok(propsets
->rgProperties
[0].dwStatus
== S_OK
, "Expected property options of 0x%x, but got 0x%x\n", S_OK
, propsets
->rgProperties
[0].dwStatus
);
250 ok(propsets
->rgProperties
[0].colid
.eKind
== DBKIND_GUID_NAME
, "Expected property colid kind of DBKIND_GUID_NAME, but got %d\n", propsets
->rgProperties
[0].colid
.eKind
);
252 ok(IsEqualGUID(&propsets
->rgProperties
[0].colid
.uGuid
.guid
, &IID_IDBProperties
), "Unexpected property colid guid\n");
253 ok(!lstrcmpW(propsets
->rgProperties
[0].colid
.uName
.pwszName
, wszDBPropertyColumnName
), "Unexpected property colid name\n");
254 /* vValue contents */
255 ok(V_VT(&propsets
->rgProperties
[0].vValue
) == VT_BSTR
, "Expected property value vt of VT_BSTR, but got %d\n", V_VT(&propsets
->rgProperties
[0].vValue
));
256 ok(!lstrcmpW(V_BSTR(&propsets
->rgProperties
[0].vValue
), wszDBPropertyTestString
), "Unexpected property value string\n");
257 ok(propsets
->cProperties
== 1, "Expected property count of 1 but got %d\n", propsets
->cProperties
);
258 ok(IsEqualGUID(&propsets
->guidPropertySet
, &IID_IDBProperties
), "Unexpected guid for property set\n");
260 IDBProperties_Release(pProxy
);
262 end_host_object(tid
, thread
);
267 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
269 test_IDBProperties();