[PATCH 0/4] MR6788: dlls/structuredquery: Introduce new DLL, add stubs.
structuredquery is required to support AQS filters in Windows.Devices.Enumeration's `FindAllAsync` methods, and this stubs adds a basic set of stubs to get the ball rolling. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6788
From: Vibhav Pant <vibhavp(a)gmail.com> --- include/Makefile.in | 1 + include/structuredquery.idl | 293 +++++++++++++++++++++++++++ include/structuredquerycondition.idl | 43 ++++ 3 files changed, 337 insertions(+) create mode 100644 include/structuredquery.idl diff --git a/include/Makefile.in b/include/Makefile.in index 856a9f79b95..b56f4aa2fcf 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -747,6 +747,7 @@ SOURCES = \ strmif.idl \ strongname.h \ strsafe.h \ + structuredquery.idl \ structuredquerycondition.idl \ svrapi.h \ synchapi.h \ diff --git a/include/structuredquery.idl b/include/structuredquery.idl new file mode 100644 index 00000000000..2040cf9a0e5 --- /dev/null +++ b/include/structuredquery.idl @@ -0,0 +1,293 @@ +/* + * Structured Query support + * + * 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 + * + */ + +import "structuredquerycondition.idl"; +import "objectarray.idl"; + +cpp_quote("#if 0") +typedef PROPERTYKEY *REFPROPERTYKEY; +cpp_quote("#endif") +cpp_quote("#include <propkeydef.h>") + +typedef [v1_enum] enum tagSTRUCTURED_QUERY_SINGLE_OPTION +{ + SQSO_SCHEMA, + SQSO_LOCALE_WORD_BREAKING, + SQSO_WORD_BREAKER, + SQSO_NATURAL_SYNTAX, + SQSO_AUTOMATIC_WILDCARD, + SQSO_TRACE_LEVEL, + SQSO_LANGUAGE_KEYWORDS, + SQSO_SYNTAX, + SQSO_TIME_ZONE, + SQSO_IMPLICIT_CONNECTOR, + SQSO_CONNECTOR_CASE, +} STRUCTURED_QUERY_SINGLE_OPTION; + +typedef [v1_enum] enum tagSTRUCTURED_QUERY_MULTIOPTION +{ + SQMO_VIRTUAL_PROPERTY, + SQMO_DEFAULT_PROPERTY, + SQMO_GENERATOR_FOR_TYPE, + SQMO_MAP_PROPERTY, +} STRUCTURED_QUERY_MULTIOPTION; + +typedef [v1_enum] enum STRUCTURED_QUERY_RESOLVE_OPTION +{ + SQRO_DEFAULT = 0, + SQRO_DONT_RESOLVE_DATETIME = 0x0001, + SQRO_ALWAYS_ONE_INTERVAL = 0x0002, + SQRO_DONT_SIMPLIFY_CONDITION_TREES = 0x0004, + SQRO_DONT_MAP_RELATIONS = 0x0008, + SQRO_DONT_RESOLVE_RANGES = 0x0010, + SQRO_DONT_REMOVE_UNRESTRICTED_KEYWORDS = 0x0020, + SQRO_DONT_SPLIT_WORDS = 0x0040, + SQRO_IGNORE_PHRASE_ORDER = 0x0080, + SQRO_ADD_VALUE_TYPE_FOR_PLAIN_VALUES = 0x0100, + SQRO_ADD_ROBUST_ITEM_NAME = 0x0200, +} STRUCTURED_QUERY_RESOLVE_OPTION; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(STRUCTURED_QUERY_RESOLVE_OPTION);") + +interface IQueryParser; +interface IQuerySolution; +interface IConditionFactory; +interface IConditionFactory2; +interface ITokenCollection; +interface IRelationship; +interface IEntity; +interface INamedEntity; +interface ISchemaLocalizerSupport; +interface ISchemaProvider; + +[ + object, + pointer_default(unique), + uuid(2ebdee67-3505-43f8-9946-ea44abc8e5b0) +] +interface IQueryParser : IUnknown +{ + HRESULT Parse([in] LPCWSTR input, [in] IEnumUnknown *custom_props, [out, retval] IQuerySolution **solution); + HRESULT SetOption([in] STRUCTURED_QUERY_SINGLE_OPTION option, [in] const PROPVARIANT *val); + HRESULT GetOption([in] STRUCTURED_QUERY_SINGLE_OPTION option, [out, retval] PROPVARIANT *val); + HRESULT SetMultiOption([in] STRUCTURED_QUERY_MULTIOPTION option, [in] LPCWSTR key, [in] const PROPVARIANT *val); + HRESULT GetSchemaProvider([out, retval] ISchemaProvider **provider); + HRESULT RestateToString([in] ICondition *cond, [in] BOOL english, [out] LPWSTR *query); + HRESULT ParsePropertyValue([in] LPCWSTR property, [in] LPCWSTR input, [out, retval] IQuerySolution **solution); + HRESULT RestatePropertyValueToString([in] ICondition* cond, [in] BOOL english, [out] LPWSTR *name, + [out] LPWSTR *query); + +} + +typedef [v1_enum] enum tagQUERY_PARSER_MANAGER_OPTION +{ + QPMO_SCHEMA_BINARY_NAME, + QPMO_PRELOCALIZED_SCHEMA_BINARY_PATH, + QPMO_UNLOCALIZED_SCHEMA_BINARY_PATH, + QPMO_LOCALIZED_SCHEMA_BINARY_PATH, + QPMO_APPEND_LCID_TO_LOCALIZED_PATH, + QPMO_LOCALIZER_SUPPORT, +} QUERY_PARSER_MANAGER_OPTION; + +[ + object, + uuid(D6EBC66B-8921-4193-AFDD-A1789FB7FF57), + pointer_default(unique) +] +interface IQuerySolution : IConditionFactory +{ + [local] + HRESULT GetQuery([out] ICondition **cond, [out] IEntity **main); + /* ID can be IID_IEnumUnknown and IID_IEnumVARIANT */ + HRESULT GetErrors([in] REFIID riid, [out, retval, iid_is(riid)] void **out); + [local] + HRESULT GetLexicalData([out] LPWSTR *input, [out] ITokenCollection **tokens, [out] LCID *lcid, + [out] IUnknown **breaker); +} + +[ + object, + pointer_default(unique), + uuid(A5EFE073-B16F-474f-9F3E-9f8b497a3e08) +] +interface IConditionFactory : IUnknown +{ + HRESULT MakeNot([in] ICondition *cond, [in] BOOL simplify, [out, retval] ICondition **result); + HRESULT MakeAndOr([in] CONDITION_TYPE type, [in] IEnumUnknown *conditions, [in] BOOL simplify, + [out, retval] ICondition **result); + HRESULT MakeLeaf([in, unique] LPCWSTR prop, [in] CONDITION_OPERATION cop, [in, unique] LPCWSTR val_type, + [in] const PROPVARIANT *prop_var, [in] IRichChunk *prop_term, [in] IRichChunk *op_term, + [in] IRichChunk *value_term, [in] BOOL expand, [out, retval] ICondition **result); + [local] + HRESULT Resolve([in] ICondition *cond, [in] STRUCTURED_QUERY_RESOLVE_OPTION opt, [in, ref] const SYSTEMTIME *time, + [out, retval] ICondition **result); +} + +typedef [v1_enum] enum CONDITION_CREATION_OPTIONS +{ + CONDITION_CREATION_DEFAULT = 0, + CONDITION_CREATION_NONE = 0, + CONDITION_CREATION_SIMPLIFY = 0x01, + CONDITION_CREATION_VECTOR_AND = 0x02, + CONDITION_CREATION_VECTOR_OR = 0x04, + CONDITION_CREATION_VECTOR_LEAF = 0x08, + CONDITION_CREATION_USE_CONTENT_LOCALE = 0x10, +} CONDITION_CREATION_OPTIONS; +cpp_quote("DEFINE_ENUM_FLAG_OPERATORS( CONDITION_CREATION_OPTIONS );") + + +[ + object, + pointer_default(unique), + uuid(71d222e1-432f-429e-8c13-b6dafde5077a), + local +] +interface IConditionFactory2 : IConditionFactory +{ + HRESULT CreateTrueFalse([in] BOOL val, [in] CONDITION_CREATION_OPTIONS opts, [in] REFIID riid, + [out, iid_is(riid)] void **out); + HRESULT CreateNegation([in] ICondition *cond, [in] CONDITION_CREATION_OPTIONS opts, [in] REFIID riid, + [out, iid_is(riid)] void **out); + HRESULT CreateCompoundFromObjectArray([in] CONDITION_TYPE type, [in] IObjectArray *conditions, + [in] CONDITION_CREATION_OPTIONS opts, [in] REFIID riid, + [out, iid_is(riid)] void **out); + HRESULT CreateCompoundFromArray([in] CONDITION_TYPE type, [in, size_is(cond_count)] ICondition **conditions, + [in] ULONG cond_count, [in] CONDITION_CREATION_OPTIONS opts, [in] REFIID riid, + [out, iid_is(riid)] void **out); + HRESULT CreateStringLeaf([in] REFPROPERTYKEY propkey, [in] CONDITION_OPERATION op, [in] LPCWSTR val, + [in] LPCWSTR locale, [in] CONDITION_CREATION_OPTIONS opts, [in] REFIID riid, + [out, iid_is(riid)] void **out); + HRESULT CreateIntegerLeaf([in] REFPROPERTYKEY propkey, [in] CONDITION_OPERATION op, [in] INT32 val, + [in] CONDITION_CREATION_OPTIONS opts, [in] REFIID riid, [out, iid_is(riid)] void **out); + HRESULT CreateBooleanLeaf([in] REFPROPERTYKEY propkey, [in] CONDITION_OPERATION op, [in] BOOL val, + [in] CONDITION_CREATION_OPTIONS opts, [in] REFIID riid, [out, iid_is(riid)] void **out); + HRESULT CreateLeaf([in] REFPROPERTYKEY propkey, [in] CONDITION_OPERATION op, [in] REFPROPVARIANT prop_var, + [in] LPCWSTR type, [in] LPCWSTR locale, [in] IRichChunk *prop_name_term, [in] IRichChunk *op_term, + [in] IRichChunk *val_term, [in] CONDITION_CREATION_OPTIONS cco, [in] REFIID riid, + [out, iid_is(riid)] void **out); + HRESULT ResolveCondition([in] ICondition *cond, [in] STRUCTURED_QUERY_RESOLVE_OPTION opt, [in] const SYSTEMTIME *time, + [in] REFIID riid, [out, iid_is(riid)] void **out); +} + +[ + object, + pointer_default(unique), + uuid(22d8b4f2-f577-4adb-a335-c2ae88416fab), +] +interface ITokenCollection : IUnknown +{ + HRESULT NumberOfTokens([out] ULONG *num); + [local] + HRESULT GetToken([in] ULONG i, [out] ULONG *begin, [out] ULONG *len, [out] LPWSTR *token_str); +}; + +[ + object, + pointer_default(unique), + uuid(2769280b-5108-498c-9c7f-a51239b63147), +] +interface IRelationship : IUnknown +{ + [local] + HRESULT Name([out, retval] LPWSTR *name); + HRESULT IsReal([out, retval] BOOL *real); + HRESULT Destination([out, retval] IEntity **dest); + /* ID can be be IID_IEnumUnknown or IID_IEnumVARIANT */ + HRESULT MetaData([in] REFIID riid, [out, retval, iid_is(riid)] void **out); + [local] + HRESULT DefaultPhrase([out, retval] LPWSTR *phrase); +}; + +[ + object, + pointer_default(unique), + uuid(24264891-e80b-4fd3-b7ce-4ff2fae8931f), +] +interface IEntity : IUnknown +{ + [local] + HRESULT Name([out, retval] LPWSTR *name); + HRESULT Base([out, retval] IEntity **base); + /* ID can be IID_IEnumUnknown or IID_IEnumVARIANT. */ + HRESULT Relationships([in] REFIID riid, [out, retval, iid_is(riid)] void **out); + HRESULT GetRelationship([in] LPCWSTR name, [out, retval] IRelationship **relation); + HRESULT MetaData([in] REFIID riid, [out, retval, iid_is(riid)] void **out); + /* ID can be IID_IEnumUnknown or IID_IEnumVARIANT. */ + HRESULT NamedEntities([in] REFIID riid, [out, retval, iid_is(riid)] void **out); + HRESULT GetNamedEntity([in] LPCWSTR name, [out, retval] INamedEntity **entity); + [local] + HRESULT DefaultPhrase([out, retval] LPWSTR *phrase); +}; + +[ + object, + pointer_default(unique), + uuid(abdbd0b1-7d54-49fb-ab5c-bff4130004cd), +] +interface INamedEntity : IUnknown +{ + HRESULT GetValue([out, retval] LPWSTR *value); + [local] + HRESULT DefaultPhrase([out, retval] LPWSTR *phrase); +} + +[ + object, + pointer_default(unique), + uuid(ca3fdca2-bfbe-4eed-90d7-0caef0a1bda1), +] +interface ISchemaLocalizerSupport : IUnknown +{ + HRESULT Localize([in] LPCWSTR str, [out, retval] LPWSTR *str_out); +} + +[ + object, + pointer_default(unique), + uuid(8cf89bcb-394c-49b2-ae28-a59dd4ed7f68), +] +interface ISchemaProvider : IUnknown +{ + /* ID can be be IID_IEnumUnknown or IID_IEnumVARIANT */ + HRESULT Entities([in] REFIID riid, [out, retval, iid_is(riid)] void** out); + HRESULT RootEntity([out, retval] IEntity **root); + HRESULT GetEntity([in] LPCWSTR name, [out, retval] IEntity **entity); + /* ID can be be IID_IEnumUnknown or IID_IEnumVARIANT */ + HRESULT MetaData([in] REFIID riid, [out, retval, iid_is(riid)] void** out); + HRESULT Localize([in] LCID lcid, [in] ISchemaLocalizerSupport *support); + HRESULT SaveBinary([in] LPCWSTR path); + HRESULT LookupAuthoredNamedEntity([in] IEntity *entity, [in] LPCWSTR input, [in] ITokenCollection *tokens, + [in] ULONG begin, [out] ULONG *len, [out] LPWSTR *val); +}; + +[ + uuid(1352fa67-2022-41df-9d6f-943a5ee97c9f), + version(1.0) +] +library StructuredQuery1 +{ + [ + uuid(b72f8fd8-0fab-4dd9-bdbf-245a6ce1485b) + ] + coclass QueryParser + { + interface IQueryParser; + }; +} diff --git a/include/structuredquerycondition.idl b/include/structuredquerycondition.idl index 8eb4d51ce87..9cc3b12e147 100644 --- a/include/structuredquerycondition.idl +++ b/include/structuredquerycondition.idl @@ -51,3 +51,46 @@ typedef [v1_enum] enum tagCONDITION_OPERATION COP_WORD_STARTSWITH, COP_APPLICATION_SPECIFIC } CONDITION_OPERATION; + +[ + object, + pointer_default(unique), + uuid(4fdef69c-dbc9-454e-9910-b34f3c64b510), +] +interface IRichChunk : IUnknown +{ + [local] + HRESULT GetData([out, unique] ULONG *first_pos, [out, unique] ULONG *len, + [out, unique] LPWSTR *str, [out, unique] PROPVARIANT *val); + [call_as(GetData)] + HRESULT RemoteGetData([out, unique] ULONG *first_pos, [out, unique] ULONG *len, + [out, unique] LPWSTR *str, [out, unique] PROPVARIANT *val); +}; + +[ + object, + uuid(0FC988D4-C935-4b97-A973-46282EA175C8), + pointer_default(unique), +] +interface ICondition : IPersistStream +{ + HRESULT GetConditionType([out, retval] CONDITION_TYPE *type); + /* ID can be ID IID_IEnumUnknown, IID_IEnumVARIANT IID_IObjectArray, or IID_ICondition. */ + HRESULT GetSubConditions([in] REFIID riid, [out, retval, iid_is(riid)] void** ppv); + [local] + HRESULT GetComparisonInfo([out, unique] LPWSTR *prop_name, [out, unique] CONDITION_OPERATION *op, + [out, unique] PROPVARIANT *prop_var); + [call_as(GetComparisonInfo)] + HRESULT RemoteGetComparisonInfo([out, unique] LPWSTR *prop_name, [out, unique] CONDITION_OPERATION *op, + [out, unique] PROPVARIANT *prop_var); + HRESULT GetValueType([out, retval] LPWSTR *name); + HRESULT GetValueNormalization([out, retval] LPWSTR *normalized); + [local] + HRESULT GetInputTerms([out, unique] IRichChunk **prop_Term, [out, unique] IRichChunk **op_term, + [out, unique] IRichChunk **val_term); + + [call_as(GetInputTerms)] + HRESULT RemoteGetInputTerms([out, unique] IRichChunk **prop_Term, [out, unique] IRichChunk **op_term, + [out, unique] IRichChunk **val_term); + HRESULT Clone([out, retval] ICondition **out); +}; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6788
From: Vibhav Pant <vibhavp(a)gmail.com> --- configure | 3 + configure.ac | 2 + dlls/structuredquery/Makefile.in | 8 ++ dlls/structuredquery/classes.idl | 28 +++++ dlls/structuredquery/main.c | 130 ++++++++++++++++++++++ dlls/structuredquery/structuredquery.spec | 4 + 6 files changed, 175 insertions(+) create mode 100644 dlls/structuredquery/Makefile.in create mode 100644 dlls/structuredquery/classes.idl create mode 100644 dlls/structuredquery/main.c create mode 100644 dlls/structuredquery/structuredquery.spec diff --git a/configure b/configure index bf64f9b8bb9..419f2044bf8 100755 --- a/configure +++ b/configure @@ -1434,6 +1434,7 @@ enable_stdole2_tlb enable_stdole32_tlb enable_sti enable_strmdll +enable_structuredquery enable_svrapi enable_sxs enable_t2embed @@ -22525,6 +22526,8 @@ wine_fn_config_makefile dlls/sti/tests enable_tests wine_fn_config_makefile dlls/storage.dll16 enable_win16 wine_fn_config_makefile dlls/stress.dll16 enable_win16 wine_fn_config_makefile dlls/strmdll enable_strmdll +wine_fn_config_makefile dlls/structuredquery enable_structuredquery +wine_fn_config_makefile dlls/structuredquery/tests enable_tests wine_fn_config_makefile dlls/svrapi enable_svrapi wine_fn_config_makefile dlls/sxs enable_sxs wine_fn_config_makefile dlls/sxs/tests enable_tests diff --git a/configure.ac b/configure.ac index 8edfce44d6e..e5ba9dc1503 100644 --- a/configure.ac +++ b/configure.ac @@ -3102,6 +3102,8 @@ WINE_CONFIG_MAKEFILE(dlls/sti/tests) WINE_CONFIG_MAKEFILE(dlls/storage.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/stress.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/strmdll) +WINE_CONFIG_MAKEFILE(dlls/structuredquery) +WINE_CONFIG_MAKEFILE(dlls/structuredquery/tests) WINE_CONFIG_MAKEFILE(dlls/svrapi) WINE_CONFIG_MAKEFILE(dlls/sxs) WINE_CONFIG_MAKEFILE(dlls/sxs/tests) diff --git a/dlls/structuredquery/Makefile.in b/dlls/structuredquery/Makefile.in new file mode 100644 index 00000000000..747309707a3 --- /dev/null +++ b/dlls/structuredquery/Makefile.in @@ -0,0 +1,8 @@ +MODULE = structuredquery.dll +IMPORTLIB = structuredquery +IMPORTS = ole32 oleaut32 uuid + +EXTRADLLFLAGS = -Wb,--prefer-native +SOURCES = \ + classes.idl \ + main.c \ diff --git a/dlls/structuredquery/classes.idl b/dlls/structuredquery/classes.idl new file mode 100644 index 00000000000..d5cf17fd37c --- /dev/null +++ b/dlls/structuredquery/classes.idl @@ -0,0 +1,28 @@ +/* + * 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 + */ + +#pragma makedep register + +[ + uuid(b72f8fd8-0fab-4dd9-bdbf-245a6ce1485b), + threading(both) +] +coclass QueryParser +{ + interface IQueryParser; +} diff --git a/dlls/structuredquery/main.c b/dlls/structuredquery/main.c new file mode 100644 index 00000000000..40b328dd3e8 --- /dev/null +++ b/dlls/structuredquery/main.c @@ -0,0 +1,130 @@ +/* + * 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 <initguid.h> +#include <structuredquery.h> + +#include <wine/debug.h> + +WINE_DEFAULT_DEBUG_CHANNEL( structquery ); + +struct class_factory +{ + IClassFactory iface; + LONG ref; +}; + +static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct class_factory, iface ); +} + +static HRESULT WINAPI factory_QueryInterface( IClassFactory *iface, REFIID iid, void **out ) +{ + TRACE( "(%p, %s, %p)\n", iface, debugstr_guid( iid ), out ); + *out = NULL; + + if (IsEqualGUID( &IID_IUnknown, iid ) || + IsEqualGUID( &IID_IClassFactory, iid )) + { + *out = iface; + IClassFactory_AddRef( iface ); + return S_OK; + } + + FIXME( "Interface not implemented, returning E_NOINTERFACE.\n" ); + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IClassFactory *iface ) +{ + struct class_factory *impl = impl_from_IClassFactory( iface ); + TRACE( "(%p)\n", iface ); + return InterlockedIncrement( &impl->ref ); +} + +static ULONG WINAPI factory_Release( IClassFactory *iface ) +{ + struct class_factory *impl = impl_from_IClassFactory( iface ); + ULONG ref; + + TRACE( "(%p)\n", iface ); + ref = InterlockedDecrement( &impl->ref ); + if (!ref) + free( impl ); + return ref; +} + +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; +} + +static HRESULT WINAPI factory_LockServer( IClassFactory *iface, BOOL lock ) +{ + TRACE( "(%p, %d\n)", iface, lock ); + return S_OK; +} + +const static IClassFactoryVtbl factory_vtbl = +{ + /* IUnknown */ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IClassFactory */ + factory_CreateInstance, + factory_LockServer +}; + +static HRESULT factory_create( 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->ref = 1; + + hr = IClassFactory_QueryInterface( &impl->iface, iid, obj ); + IClassFactory_Release( &impl->iface ); + + return hr; +} + +HRESULT DllGetClassObject( REFCLSID clsid, REFIID iid, void **out ) +{ + TRACE( "(%s, %, %p)\n", debugstr_guid( clsid ), debugstr_guid( iid ), out ); + + if (!clsid || !iid || !out) + return E_INVALIDARG; + + *out = NULL; + + if (IsEqualCLSID( clsid, &CLSID_QueryParser )) + return factory_create( iid, out ); + + FIXME("Class not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n"); + return CLASS_E_CLASSNOTAVAILABLE; +} diff --git a/dlls/structuredquery/structuredquery.spec b/dlls/structuredquery/structuredquery.spec new file mode 100644 index 00000000000..b16365d0c9f --- /dev/null +++ b/dlls/structuredquery/structuredquery.spec @@ -0,0 +1,4 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6788
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/structuredquery/tests/Makefile.in | 5 +++ dlls/structuredquery/tests/query.c | 51 ++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 dlls/structuredquery/tests/Makefile.in create mode 100644 dlls/structuredquery/tests/query.c diff --git a/dlls/structuredquery/tests/Makefile.in b/dlls/structuredquery/tests/Makefile.in new file mode 100644 index 00000000000..5bf2fc317b7 --- /dev/null +++ b/dlls/structuredquery/tests/Makefile.in @@ -0,0 +1,5 @@ +TESTDLL = structuredquery.dll +IMPORTS = ole32 oleaut32 + +SOURCES = \ + query.c diff --git a/dlls/structuredquery/tests/query.c b/dlls/structuredquery/tests/query.c new file mode 100644 index 00000000000..0e8c7cb7fbe --- /dev/null +++ b/dlls/structuredquery/tests/query.c @@ -0,0 +1,51 @@ +/* + * 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 <initguid.h> +#include <structuredquery.h> + +#include <wine/test.h> + +void test_IQueryParser(void) +{ + HRESULT hr; + IQueryParser *parser = NULL; + + hr = CoInitializeEx( NULL, COINIT_MULTITHREADED ); + ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + + hr = CoCreateInstance( &CLSID_QueryParser, NULL, CLSCTX_INPROC, &IID_IQueryParser, + (void **)&parser ); + todo_wine ok( SUCCEEDED( hr ), "got %#lx\n", hr ); + + if (!parser) + { + skip( "Could not create IQueryParser instance.\n" ); + CoUninitialize(); + return; + } + + IQueryParser_Release( parser ); + CoUninitialize(); +} + +START_TEST(query) +{ + test_IQueryParser(); +} -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6788
From: Vibhav Pant <vibhavp(a)gmail.com> --- dlls/structuredquery/Makefile.in | 1 + dlls/structuredquery/main.c | 40 +++++-- dlls/structuredquery/queryparser.c | 167 +++++++++++++++++++++++++++++ dlls/structuredquery/tests/query.c | 2 +- 4 files changed, 202 insertions(+), 8 deletions(-) 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 40b328dd3e8..e547fdb96d2 100644 --- a/dlls/structuredquery/main.c +++ b/dlls/structuredquery/main.c @@ -18,16 +18,27 @@ #define COBJMACROS #include <initguid.h> -#include <structuredquery.h> +#include "private.h" #include <wine/debug.h> WINE_DEFAULT_DEBUG_CHANNEL( structquery ); +extern HRESULT queryparser_create( REFIID iid, void **out ); + +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 +85,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 +116,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 +136,8 @@ static HRESULT factory_create( REFIID iid, void **obj ) HRESULT DllGetClassObject( REFCLSID clsid, REFIID iid, void **out ) { + SIZE_T i; + TRACE( "(%s, %, %p)\n", debugstr_guid( clsid ), debugstr_guid( iid ), out ); if (!clsid || !iid || !out) @@ -122,8 +145,11 @@ HRESULT 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/queryparser.c b/dlls/structuredquery/queryparser.c new file mode 100644 index 00000000000..c522a209863 --- /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" ); + 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 0e8c7cb7fbe..0fa71c8b75b 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) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6788
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=149531 Your paranoid android. === build (build log) === ../wine/dlls/structuredquery/main.c:21: error: private.h: No such file or directory config.status: error: could not create Makefile Task: The exe32 Wine build failed === debian11 (build log) === ../wine/dlls/structuredquery/main.c:21: error: private.h: No such file or directory config.status: error: could not create Makefile Task: The win32 Wine build failed === debian11b (build log) === ../wine/dlls/structuredquery/main.c:21: error: private.h: No such file or directory config.status: error: could not create Makefile Task: The wow64 Wine build failed
participants (3)
-
Marvin -
Vibhav Pant -
Vibhav Pant (@vibhavp)