From: Vibhav Pant vibhavp@gmail.com
--- dlls/structuredquery/Makefile.in | 1 + dlls/structuredquery/main.c | 38 +++++-- dlls/structuredquery/private.h | 24 +++++ dlls/structuredquery/queryparser.c | 167 +++++++++++++++++++++++++++++ dlls/structuredquery/tests/query.c | 2 +- 5 files changed, 224 insertions(+), 8 deletions(-) create mode 100644 dlls/structuredquery/private.h create mode 100644 dlls/structuredquery/queryparser.c
diff --git a/dlls/structuredquery/Makefile.in b/dlls/structuredquery/Makefile.in index 747309707a3..673ab666aa1 100644 --- a/dlls/structuredquery/Makefile.in +++ b/dlls/structuredquery/Makefile.in @@ -6,3 +6,4 @@ EXTRADLLFLAGS = -Wb,--prefer-native SOURCES = \ classes.idl \ main.c \ + queryparser.c diff --git a/dlls/structuredquery/main.c b/dlls/structuredquery/main.c index 81b24c3873d..939b5da251f 100644 --- a/dlls/structuredquery/main.c +++ b/dlls/structuredquery/main.c @@ -18,16 +18,25 @@
#define COBJMACROS #include <initguid.h> -#include <structuredquery.h> +#include "private.h"
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL( structquery );
+static const struct class_info +{ + const CLSID *clsid; + HRESULT (*constructor)(REFIID, void **); +} class_info[] = { + { &CLSID_QueryParser, queryparser_create }, +}; + struct class_factory { IClassFactory iface; LONG ref; + const struct class_info *info; };
static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface ) @@ -74,8 +83,18 @@ static ULONG WINAPI factory_Release( IClassFactory *iface ) static HRESULT WINAPI factory_CreateInstance( IClassFactory *iface, IUnknown *outer, REFIID iid, void **out ) { - FIXME( "(%p, %p, %s, %p) stub!\n", iface, outer, debugstr_guid( iid ), out ); - return E_NOTIMPL; + struct class_factory *impl; + + TRACE( "(%p, %p, %s, %p)\n", iface, outer, debugstr_guid( iid ), out ); + impl = impl_from_IClassFactory( iface ); + + if (!iid || !out) + return E_INVALIDARG; + if (outer) + return CLASS_E_NOAGGREGATION; + + *out = NULL; + return impl->info->constructor( iid, out ); }
static HRESULT WINAPI factory_LockServer( IClassFactory *iface, BOOL lock ) @@ -95,16 +114,16 @@ const static IClassFactoryVtbl factory_vtbl = factory_LockServer };
-static HRESULT factory_create( REFIID iid, void **obj ) +static HRESULT factory_create( const struct class_info *info, REFIID iid, void **obj ) { HRESULT hr; struct class_factory *impl;
- impl = calloc( 1, sizeof( *impl ) ); if (!impl) return E_OUTOFMEMORY; impl->iface.lpVtbl = &factory_vtbl; + impl->info = info; impl->ref = 1;
hr = IClassFactory_QueryInterface( &impl->iface, iid, obj ); @@ -115,6 +134,8 @@ static HRESULT factory_create( REFIID iid, void **obj )
HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID iid, void **out ) { + SIZE_T i; + TRACE( "(%s, %s, %p)\n", debugstr_guid( clsid ), debugstr_guid( iid ), out );
if (!clsid || !iid || !out) @@ -122,8 +143,11 @@ HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID iid, void **out )
*out = NULL;
- if (IsEqualCLSID( clsid, &CLSID_QueryParser )) - return factory_create( iid, out ); + for (i = 0; i < ARRAY_SIZE( class_info ); i++) + { + if (IsEqualCLSID( class_info[i].clsid, clsid )) + return factory_create( &class_info[i], iid, out ); + }
FIXME("Class not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n"); return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/structuredquery/private.h b/dlls/structuredquery/private.h new file mode 100644 index 00000000000..52c968b9a89 --- /dev/null +++ b/dlls/structuredquery/private.h @@ -0,0 +1,24 @@ +/* + * Copyright 2024 Vibhav Pant + * + * 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 + */ + +#ifndef __WINE_STRUCTUREDQUERY_PRIVATE_H__ +#define __WINE_STRUCTUREDQUERY_PRIVATE_H__ +#include <structuredquery.h> + +extern HRESULT queryparser_create( REFIID iid, void **out ); +#endif diff --git a/dlls/structuredquery/queryparser.c b/dlls/structuredquery/queryparser.c new file mode 100644 index 00000000000..ffb153be197 --- /dev/null +++ b/dlls/structuredquery/queryparser.c @@ -0,0 +1,167 @@ +/* + * Copyright 2024 Vibhav Pant + * + * 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 COBJMACROS +#include "private.h" + +#include <wine/debug.h> + +WINE_DEFAULT_DEBUG_CHANNEL( structquery ); + +struct queryparser +{ + IQueryParser iface; + PROPVARIANT options[SQSO_CONNECTOR_CASE]; + LONG ref; +}; + +static inline struct queryparser *impl_from_IQueryParser( IQueryParser *iface ) +{ + return CONTAINING_RECORD( iface, struct queryparser, iface ); +} + +static HRESULT WINAPI queryparser_QueryInterface( IQueryParser *iface, REFIID iid, void **out ) +{ + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out ); + + *out = NULL; + if (IsEqualGUID( &IID_IUnknown, iid ) || + IsEqualGUID( &IID_IQueryParser, iid )) + { + *out = iface; + IUnknown_AddRef( iface ); + return S_OK; + } + + FIXME( "interface not implemented, returning E_NOINTERFACE\n" ); + return E_NOINTERFACE; +} + +static ULONG WINAPI queryparser_AddRef( IQueryParser *iface ) +{ + struct queryparser *impl; + TRACE( "(%p)\n", iface ); + + impl = impl_from_IQueryParser( iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG WINAPI queryparser_Release( IQueryParser *iface ) +{ + struct queryparser *impl; + ULONG ref; + + TRACE( "(%p)\n", iface ); + + impl = impl_from_IQueryParser( iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + free( impl ); + return ref; +} + +static HRESULT WINAPI queryparser_Parse( IQueryParser *iface, LPCWSTR input, + IEnumUnknown *custom_props, IQuerySolution **solution ) +{ + FIXME( "(%p, %s, %p, %p) stub!\n", iface, debugstr_w( input ), custom_props, solution ); + return E_NOTIMPL; +} + +static HRESULT WINAPI queryparser_SetOption( IQueryParser *iface, + STRUCTURED_QUERY_SINGLE_OPTION option, + const PROPVARIANT *val ) +{ + FIXME( "(%p, %d, %p) stub!\n", iface, option, val ); + return E_NOTIMPL; +} + +static HRESULT WINAPI queryparser_GetOption( IQueryParser *iface, + STRUCTURED_QUERY_SINGLE_OPTION option, + PROPVARIANT *val ) +{ + FIXME( "(%p, %d, %p) stub!\n", iface, option, val ); + return E_NOTIMPL; +} + +static HRESULT WINAPI queryparser_SetMultiOption( IQueryParser *iface, + STRUCTURED_QUERY_MULTIOPTION opt, LPCWSTR key, + const PROPVARIANT *val ) +{ + FIXME( "(%p, %d, %s, %p) stub!\n", iface, opt, debugstr_w( key ), val ); + return E_NOTIMPL; +} + +static HRESULT WINAPI queryparser_GetSchemaProvider( IQueryParser *iface, + ISchemaProvider **provider ) +{ + FIXME( "(%p, %p) stub!\n", iface, provider ); + return E_NOTIMPL; +} + +static HRESULT WINAPI queryparser_RestateToString( IQueryParser *iface, ICondition *cond, + BOOL english, LPWSTR *query ) +{ + FIXME( "(%p, %p, %d, %p) stub!\n", iface, cond, english, query ); + return E_NOTIMPL; +} + +static HRESULT WINAPI queryparser_ParsePropertyValue( IQueryParser *iface, LPCWSTR property, + LPCWSTR input, IQuerySolution **solution ) +{ + FIXME( "(%p, %s, %s, %p) stub!\n", iface, debugstr_w( property ), debugstr_w( input ), + solution ); + return E_NOTIMPL; +} + +static HRESULT WINAPI queryparser_RestatePropertyValueToString( IQueryParser *iface, + ICondition *cond, BOOL english, + LPWSTR *name, LPWSTR *query ) +{ + FIXME( "(%p, %p, %d, %p, %p) stub!\n", iface, cond, english, name, query ); + return E_NOTIMPL; +} + +const static IQueryParserVtbl queryparser_vtbl = +{ + /* IUnknown */ + queryparser_QueryInterface, + queryparser_AddRef, + queryparser_Release, + /* IQueryParser */ + queryparser_Parse, + queryparser_SetOption, + queryparser_GetOption, + queryparser_SetMultiOption, + queryparser_GetSchemaProvider, + queryparser_RestateToString, + queryparser_ParsePropertyValue, + queryparser_RestatePropertyValueToString, +}; + +HRESULT queryparser_create( REFIID iid, void **out ) +{ + struct queryparser *impl; + + impl = calloc( 1, sizeof( *impl ) ); + if (!impl) + return E_OUTOFMEMORY; + impl->iface.lpVtbl = &queryparser_vtbl; + impl->ref = 1; + *out = &impl->iface; + return S_OK; +} diff --git a/dlls/structuredquery/tests/query.c b/dlls/structuredquery/tests/query.c index 68063679346..352cd32006e 100644 --- a/dlls/structuredquery/tests/query.c +++ b/dlls/structuredquery/tests/query.c @@ -32,7 +32,7 @@ void test_IQueryParser( void )
hr = CoCreateInstance( &CLSID_QueryParser, NULL, CLSCTX_INPROC, &IID_IQueryParser, (void **)&parser ); - todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr );
if (!parser) {