oledb32: Add test for marshalling IDBProperties.
This commit is contained in:
parent
da4f7a5dc1
commit
d5ef09409d
|
@ -3,10 +3,11 @@ TOPOBJDIR = ../../..
|
|||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
TESTDLL = oledb32.dll
|
||||
IMPORTS = oleaut32 ole32 gdi32 advapi32 kernel32
|
||||
IMPORTS = oleaut32 ole32 user32 gdi32 advapi32 kernel32
|
||||
|
||||
CTESTS = \
|
||||
convert.c
|
||||
convert.c \
|
||||
marshal.c
|
||||
|
||||
IDL_I_SRCS = convert.idl
|
||||
|
||||
|
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* OLE DB Marshaling Tests
|
||||
*
|
||||
* Copyright 2009 Robert Shearman
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define _WIN32_DCOM
|
||||
#define COBJMACROS
|
||||
#define CONST_VTABLE
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "initguid.h"
|
||||
#include "objbase.h"
|
||||
#include "oledb.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define RELEASEMARSHALDATA WM_USER
|
||||
|
||||
#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
|
||||
|
||||
struct host_object_data
|
||||
{
|
||||
IStream *stream;
|
||||
IID iid;
|
||||
IUnknown *object;
|
||||
MSHLFLAGS marshal_flags;
|
||||
HANDLE marshal_event;
|
||||
IMessageFilter *filter;
|
||||
};
|
||||
|
||||
static DWORD CALLBACK host_object_proc(LPVOID p)
|
||||
{
|
||||
struct host_object_data *data = p;
|
||||
HRESULT hr;
|
||||
MSG msg;
|
||||
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
if (data->filter)
|
||||
{
|
||||
IMessageFilter * prev_filter = NULL;
|
||||
hr = CoRegisterMessageFilter(data->filter, &prev_filter);
|
||||
if (prev_filter) IMessageFilter_Release(prev_filter);
|
||||
ok_ole_success(hr, CoRegisterMessageFilter);
|
||||
}
|
||||
|
||||
hr = CoMarshalInterface(data->stream, &data->iid, data->object, MSHCTX_INPROC, NULL, data->marshal_flags);
|
||||
ok_ole_success(hr, CoMarshalInterface);
|
||||
|
||||
/* force the message queue to be created before signaling parent thread */
|
||||
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
|
||||
|
||||
SetEvent(data->marshal_event);
|
||||
|
||||
while (GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if (msg.hwnd == NULL && msg.message == RELEASEMARSHALDATA)
|
||||
{
|
||||
CoReleaseMarshalData(data->stream);
|
||||
SetEvent((HANDLE)msg.lParam);
|
||||
}
|
||||
else
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static DWORD start_host_object2(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, IMessageFilter *filter, HANDLE *thread)
|
||||
{
|
||||
DWORD tid = 0;
|
||||
HANDLE marshal_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
struct host_object_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
|
||||
|
||||
data->stream = stream;
|
||||
data->iid = *riid;
|
||||
data->object = object;
|
||||
data->marshal_flags = marshal_flags;
|
||||
data->marshal_event = marshal_event;
|
||||
data->filter = filter;
|
||||
|
||||
*thread = CreateThread(NULL, 0, host_object_proc, data, 0, &tid);
|
||||
|
||||
/* wait for marshaling to complete before returning */
|
||||
ok( !WaitForSingleObject(marshal_event, 10000), "wait timed out\n" );
|
||||
CloseHandle(marshal_event);
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
static DWORD start_host_object(IStream *stream, REFIID riid, IUnknown *object, MSHLFLAGS marshal_flags, HANDLE *thread)
|
||||
{
|
||||
return start_host_object2(stream, riid, object, marshal_flags, NULL, thread);
|
||||
}
|
||||
|
||||
static void end_host_object(DWORD tid, HANDLE thread)
|
||||
{
|
||||
BOOL ret = PostThreadMessage(tid, WM_QUIT, 0, 0);
|
||||
ok(ret, "PostThreadMessage failed with error %d\n", GetLastError());
|
||||
/* be careful of races - don't return until hosting thread has terminated */
|
||||
ok( !WaitForSingleObject(thread, 10000), "wait timed out\n" );
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
#define TEST_PROPID 0xdead
|
||||
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};
|
||||
static const WCHAR wszDBPropertyColumnName[] = {'C','o','l','u','m','n',0};
|
||||
|
||||
static HRESULT WINAPI Test_DBProperties_QueryInterface(
|
||||
IDBProperties* iface,
|
||||
REFIID riid,
|
||||
void **ppvObject)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IDBProperties))
|
||||
{
|
||||
*ppvObject = iface;
|
||||
return S_OK;
|
||||
}
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_DBProperties_AddRef(
|
||||
IDBProperties* iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_DBProperties_Release(
|
||||
IDBProperties* iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*** IDBProperties methods ***/
|
||||
static HRESULT WINAPI Test_DBProperties_GetProperties(
|
||||
IDBProperties* iface,
|
||||
ULONG cPropertyIDSets,
|
||||
const DBPROPIDSET rgPropertyIDSets[],
|
||||
ULONG *pcPropertySets,
|
||||
DBPROPSET **prgPropertySets)
|
||||
{
|
||||
ok(cPropertyIDSets == 0, "Expected cPropertyIDSets to be 0 instead of %d\n", cPropertyIDSets);
|
||||
ok(*pcPropertySets == 1, "Expected *pcPropertySets to be 1 instead of %d\n", *pcPropertySets);
|
||||
prgPropertySets[0] = CoTaskMemAlloc(sizeof(DBPROPSET));
|
||||
prgPropertySets[0]->rgProperties = CoTaskMemAlloc(sizeof(DBPROP));
|
||||
prgPropertySets[0]->rgProperties[0].dwPropertyID = TEST_PROPID;
|
||||
prgPropertySets[0]->rgProperties[0].dwOptions = DBPROPOPTIONS_REQUIRED;
|
||||
prgPropertySets[0]->rgProperties[0].dwStatus = S_OK;
|
||||
prgPropertySets[0]->rgProperties[0].colid.eKind = DBKIND_GUID_NAME;
|
||||
/* colid contents */
|
||||
prgPropertySets[0]->rgProperties[0].colid.uGuid.guid = IID_IDBProperties;
|
||||
prgPropertySets[0]->rgProperties[0].colid.uName.pwszName = CoTaskMemAlloc(sizeof(wszDBPropertyColumnName));
|
||||
memcpy(prgPropertySets[0]->rgProperties[0].colid.uName.pwszName, wszDBPropertyColumnName, sizeof(wszDBPropertyColumnName));
|
||||
/* vValue contents */
|
||||
V_VT(&prgPropertySets[0]->rgProperties[0].vValue) = VT_BSTR;
|
||||
V_BSTR(&prgPropertySets[0]->rgProperties[0].vValue) = SysAllocString(wszDBPropertyTestString);
|
||||
prgPropertySets[0]->cProperties = 1;
|
||||
prgPropertySets[0]->guidPropertySet = IID_IDBProperties;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Test_DBProperties_GetPropertyInfo(
|
||||
IDBProperties* iface,
|
||||
ULONG cPropertyIDSets,
|
||||
const DBPROPIDSET rgPropertyIDSets[],
|
||||
ULONG *pcPropertyInfoSets,
|
||||
DBPROPINFOSET **prgPropertyInfoSets,
|
||||
OLECHAR **ppDescBuffer)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Test_DBProperties_SetProperties(
|
||||
IDBProperties* iface,
|
||||
ULONG cPropertySets,
|
||||
DBPROPSET rgPropertySets[])
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IDBPropertiesVtbl Test_DBProperties_Vtbl =
|
||||
{
|
||||
Test_DBProperties_QueryInterface,
|
||||
Test_DBProperties_AddRef,
|
||||
Test_DBProperties_Release,
|
||||
Test_DBProperties_GetProperties,
|
||||
Test_DBProperties_GetPropertyInfo,
|
||||
Test_DBProperties_SetProperties,
|
||||
};
|
||||
|
||||
static IDBProperties Test_DBProperties =
|
||||
{
|
||||
&Test_DBProperties_Vtbl
|
||||
};
|
||||
|
||||
static void test_IDBProperties(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
IStream *pStream = NULL;
|
||||
IDBProperties *pProxy = NULL;
|
||||
DWORD tid;
|
||||
HANDLE thread;
|
||||
static const LARGE_INTEGER ullZero;
|
||||
ULONG propset_count;
|
||||
DBPROPSET *propsets = NULL;
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
|
||||
ok_ole_success(hr, "CreateStreamOnHGlobal");
|
||||
tid = start_host_object(pStream, &IID_IDBProperties, (IUnknown*)&Test_DBProperties, MSHLFLAGS_NORMAL, &thread);
|
||||
|
||||
IStream_Seek(pStream, ullZero, STREAM_SEEK_SET, NULL);
|
||||
hr = CoUnmarshalInterface(pStream, &IID_IDBProperties, (void **)&pProxy);
|
||||
ok_ole_success(hr, "CoUnmarshalInterface");
|
||||
IStream_Release(pStream);
|
||||
|
||||
propset_count = 1;
|
||||
hr = IDBProperties_GetProperties(pProxy, 0, NULL, &propset_count, &propsets);
|
||||
ok_ole_success(hr, "IDBProperties_GetProperties");
|
||||
|
||||
ok(propset_count == 1, "Expected propset_count of 1 but got %d\n", propset_count);
|
||||
ok(propsets->rgProperties[0].dwPropertyID == TEST_PROPID, "Expected property ID of 0x%x, but got 0x%x\n", TEST_PROPID, propsets->rgProperties[0].dwPropertyID);
|
||||
ok(propsets->rgProperties[0].dwOptions == DBPROPOPTIONS_REQUIRED, "Expected property options of 0x%x, but got 0x%x\n", DBPROPOPTIONS_REQUIRED, propsets->rgProperties[0].dwOptions);
|
||||
ok(propsets->rgProperties[0].dwStatus == S_OK, "Expected property options of 0x%x, but got 0x%x\n", S_OK, propsets->rgProperties[0].dwStatus);
|
||||
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);
|
||||
/* colid contents */
|
||||
ok(IsEqualGUID(&propsets->rgProperties[0].colid.uGuid.guid, &IID_IDBProperties), "Unexpected property colid guid\n");
|
||||
ok(!lstrcmpW(propsets->rgProperties[0].colid.uName.pwszName, wszDBPropertyColumnName), "Unexpected property colid name\n");
|
||||
/* vValue contents */
|
||||
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));
|
||||
ok(!lstrcmpW(V_BSTR(&propsets->rgProperties[0].vValue), wszDBPropertyTestString), "Unexpected property value string\n");
|
||||
ok(propsets->cProperties == 1, "Expected property count of 1 but got %d\n", propsets->cProperties);
|
||||
ok(IsEqualGUID(&propsets->guidPropertySet, &IID_IDBProperties), "Unexpected guid for property set\n");
|
||||
|
||||
IDBProperties_Release(pProxy);
|
||||
|
||||
end_host_object(tid, thread);
|
||||
}
|
||||
|
||||
START_TEST(marshal)
|
||||
{
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
test_IDBProperties();
|
||||
CoUninitialize();
|
||||
}
|
Loading…
Reference in New Issue