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.
-- v4: dlls/structuredquery: Add stubs for QueryParser.
From: Vibhav Pant vibhavp@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); +};
From: Vibhav Pant vibhavp@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..72763fd18de --- /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, %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()
From: Vibhav Pant vibhavp@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(); +}
From: Vibhav Pant vibhavp@gmail.com
--- dlls/structuredquery/Makefile.in | 1 + dlls/structuredquery/main.c | 40 +++++-- dlls/structuredquery/private.h | 24 +++++ dlls/structuredquery/queryparser.c | 167 +++++++++++++++++++++++++++++ dlls/structuredquery/tests/query.c | 2 +- 5 files changed, 226 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 72763fd18de..0035c3e14be 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, %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/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..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) {
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=149532
Your paranoid android.
=== debian11 (build log) ===
../wine/dlls/structuredquery/main.c:137:9: error: conflicting types for ‘DllGetClassObject’ Task: The win32 Wine build failed
=== debian11b (build log) ===
../wine/dlls/structuredquery/main.c:137:9: error: conflicting types for ‘DllGetClassObject’ Task: The wow32 Wine build failed