import "oaidl.idl"; import "ocidl.idl"; import "objidl.idl"; import "propidl.idl"; /* STRUCTURED QUERY Overview: The main purpose of Structured Query is to parse an input string that adheres to Advanced Query Syntax (AQS) or Natural Query Syntax (NQS) and produce a parse tree (known as a condition tree) from which a database or index can conveniently be queried. (Note that NQS includes AQS as a subset, and AQS incorporates plain keyword search as a special case.) AQS and NQS allow expressing basic queries over properties, such as whether the value of a string property contains a certain word or whether the value of a numeric property is greater than some constant value, optionally connected by AND, OR and NOT. The minimum preparation for parsing queries is to create an IQueryParser, and give it a schema binary and an LCID. The result is an IQuerySolution object, which encompasses all available information about the query: the query string, how it was tokenized, and a condition tree in the form of an ICondition. The schema binary contains a representation of the application schema (basically what properties there are to query over and some information about them such as types) and a mapping from words and phrases to these properties. One can use a trivial schema, which enables the AND, OR and NOT of primitive queries, but the primitive queries can then not be over any specific properties. An IQueryParser holds a very small state between queries, basically a loaded schema which typically requires 100-150KB of memory. However, it also holds a reference to some word breaker object, which may have a substantially larger state. Query times are typically under 1ms. Expected scenarios: 1. Wordwheeling -- The application invokes IQueryParser::Parse for each character typed and uses the resulting ICondition to create a query which is run to update a set of results to reflect the current input string. Typically, the application would turn on the "automatic wildcard" option so that (partial) words typed will match contents that begin with these words. 2. Type query, press enter -- As above but the user has to actively state when to actually processa query (such as hitting Enter or clicking a button). An application may still choose to use "automatic wildcard" but the benefits are less clear. 3. "Query builder" -- a. Input string -> query tree Pass a query string from the user to IQueryParser::Parse and use the resulting condition tree to render a graphical representation of the query. If this graphical representation is not editable, it serves simply as an explanation to the user how the input string was interpreted. If is it editable, one may think of the input string as a way or priming the query builder. b. Just a query tree ICondition is useful on its own even if not parsed from AQS or NQS strings. An IConditionFactory object can be created to build condition trees (and every IQuerySolution is also an IConditionFactory). c. Semantic canvas (two way editing) This is like alternative a above but not only is the graphical representation editable, whenever it is edited, the query string is updated to reflect the new query. Thus, whenever the query string or the graphical query is edited, the other is updated. API conventions: Any method will return E_INVALIDARG if some input argument is NULL, unless explicitly permitted. Any method will return E_POINTER if some output or input/output argument is NULL, unless explicitly permitted. For any output argument that inherits from IUnknown, the caller must eventually free it using IUnknown::Release. For any output argument of type LPWSTR, the caller must eventually free it using CoTaskMemFree. For any output argument of type PROPVARIANT, it is expected to be uninitialized before the call and after a successful return, the caller must eventually clear it using PropVariantClear. */ interface ICondition; interface IQuerySolution; interface IConditionGenerator; interface ISchemaProvider; interface IEntity; interface INamedEntity; interface ITokenCollection; interface INamedEntityCollector; interface IRichChunk; interface ISchemaLocalizerSupport; // --------------------------------- // Condition types // --------------------------------- typedef [v1_enum] enum tagCONDITION_TYPE { CT_AND_CONDITION, // and of subterms CT_OR_CONDITION, // or of subterms CT_NOT_CONDITION, // a single subterm CT_LEAF_CONDITION, // no subterms, field, value expression } CONDITION_TYPE; // Prefix CT // --------------------------------- // Operations // --------------------------------- typedef [v1_enum] enum tagCONDITION_OPERATION { COP_IMPLICIT, COP_EQUAL, COP_NOTEQUAL, COP_LESSTHAN, COP_GREATERTHAN, COP_LESSTHANOREQUAL, COP_GREATERTHANOREQUAL, COP_VALUE_STARTSWITH, // LIKE FOO% COP_VALUE_ENDSWITH, // LIKE %FOO COP_VALUE_CONTAINS, // LIKE %FOO% COP_VALUE_NOTCONTAINS, // NOT LIKE %FOO% COP_DOSWILDCARDS, // "DOS wildcards" and the like COP_WORD_EQUAL, // Contains a word/phrase somewhere. COP_WORD_STARTSWITH, // Contains a word/phrase beginning with this COP_APPLICATION_SPECIFIC, // Application specific, presumably uses the Value. } CONDITION_OPERATION; // Prefix COP // ----------------------------------------------- // Query Parser options // ----------------------------------------------- typedef [v1_enum] enum tagSTRUCTURED_QUERY_SINGLE_OPTION { SQSO_SCHEMA, // The value should be VT_LPWSTR and the path to a file containing a schema binary. // In the future, VT_EMPTY may load a default schema that only defines the elements of // AQS and NQS but no properties. Presently that returns E_NOTIMPL. SQSO_LOCALE_WORD_BREAKING, // The value must be a VT_UI4 that is an LCID. It is an error not to set this option before // calling Parse. SQSO_WORD_BREAKER, // When setting this option, the value should be VT_EMPTY for using the default // word breaker for the chosen locale, or a VT_UNKNOWN with an object supporting // the IWordBreaker interface. Retrieving the option always returns // a VT_UNKNOWN with an object supporting the IWordBreaker interface, unless there // is no default word breaker for the chosen locale, in which case VT_EMPTY // will be returned. SQSO_NATURAL_SYNTAX, // The value should be VT_EMPTY or VT_BOOL with VARIANT_TRUE to allow natural query // syntax (the default) or VT_BOOL with VARIANT_FALSE to allow only advanced query syntax. // Retrieving the option always returns a VT_BOOL. SQSO_AUTOMATIC_WILDCARD, // The value should be VT_BOOL with VARIANT_TRUE to generate query expressions // as if each word in the query had a star appended to it (unless followed by punctuation // other than a parenthesis), or VT_EMPTY or VT_BOOL with VARIANT_FALSE to // use the words as they are (the default). A word-wheeling application // will generally want to set this option to true. // Retrieving the option always returns a VT_BOOL. SQSO_TRACE_LEVEL, // Reserved. The value should be VT_EMPTY (the default) or VT_I4. // Retrieving the option always returns a VT_I4. SQSO_LANGUAGE_KEYWORDS, // The value must be a VT_UI4 that is a LANGID. It defaults to the default user UI language. } STRUCTURED_QUERY_SINGLE_OPTION; // Prefix SQSO typedef [v1_enum] enum tagSTRUCTURED_QUERY_MULTIOPTION { SQMO_VIRTUAL_PROPERTY, // The key should be property name P. The value should be a // VT_UNKNOWN with an IEnumVARIANT which has two values: a VT_BSTR that is another // property name Q and a VT_I4 that is a CONDITION_OPERATION op. A predicate with // property name P, some operation and a value V will then be replaced by a predicate // with property name Q, operation op and value V before further processing happens. SQMO_DEFAULT_PROPERTY, // The key should be a value type name V. The value should be a // VT_LPWSTR with a property name P. A predicate with no property name and a value of type // V (or any subtype of V) will then use property P. SQMO_GENERATOR_FOR_TYPE, // The key should be a value type name V. The value should be a // VT_UNKNOWN with a IConditionGenerator G. The GenerateForLeaf method of // G will then be applied to any predicate with value type V and if it returns a query // expression, that will be used. If it returns NULL, normal processing will be used // instead. } STRUCTURED_QUERY_MULTIOPTION; // prefix SQMO // ------------------------------------------ // Parse error information // ------------------------------------------ typedef [v1_enum] enum tagSTRUCTURED_QUERY_PARSE_ERROR { SQPE_NONE, SQPE_EXTRA_OPENING_PARENTHESIS, // A spurious ( SQPE_EXTRA_CLOSING_PARENTHESIS, // A spurious ) SQPE_IGNORED_MODIFIER, // A spurious NOT, <, >=, etc. SQPE_IGNORED_CONNECTOR, // A spurious AND or OR. SQPE_IGNORED_KEYWORD, // A spurious property. SQPE_UNHANDLED, // Something else. } STRUCTURED_QUERY_PARSE_ERROR; // prefix SQPE // ------------------------------------------ // Resolution options // ------------------------------------------ [v1_enum] enum tagSTRUCTURED_QUERY_RESOLVE_OPTION { SQRO_DONT_RESOLVE_DATETIME = 0x00000001, SQRO_ALWAYS_ONE_INTERVAL = 0x00000002, SQRO_DONT_SIMPLIFY_CONDITION_TREES = 0x00000004, SQRO_DONT_MAP_RELATIONS = 0x00000008, SQRO_DONT_RESOLVE_RANGES = 0x00000010, SQRO_DONT_REMOVE_UNRESTRICTED_KEYWORDS = 0x00000020, // An unrestricted keyword is a keyword that is not associated with a value to make a real condition. SQRO_DONT_SPLIT_WORDS = 0x00000040, // If this flag is set, groups of words that are not separated by whitespace // will be kept together and it is up to the consumer of the parse result to do any // additional separation. (Note that it is possible through this interface to obtain // how the input string was broken into words as well as the word breaker used.) // If this flag is not set, then each word will end up in a separate condition tree node. SQRO_IGNORE_PHRASE_ORDER = 0x00000080, // If this flag is set, a full-text query for a phrase will disregard the order of the words in the phrase. // In this case, the query from:"foo bar" will behave like from:(foo bar). }; // prefix SQRO typedef int STRUCTURED_QUERY_RESOLVE_OPTION; // ------------------------------------------ // An interval limit // ------------------------------------------ typedef [v1_enum] enum tagINTERVAL_LIMIT_KIND { ILK_EXPLICIT_INCLUDED, ILK_EXPLICIT_EXCLUDED, ILK_NEGATIVE_INFINITY, ILK_POSITIVE_INFINITY, } INTERVAL_LIMIT_KIND; // prefix ILK // ----------------------------------------------- // Query Parser Manager options // ----------------------------------------------- typedef [v1_enum] enum tagQUERY_PARSER_MANAGER_OPTION { QPMO_SCHEMA_BINARY_NAME, // The value must be VT_LPWSTR and be the name of the file containing a schema binary. // The default value depends on the catalog. For the SystemIndex catalog it is // "StructuredQuerySchema.bin". QPMO_PRELOCALIZED_SCHEMA_BINARY_PATH, // The value must be either a VT_BOOL or a VT_LPWSTR. If it is a VT_BOOL and the value // IS VARIANT_FALSE, a prelocalized schema binary path will not be used. If it is VARIANT_TRUE, // a default prelocalized schema binary path will be used, depending on the catalog. // If it is a VT_LPWSTR, the value should be a full folder part (though an LCID may be // appended to it according to the QPMO_APPEND_LCID_TO_LOCALIZED_PATH setting). // The default is VT_BOOL with VARIANT_TRUE; the actual path is // "%COMMONAPPDATA%\Microsoft\Windows" (note though that environment variables in the // given string will not be expanded). QPMO_UNLOCALIZED_SCHEMA_BINARY_PATH, // The value must be VT_LPWSTR and be the full path of a folder in which an unlocalized // schema binary resides and can be read. // The default value is the expansion of "%SYSTEMROOT%\System32" (note though // that environment variables in the given string will not be expanded). QPMO_LOCALIZED_SCHEMA_BINARY_PATH, // The value must be VT_LPWSTR and be the full path of a folder in which a localized // schema binary can be read, or written as necessary. // The default value is "%LOCALAPPDATA%\Microsoft\Windows" (note though // that environment variables in the given string will not be expanded). QPMO_APPEND_LCID_TO_LOCALIZED_PATH, // The value must be a VT_BOOL. If it is VARIANT_TRUE, then the path(s) for localized // binary will have "\" appended to it, e.g., "\1042". The default is VARIANT_TRUE. QPMO_LOCALIZER_SUPPORT, // The value must be a VT_UNKNOWN with an object supporting ISchemaLocalizerSupport. // It will be used instead of the default localizer support object which expects "global" // mnemonics to be on the form "@foo.dll,-12345" and will return the resourec with ID 12345 // of the binary foo.dll. } QUERY_PARSER_MANAGER_OPTION; // Prefix QPMO // ----------------------------------------------- // IQueryParser -- parse an input string to a query structure // ----------------------------------------------- [ object, uuid(2EBDEE67-3505-43f8-9946-EA44ABC8E5B0), pointer_default(unique) ] interface IQueryParser : IUnknown { // Parse parses an input string, producing a query solution. // pCustomProperties should be an enumeration of IRichChunk objects, one for each custom property // the application has recognized. pCustomProperties may be NULL, equivalent to an empty enumeration. // For each IRichChunk, the position information identifies the character span of the custom property, // the string value should be the name of an actual property, and the PROPVARIANT is completely ignored. HRESULT Parse([in] LPCWSTR pszInputString, [in] IEnumUnknown* pCustomProperties, [out, retval] IQuerySolution** ppSolution); // Set a single option. See STRUCTURED_QUERY_SINGLE_OPTION above. HRESULT SetOption([in] STRUCTURED_QUERY_SINGLE_OPTION option, [in] PROPVARIANT const* pOptionValue); // Get a single option. HRESULT GetOption([in] STRUCTURED_QUERY_SINGLE_OPTION option, [out, retval] PROPVARIANT* pOptionValue); // Set a multi option. See STRUCTURED_QUERY_MULTIOPTION above. HRESULT SetMultiOption([in] STRUCTURED_QUERY_MULTIOPTION option, [in] LPCWSTR pszOptionKey, [in] PROPVARIANT const* pOptionValue); // Get a schema provider for browsing the currently loaded schema. HRESULT GetSchemaProvider([out, retval] ISchemaProvider** ppSchemaProvider); // Restate a condition as a query string. If SQSO_NATURAL_SYNTAX is true, then the query string will use natural syntax. // If fUseEnglish is TRUE, then the query string will be in English; otherwise it will be in the current language. HRESULT RestateToString([in] ICondition* pCondition, [in] BOOL fUseEnglish, [out] LPWSTR* ppszQueryString); // Parse a condition for a given property. It can be anything that would go after 'PROPERTY:' in an AQS expession. HRESULT ParsePropertyValue([in] LPCWSTR pszPropertyName, [in] LPCWSTR pszInputString, [out, retval] IQuerySolution** ppSolution); // Restate a condition for a given property. If the condition contains a leaf with any other property name, or no property name at all, // E_INVALIDARG will be returned. HRESULT RestatePropertyValueToString([in] ICondition* pCondition, [in] BOOL fUseEnglish, [out] LPWSTR* ppszPropertyName, [out] LPWSTR* ppszQueryString); }; // ---------------------------------------------------------------------------------- // IQuerySolution -- encapsulates all information about the interpretation of a query // ---------------------------------------------------------------------------------- [ object, uuid(D6EBC66B-8921-4193-AFDD-A1789FB7FF57), pointer_default(unique) ] interface IQuerySolution : IConditionFactory { // Retrieve the condition tree and the "main type" of the solution. // ppQueryNode and ppMainType may be NULL. [local] HRESULT GetQuery([out, annotation("__out_opt")] ICondition** ppQueryNode, [out, annotation("__out_opt")] IEntity** ppMainType); // Identify parts of the input string not accounted for. // Each parse error is represented by an IRichChunk where the position information // reflect token counts, the string is NULL and the value is a VT_I4 // where lVal is from the ParseErrorType enumeration. The valid // values for riid are __uuidof(IEnumUnknown) and __uuidof(IEnumVARIANT). HRESULT GetErrors([in] REFIID riid, [out, retval, iid_is(riid)] void** ppParseErrors); // Report the query string, how it was tokenized and what LCID and word breaker were used. // ppszInputString, ppTokens, pLocale and ppWordBreaker may be NULL. [local] HRESULT GetLexicalData([out, annotation("__deref_opt_out")] LPWSTR* ppszInputString, [out, annotation("__out_opt")] ITokenCollection** ppTokens, [out, annotation("__out_opt")] LCID* pLocale, [out, annotation("__out_opt")] IUnknown** ppWordBreaker); } // ---------------------------------------------------------------------------------- // IConditionFactory -- interface for creating conditions // ---------------------------------------------------------------------------------- [ object, uuid(A5EFE073-B16F-474f-9F3E-9F8B497A3E08), pointer_default(unique) ] interface IConditionFactory : IUnknown { // Create a condition that is a negation of another condition. // If simplify is VARIANT_TRUE, then the result will be simplified if possible (for example, if pSubCondition is a // negation condition as well with a subcondition C, then *ppResultQuery will be set to C), and thus will not // necessarily be a negation condition. In a query builder scenario, simplify should typically be VARIANT_FALSE. HRESULT MakeNot([in] ICondition* pSubCondition, [in] BOOL simplify, [out, retval] ICondition** ppResultQuery); // Create a query node that is a conjunction (AND) or a disjunction (OR) of a collection of subconditions. // nodeType must be CT_AND_CONDITION or CT_ORD_CONDITION. // pSubConditions should be an enumeration of ICondition or NULL which is equivalent to an empty enumeration. // An AND node with no subconditions is trivially true, while an OR node with no subconditions is trivially false. // If simplify is VARIANT_TRUE, then the result will be logically simplified, if possible, and thus need not be of // the specified kind. HRESULT MakeAndOr([in] CONDITION_TYPE nodeType, [in] IEnumUnknown* pSubConditions, [in] BOOL simplify, [out, retval] ICondition** ppResultQuery); // Create a leaf query node. // pszPropertyName should be the name of a property to be compared, or NULL for no particular property. // pszValueType should be the name of a semantic type, or NULL for a plain string keyword. // Each of pPropertyNameTerm, pOperationTerm and pValueTerm should be an IRichChunk or NULL. The position information // of each IRichChunk should identify the tokens that contributed the property/operation/value, the string value // should be the corresponding part of the input string, and the PROPVARIANT is ignored. // If expand is VARIANT_TRUE and pszPropertyName identifies a virtual property, the result is a disjunction of // leaf conditions, each of which corresponds to one expansion of the virtual property. // (A virtual property is one that has one or more metadata with key "mapsToRelation" and value some property name.) HRESULT MakeLeaf([in, unique] LPCWSTR pszPropertyName, [in] CONDITION_OPERATION op, [in, unique] LPCWSTR pszValueType, [in] PROPVARIANT const* pValue, [in] IRichChunk* pPropertyNameTerm, [in] IRichChunk* pOperationTerm, [in] IRichChunk* pValueTerm, [in] BOOL expand, [out, retval] ICondition** ppResultQuery); // Structured Query supports relative date/time expressions, which can remain unresolved until they are applied to some // reference time. In a leaf condition with semantic type DateTime, the value can either be a VT_FILETIME or a VT_LPWSTR. // The former is an absolute date/time; already resolved. The latter is a string representation of a relative date/time // expression. // The ResolveDateTime method takes a condition tree and a reference time and produces a condition tree that is identical // to the given one except that any leaf condition with an unresolved date/time has been replaced with a fully resolved condition. // The input condition tree is not modified in any way. The output condition may share parts of the input condition that contained // no leaf nodes with unresolved date/time. // The reference time should be a local time but the resolved times in the resulting query expression will be in UTC. // Note that resolving a leaf node will often produce a non-leaf node. // For an application that wishes maximal uniformity of the resulting condition tree, the fAlwaysOneInterval argument // should be VARIANT_TRUE. In this case, a leaf condition with an unresolved date/time will always be one of: // 1. A leaf node with a COP_GREATERTHANOREQUAL operation. // 2. A leaf node with a COP_LESSTHAN operation. // 3. An AND node with two leaf nodes, one with a COP_GREATERTHANOREQUAL operation and one with a COP_LESSTHAN operation. // An always false condition will then follow case 3 above with two incompatible leaves. // When fAlwaysOneInterval is true, date/time resolution will never "ambiguate" a date/time. [local] HRESULT Resolve([in, annotation("__in")] ICondition* pConditionTree, [in, annotation("__in")] STRUCTURED_QUERY_RESOLVE_OPTION sqro, [in, ref, annotation("__in_opt")] SYSTEMTIME const* pstReferenceTime, [out, retval, annotation("__out")] ICondition** ppResolvedConditionTree); } // ----------------------------------------------- // ICondition -- a node in a condition tree // ----------------------------------------------- [ object, uuid(0FC988D4-C935-4b97-A973-46282EA175C8), pointer_default(unique) ] interface ICondition : IPersistStream { // For any node, return what kind of node it is. HRESULT GetConditionType([out, retval] CONDITION_TYPE* pNodeType); // riid must be __uuidof(IEnumUnknown) or __uuidof(IEnumVARIANT), or in the case of a negation node __uuidof(ICondition). // If this is a leaf node, E_FAIL will be returned. // If this is a negation node, then if riid is __uuidof(ICondition), *ppv will be set to a single ICondition, otherwise an enumeration of one. // If this is a conjunction or a disjunction, *ppv will be set to an enumeration of the subconditions. HRESULT GetSubConditions([in] REFIID riid, [out, retval, iid_is(riid)] void** ppv); // If this is not a leaf node, E_FAIL will be returned. // Retrieve the property name, operation and value from the leaf node. // Any one of ppszPropertyName, pOperation and pValue may be NULL. [local] HRESULT GetComparisonInfo([out, annotation("__deref_opt_out")] LPWSTR *ppszPropertyName, [out, annotation("__out_opt")] CONDITION_OPERATION *pOperation, [out, annotation("__out_opt")] PROPVARIANT *pValue); // If this is not a leaf node, E_FAIL will be returned. // *pValueTypeName will be set to the semantic type of the value, or to NULL if this is not meaningful. HRESULT GetValueType([out, retval] LPWSTR* ppszValueTypeName); // If this is not a leaf node, E_FAIL will be returned. // If the value of the leaf node is VT_EMPTY, *ppszNormalization will be set to an empty string. // If the value is a string (VT_LPWSTR, VT_BSTR or VT_LPSTR), then *ppszNormalization will be set to a // character-normalized form of the value. // Otherwise, *ppszNormalization will be set to some (character-normalized) string representation of the value. HRESULT GetValueNormalization([out, retval] LPWSTR* ppszNormalization); // Return information about what parts of the input produced the property, the operation and the value. // Any one of ppPropertyTerm, ppOperationTerm and ppValueTerm may be NULL. // For a leaf node returned by the parser, the position information of each IRichChunk identifies the tokens that // contributed the property/operation/value, the string value is the corresponding part of the input string, and // the PROPVARIANT is VT_EMPTY. [local] HRESULT GetInputTerms([out, annotation("__out_opt")] IRichChunk** ppPropertyTerm, [out, annotation("__out_opt")] IRichChunk** ppOperationTerm, [out, annotation("__out_opt")] IRichChunk** ppValueTerm); // Make a deep copy of this ICondition. HRESULT Clone([out, retval] ICondition** ppc); }; // ----------------------------------------------- // IConditionGenerator -- handle named entities and special conditions // ----------------------------------------------- // Typically, an IConditionGenerator recognizes a certain type of named entities and generates // condition trees for them. An application makes an IConditionGenerator for a type known to // the query parser by invoking IQueryParser::SetMultiOption with the name of the type and // the IConditionGenerator. The query parser has preloaded condition generators for the base // schema types Boolean, Integer, FloatingPoint, DateTime and FilePath. // Consider an IConditionGenerator G for some semantic type T. // The query parser will call the Initialize method of G as soon as possible (if a schema has // been loaded) and again any time a new schema has been loaded (so the named entity // recognizer should reset any sort of state each time Initialize is called). // The query parser will call the RecognizeNamedEntities method of G for each query and expects that // any recognized named entities for type T are added to a named entity collection. // The query parser will call the GenerateForLeaf method of G any time it is about to generate a leaf // condition with a value of semantic type T. [ object, uuid(92D2CC58-4386-45a3-B98C-7E0CE64A4117), pointer_default(unique) ] interface IConditionGenerator : IUnknown { // The condition generator is expected to reset any state and to retrieve anew any schema // information that it uses. HRESULT Initialize([in] ISchemaProvider* pSchemaProvider); // Given an input string, the current LCID and a tokenization of the input string, the condition generator // should identify any named entities it knows of in that input string and add each one to the named // entity collection. Note that the value of the named entity must be expressed as a string. That string value // will come back to the IConditionGenerator in a call to GenerateForLeaf. HRESULT RecognizeNamedEntities([in] LPCWSTR pszInputString, [in] LCID lcid, [in] ITokenCollection* pTokenCollection, [in,out] INamedEntityCollector* pNamedEntities); // For what would otherwise become a leaf query expression, generate an arbitrary query expression. // pConditionFactory should be used to create the necessary nodes. pszPropertyName is either a property name or NULL. // pszValueType is a semantic type. pszValue is a string as produced earlier by RecognizeNamedEntities. // If pszValue2 is not NULL, then this is actually a range of values beginning with that represented by pszValue // and ending with that represented by pszValue2. // Each of pPropertyNameTerm, pOperationTerm and pValueTerm is either NULL or an IRichChunk with information about // what part of an input string produced the property name, operation or value (cf IConditionFacrory::MakeLeaf and // ICondition::GetInputTerms). If automaticWildcard is VARIANT_TRUE, the generated condition should be one that // matches results that begin with the given value, if meaningful. // If this method returns S_FALSE, it means that it did not generate a condition and the query parser must produce // one in some other way. If it returns S_OK, then there are two outputs that should be set on exit. // If *pNoStringQuery is set to VARIANT_TRUE, then *ppQueryExpression will be the whole condition tree // for this part. It *pNoStringQuery is set to VARIANT_FALSE, then a disjunction will be formed of *ppQueryExpression // and a node that simply looks for the covered part of the input as a string. HRESULT GenerateForLeaf([in] IConditionFactory* pConditionFactory, [in, unique] LPCWSTR pszPropertyName, [in] CONDITION_OPERATION op, [in, unique] LPCWSTR pszValueType, [in] LPCWSTR pszValue, [in, unique] LPCWSTR pszValue2, [in] IRichChunk* pPropertyNameTerm, [in] IRichChunk* pOperationTerm, [in] IRichChunk* pValueTerm, [in] BOOL automaticWildcard, [out] BOOL* pNoStringQuery, [out, retval] ICondition** ppQueryExpression); // Given a semantic type and a value, this method attempts to produce a phrase that when recognized by this // IConditionGenerator would produce the given value. On success S_OK will be returned and *ppszPhrase will // be assigned the phrase, to be freed by the caller (CoTaskMemFree). If no such phrase can be produced, S_FALSE // will be returned and NULL assigned to *ppszPhrase. [local] HRESULT DefaultPhrase([in, unique] LPCWSTR pszValueType, [in] PROPVARIANT const* ppropvar, [in] BOOL fUseEnglish, [out, annotation("__deref_opt_out"), retval] LPWSTR* ppszPhrase); } // --------------------------------------------------------------------------------------------- // IRichChunk -- a range with an associated string and PROPVARIANT value // --------------------------------------------------------------------------------------------- // IRichChunk is a utility interface, used for many different purposes in the Structured Query API. // For each method that has an IRichChunk as input or output, see how it is to be interpreted. [ object, uuid(4FDEF69C-DBC9-454e-9910-B34F3C64B510), pointer_default(unique) ] interface IRichChunk : IUnknown { // The position *pFirstPos is zero-based. // Any one of pFirstPos, pLength, ppsz and pValue may be NULL. [local] HRESULT GetData([out, annotation("__out_opt")] ULONG* pFirstPos, [out, annotation("__out_opt")] ULONG* pLength, [out, annotation("__deref_opt_out")] LPWSTR* ppsz, [out, annotation("__out_opt")] PROPVARIANT* pValue); } // --------------------------------------------------------------------------------------------- // IInterval -- a closed or open interval // --------------------------------------------------------------------------------------------- [ object, uuid(6BF0A714-3C18-430b-8B5D-83B1C234D3DB), pointer_default(unique) ] interface IInterval : IUnknown { // If an INTERVAL_LIMIT_KIND is ILK_EXPLICIT_INCLUDED or ILK_EXPLICIT_EXCLUDED, then the corresponding PROPVARIANT will be set to an actual value that is the limit. // If an INTERVAL_LIMIT_KIND is ILK_NEGATIVE_INFINITY or ILK_POSITIVE_INFINITY, then the corresponding PROPVARIANT will be set to VT_EMPTY. HRESULT GetLimits([out] INTERVAL_LIMIT_KIND* pilkLower, [out] PROPVARIANT* ppropvarLower, [out] INTERVAL_LIMIT_KIND* pilkUpper, [out] PROPVARIANT* ppropvarUpper); } // --------------------------------------------------------------------------------------------- // IMetaData -- a pair of strings, to be thought of as a key and a value // --------------------------------------------------------------------------------------------- [ helpstring("Key/Value pair of strings"), object, uuid(780102B0-C43B-4876-BC7B-5E9BA5C88794), pointer_default(unique) ] interface IMetaData : IUnknown { // Return a key/value pair. [local] HRESULT GetData([out, annotation("__deref_opt_out")] LPWSTR* ppszKey, [out, annotation("__deref_opt_out")] LPWSTR* ppszValue); } // ---------------------------------------------------------------------------------------------- // IEntity -- a type in the schema // ---------------------------------------------------------------------------------------------- interface IRelationship; [ helpstring("Representing a schema type"), uuid(24264891-E80B-4fd3-B7CE-4FF2FAE8931F), object, pointer_default(unique) ] interface IEntity : IUnknown { // Return the name of the entity. [local] HRESULT Name([out, annotation("__deref_opt_out"), retval] LPWSTR* ppszName); // If the entity has no base (parent) entity, S_FALSE is returned (and *pBaseEntity is set to NULL), // otherwise *pBaseEntity is set to the base entity. HRESULT Base([out, retval] IEntity** pBaseEntity); // Return an enumeration of IRelationship, one for each relationship going out from this entity. // riid must be __uuidof(IEnumUnknown) or __uuidof(IEnumVARIANT). HRESULT Relationships([in] REFIID riid, [out, retval, iid_is(riid)] void** pRelationships); // If this entity has no outgoing relationship with the given name, S_FALSE is returned (and *pRelationship is set to NULL), // otherwise *pRelationship is set to the corresponding IRelationship. HRESULT GetRelationship([in] LPCWSTR pszRelationName, [out, retval] IRelationship** pRelationship); // Return an enumeration of IMetaData for this entity. There may be multiple pairs with the same key (or the same value). // riid must be __uuidof(IEnumUnknown) or __uuidof(IEnumVARIANT). HRESULT MetaData([in] REFIID riid, [out, retval, iid_is(riid)] void** pMetaData); // Return an enumeration of INamedEntity, one for each known named entity of this type. // riid must be __uuidof(IEnumUnknown) or __uuidof(IEnumVARIANT). HRESULT NamedEntities([in] REFIID riid, [out, retval, iid_is(riid)] void** pNamedEntities); // If this entity has no known named entity with the given value, S_FALSE is returned (and *pNamedEntity is set to NULL), // otherwise *pNamedEntity is set to the corresponding INamedEntity. HRESULT GetNamedEntity([in] LPCWSTR pszValue, [out, retval] INamedEntity** ppNamedEntity); // Return S_OK and a default phrase to use for this entity in restatements, if there is one, // otherwise return S_FALSE. [local] HRESULT DefaultPhrase([out, annotation("__deref_opt_out"), retval] LPWSTR* ppszPhrase); }; // ---------------------------------------------------------------------------------------------- // IRelationship -- a property in the schema // ---------------------------------------------------------------------------------------------- [ helpstring("Representing a schema property"), uuid(2769280B-5108-498c-9C7F-A51239B63147), object, pointer_default(unique) ] interface IRelationship : IUnknown { // Return the name of the relationship. [local] HRESULT Name([out, annotation("__deref_opt_out"), retval] LPWSTR* ppszName); // A relationship is not considered "real" if its source entity derives from an entity // which has a relationship with the same name. The purpose of such a "shadow" relationship // is to store metadata specific to the inherited relationship. HRESULT IsReal([out, retval] BOOL* pIsReal); // The destination of a relationshipo corresponds to the type of a property. // If the relationship is not "real", S_FALSE will be returned and *pDestinationEntity set to NULL. HRESULT Destination([out, retval] IEntity** pDestinationEntity); // Return an enumeration of IMetaData for this relationship. There may be multiple pairs with the same key (or the same value). // riid must be __uuidof(IEnumUnknown) or __uuidof(IEnumVARIANT). HRESULT MetaData([in] REFIID riid, [out, retval, iid_is(riid)] void** pMetaData); // Return S_OK and a default phrase to use for this relationship in restatements, if there is one, // otherwise return S_FALSE. [local] HRESULT DefaultPhrase([out, annotation("__deref_opt_out"), retval] LPWSTR* ppszPhrase); }; // --------------------------------------------------------------------------------------------- // INamedEntity -- a known value of some entity type // --------------------------------------------------------------------------------------------- [ helpstring("Representing a known value of some type"), object, uuid(ABDBD0B1-7D54-49fb-AB5C-BFF4130004CD), pointer_default(unique) ] interface INamedEntity : IUnknown { // Return the value of the named entity. HRESULT GetValue([out, retval] LPWSTR* ppszValue); // Return S_OK and a default phrase to use for this named entity in restatements, if there is one, // otherwise return S_FALSE. [local] HRESULT DefaultPhrase([out, annotation("__deref_opt_out"), retval] LPWSTR* ppszPhrase); } // ---------------------------------------------------------------------------------------------- // ISchemaProvider -- a repository of schema // ---------------------------------------------------------------------------------------------- [ helpstring("Browsable, localizable schema repository"), uuid(8CF89BCB-394C-49b2-AE28-A59DD4ED7F68), object, pointer_default(unique) ] interface ISchemaProvider : IUnknown { // Return an enumeration of IEntity, one for each entity in the schema. // riid must be __uuidof(IEnumUnknown) or __uuidof(IEnumVARIANT). HRESULT Entities([in] REFIID riid, [out, retval, iid_is(riid)] void** pEntities); // Get the root entity of the schema. HRESULT RootEntity([out, retval] IEntity** pRootEntity); // If there is no entity with the given name, S_FALSE is returned (and *pEntity is set to NULL), // otherwise *pEntity is set to the corresponding IEntity. HRESULT GetEntity([in] LPCWSTR pszEntityName, [out, retval] IEntity** pEntity); // Return an enumeration of global IMetaData for this schema. There may be multiple pairs with the same key (or the same value). // riid must be __uuidof(IEnumUnknown) or __uuidof(IEnumVARIANT). HRESULT MetaData([in] REFIID riid, [out, retval, iid_is(riid)] void** pMetaData); // Localize the (presumably global) currently loaded schema for a given locale. // pSchemaLocalizerSupport may be NULL, in which case each localized string will be obtained by calling SHLoadIndirectString. HRESULT Localize([in] LCID lcid, [in] ISchemaLocalizerSupport* pSchemaLocalizerSupport); // Save the current schema as a schema binary at a specified path. // Any existing file in that location will be overwritten. HRESULT SaveBinary([in] LPCWSTR pszSchemaBinaryPath); // If the token sequence beginning at position cTokensBegin in the given token collection denotes some (authored) named entity // of the specified (entity) type, then return the length of the shortest such token sequence in *pcTokensLength and the value of the // named entity in *ppszValue, and return S_OK. If there is no such token sequence, return S_FALSE. HRESULT LookupAuthoredNamedEntity([in] IEntity* pEntity, [in] LPCWSTR pszInputString, [in] ITokenCollection* pTokenCollection, [in] ULONG cTokensBegin, [out] ULONG* pcTokensLength, [out] LPWSTR* ppszValue); }; // ---------------------------------------------------------------------------------------------- // ITokenCollection -- the result of applying a word breaker // ---------------------------------------------------------------------------------------------- [ helpstring("Sequence of tokens"), uuid(22D8B4F2-F577-4adb-A335-C2AE88416FAB), object, pointer_default(unique) ] interface ITokenCollection : IUnknown { // Return the number of tokens in the collection. HRESULT NumberOfTokens(ULONG* pCount); // Return the zero-based first position and length of a certain token. Moreover, if there was // an overriding text for this token, *ppsz will be set to that text, otherwise *ppsz will be set to NULL. // Any one of pBegin, pLength and ppsz may be NULL. [local] HRESULT GetToken([in] ULONG i, [out, annotation("__out_opt")] ULONG* pBegin, [out, annotation("__out_opt")] ULONG* pLength, [out, annotation("__deref_opt_out")] LPWSTR* ppsz); }; // ---------------------------------------------------------------------------------------------- // INamedEntityCollector -- an accumulator of named entities // ---------------------------------------------------------------------------------------------- typedef [v1_enum] enum { NEC_LOW, // It could be this named entity but additional evidence advisable. NEC_MEDIUM, // It quite likely is this named entity; it is OK to use it. NEC_HIGH, // It almost certainly is this named entity; it should be ok to toss other possibilities. } NAMED_ENTITY_CERTAINTY; // prefix NEC [ helpstring("Accumulator for named entities"), uuid(AF2440F6-8AFC-47d0-9A7F-396A0ACFB43D), object, pointer_default(unique) ] interface INamedEntityCollector : IUnknown { // Add a single (potential) named entity. beginSpan and endSpan make up the overall token span, including any quotes. // beginActual and endActual make up the significant token span. It must be that beginSpan <= beginActual < endActual <= endSpan. // The named entity has a semantic type and some value, represented by a string (cf IConditionGenerator::RecognizeNamedEntities // and IConditionGenerator::GenerateForLeaf). // The given certainty will affect how aggressively this potential named entity is used in the solution. HRESULT Add([in] ULONG beginSpan, [in] ULONG endSpan, [in] ULONG beginActual, [in] ULONG endActual, [in] IEntity* pType, [in] LPCWSTR pszValue, [in] NAMED_ENTITY_CERTAINTY certainty); }; // ---------------------------------------------------------------------------------------------- // ISchemaLocalizationSupport -- an application-provided object to translate annotations // ---------------------------------------------------------------------------------------------- [ uuid(CA3FDCA2-BFBE-4eed-90D7-0CAEF0A1BDA1), object, pointer_default(unique) ] interface ISchemaLocalizerSupport : IUnknown { // Translate one annotation. It may just return the same string back, translate any string, // or only translate strings on a certain format. HRESULT Localize([in] LPCWSTR pszGlobalString, [out, retval] LPWSTR* ppszLocalString); } // ---------------------------------------------------------------------------------------------- // IQueryParserManager -- a helper API for creating and initializing query parsers for SearchAPI // ---------------------------------------------------------------------------------------------- [ uuid(A879E3C4-AF77-44fb-8F37-EBD1487CF920), object, pointer_default(unique) ] interface IQueryParserManager : IUnknown { // Create a query parser loaded with the schema for a certain catalog localize to a certain language, and initialized with // standard defaults. One valid value for riid is IID_IQueryParser. HRESULT CreateLoadedParser([in] LPCWSTR pszCatalog, [in] LANGID langidForKeywords, [in] REFIID riid, [out, retval, iid_is(riid)] void** ppQueryParser); // In addition to setting AQS/NQS and automatic wildcard for the given query parser, this sets up standard named entity handlers and // sets the keyboard locale as locale for word breaking. HRESULT InitializeOptions([in] BOOL fUnderstandNQS, [in] BOOL fAutoWildCard, [in] IQueryParser* pQueryParser); // Change one of the settings for the query parser manager, such as the name of the schema binary, or the location of the localized and unlocalized // schema binaries. By default, the settings point to the schema binaries used by Windows Shell. HRESULT SetOption([in] QUERY_PARSER_MANAGER_OPTION option, [in] PROPVARIANT const* pOptionValue); } [ uuid(1352FA67-2022-41df-9D6F-943A5EE97C9F), version(1.0) ] library StructuredQuery1 { // --------------------------------------------------------------------------------------------- // QueryParser -- our main coclass // --------------------------------------------------------------------------------------------- // Create an instance of this coclass to obtain a query parser. [ uuid(B72F8FD8-0FAB-4dd9-BDBF-245A6CE1485B) ] coclass QueryParser { [default] interface IQueryParser; }; // --------------------------------------------------------------------------------------------- // Our implementations of ICondition // --------------------------------------------------------------------------------------------- // These coclasses are not intended to be instantiated; they exist so that the implementation of // ICondition can support IPersistStream. [ uuid(8DE9C74C-605A-4acd-BEE3-2B222AA2D23D) ] coclass NegationCondition { [default] interface ICondition; }; [ uuid(116F8D13-101E-4fa5-84D4-FF8279381935) ] coclass CompoundCondition { [default] interface ICondition; }; [ uuid(52F15C89-5A17-48e1-BBCD-46A3F89C7CC2) ] coclass LeafCondition { [default] interface ICondition; }; // --------------------------------------------------------------------------------------------- // The light weight condition factory // --------------------------------------------------------------------------------------------- // Create an instance of this coclass to obtain a factory for condition tree nodes. [ uuid(E03E85B0-7BE3-4000-BA98-6C13DE9FA486) ] coclass ConditionFactory { [default] interface IConditionFactory; }; // --------------------------------------------------------------------------------------------- // The interval implementation // --------------------------------------------------------------------------------------------- [ uuid(D957171F-4BF9-4de2-BCD5-C70A7CA55836) ] coclass Interval { [default] interface IInterval; }; // --------------------------------------------------------------------------------------------- // QueryParserManager -- coclass for creating initialized query parsers // --------------------------------------------------------------------------------------------- // Create an instance of this coclass to obtain a query parser manager. [ uuid(5088B39A-29B4-4d9d-8245-4EE289222F66) ] coclass QueryParserManager { [default] interface IQueryParserManager; }; } /* --GUIDs-- // {1352FA67-2022-41df-9D6F-943A5EE97C9F} static const GUID <> = { 0x1352fa67, 0x2022, 0x41df, { 0x9d, 0x6f, 0x94, 0x3a, 0x5e, 0xe9, 0x7c, 0x9f } }; // {1352FA67-2022-41df-9D6F-943A5EE97C9F} DEFINE_GUID(<>, 0x1352fa67, 0x2022, 0x41df, 0x9d, 0x6f, 0x94, 0x3a, 0x5e, 0xe9, 0x7c, 0x9f); // {2EBDEE67-3505-43f8-9946-EA44ABC8E5B0} static const GUID <> = { 0x2ebdee67, 0x3505, 0x43f8, { 0x99, 0x46, 0xea, 0x44, 0xab, 0xc8, 0xe5, 0xb0 } }; // {2EBDEE67-3505-43f8-9946-EA44ABC8E5B0} DEFINE_GUID(<>, 0x2ebdee67, 0x3505, 0x43f8, 0x99, 0x46, 0xea, 0x44, 0xab, 0xc8, 0xe5, 0xb0); // {D6EBC66B-8921-4193-AFDD-A1789FB7FF57} static const GUID <> = { 0xd6ebc66b, 0x8921, 0x4193, { 0xaf, 0xdd, 0xa1, 0x78, 0x9f, 0xb7, 0xff, 0x57 } }; // {D6EBC66B-8921-4193-AFDD-A1789FB7FF57} DEFINE_GUID(<>, 0xd6ebc66b, 0x8921, 0x4193, 0xaf, 0xdd, 0xa1, 0x78, 0x9f, 0xb7, 0xff, 0x57); // {A5EFE073-B16F-474f-9F3E-9F8B497A3E08} static const GUID <> = { 0xa5efe073, 0xb16f, 0x474f, { 0x9f, 0x3e, 0x9f, 0x8b, 0x49, 0x7a, 0x3e, 0x8 } }; // {A5EFE073-B16F-474f-9F3E-9F8B497A3E08} DEFINE_GUID(<>, 0xa5efe073, 0xb16f, 0x474f, 0x9f, 0x3e, 0x9f, 0x8b, 0x49, 0x7a, 0x3e, 0x8); // {0FC988D4-C935-4b97-A973-46282EA175C8} static const GUID <> = { 0xfc988d4, 0xc935, 0x4b97, { 0xa9, 0x73, 0x46, 0x28, 0x2e, 0xa1, 0x75, 0xc8 } }; // {0FC988D4-C935-4b97-A973-46282EA175C8} DEFINE_GUID(<>, 0xfc988d4, 0xc935, 0x4b97, 0xa9, 0x73, 0x46, 0x28, 0x2e, 0xa1, 0x75, 0xc8); // {92D2CC58-4386-45a3-B98C-7E0CE64A4117} static const GUID <> = { 0x92d2cc58, 0x4386, 0x45a3, { 0xb9, 0x8c, 0x7e, 0xc, 0xe6, 0x4a, 0x41, 0x17 } }; // {92D2CC58-4386-45a3-B98C-7E0CE64A4117} DEFINE_GUID(<>, 0x92d2cc58, 0x4386, 0x45a3, 0xb9, 0x8c, 0x7e, 0xc, 0xe6, 0x4a, 0x41, 0x17); // {4FDEF69C-DBC9-454e-9910-B34F3C64B510} static const GUID <> = { 0x4fdef69c, 0xdbc9, 0x454e, { 0x99, 0x10, 0xb3, 0x4f, 0x3c, 0x64, 0xb5, 0x10 } }; // {4FDEF69C-DBC9-454e-9910-B34F3C64B510} DEFINE_GUID(<>, 0x4fdef69c, 0xdbc9, 0x454e, 0x99, 0x10, 0xb3, 0x4f, 0x3c, 0x64, 0xb5, 0x10); // {6BF0A714-3C18-430b-8B5D-83B1C234D3DB} static const GUID <> = { 0x6bf0a714, 0x3c18, 0x430b, { 0x8b, 0x5d, 0x83, 0xb1, 0xc2, 0x34, 0xd3, 0xdb } }; // {6BF0A714-3C18-430b-8B5D-83B1C234D3DB} DEFINE_GUID(<>, 0x6bf0a714, 0x3c18, 0x430b, 0x8b, 0x5d, 0x83, 0xb1, 0xc2, 0x34, 0xd3, 0xdb); // {2c1c7e2e-2d0e-4059-831e-1e6f82335c2e} static const GUID <> = { 0x2c1c7e2e, 0x2d0e, 0x4059, { 0x83, 0x1e, 0x1e, 0x6f, 0x82, 0x33, 0x5c, 0x2e } }; // {2c1c7e2e-2d0e-4059-831e-1e6f82335c2e} DEFINE_GUID(<>, 0x2c1c7e2e, 0x2d0e, 0x4059, 0x83, 0x1e, 0x1e, 0x6f, 0x82, 0x33, 0x5c, 0x2e); // {780102B0-C43B-4876-BC7B-5E9BA5C88794} static const GUID <> = { 0x780102b0, 0xc43b, 0x4876, { 0xbc, 0x7b, 0x5e, 0x9b, 0xa5, 0xc8, 0x87, 0x94 } }; // {780102B0-C43B-4876-BC7B-5E9BA5C88794} DEFINE_GUID(<>, 0x780102b0, 0xc43b, 0x4876, 0xbc, 0x7b, 0x5e, 0x9b, 0xa5, 0xc8, 0x87, 0x94); // {24264891-E80B-4fd3-B7CE-4FF2FAE8931F} static const GUID <> = { 0x24264891, 0xe80b, 0x4fd3, { 0xb7, 0xce, 0x4f, 0xf2, 0xfa, 0xe8, 0x93, 0x1f } }; // {24264891-E80B-4fd3-B7CE-4FF2FAE8931F} DEFINE_GUID(<>, 0x24264891, 0xe80b, 0x4fd3, 0xb7, 0xce, 0x4f, 0xf2, 0xfa, 0xe8, 0x93, 0x1f); // {2769280B-5108-498c-9C7F-A51239B63147} static const GUID <> = { 0x2769280b, 0x5108, 0x498c, { 0x9c, 0x7f, 0xa5, 0x12, 0x39, 0xb6, 0x31, 0x47 } }; // {2769280B-5108-498c-9C7F-A51239B63147} DEFINE_GUID(<>, 0x2769280b, 0x5108, 0x498c, 0x9c, 0x7f, 0xa5, 0x12, 0x39, 0xb6, 0x31, 0x47); // {ABDBD0B1-7D54-49fb-AB5C-BFF4130004CD} static const GUID <> = { 0xabdbd0b1, 0x7d54, 0x49fb, { 0xab, 0x5c, 0xbf, 0xf4, 0x13, 0x0, 0x4, 0xcd } }; // {ABDBD0B1-7D54-49fb-AB5C-BFF4130004CD} DEFINE_GUID(<>, 0xabdbd0b1, 0x7d54, 0x49fb, 0xab, 0x5c, 0xbf, 0xf4, 0x13, 0x0, 0x4, 0xcd); // {8CF89BCB-394C-49b2-AE28-A59DD4ED7F68} static const GUID <> = { 0x8cf89bcb, 0x394c, 0x49b2, { 0xae, 0x28, 0xa5, 0x9d, 0xd4, 0xed, 0x7f, 0x68 } }; // {8CF89BCB-394C-49b2-AE28-A59DD4ED7F68} DEFINE_GUID(<>, 0x8cf89bcb, 0x394c, 0x49b2, 0xae, 0x28, 0xa5, 0x9d, 0xd4, 0xed, 0x7f, 0x68); // {22D8B4F2-F577-4adb-A335-C2AE88416FAB} static const GUID <> = { 0x22d8b4f2, 0xf577, 0x4adb, { 0xa3, 0x35, 0xc2, 0xae, 0x88, 0x41, 0x6f, 0xab } }; // {22D8B4F2-F577-4adb-A335-C2AE88416FAB} DEFINE_GUID(<>, 0x22d8b4f2, 0xf577, 0x4adb, 0xa3, 0x35, 0xc2, 0xae, 0x88, 0x41, 0x6f, 0xab); // {AF2440F6-8AFC-47d0-9A7F-396A0ACFB43D} static const GUID <> = { 0xaf2440f6, 0x8afc, 0x47d0, { 0x9a, 0x7f, 0x39, 0x6a, 0xa, 0xcf, 0xb4, 0x3d } }; // {AF2440F6-8AFC-47d0-9A7F-396A0ACFB43D} DEFINE_GUID(<>, 0xaf2440f6, 0x8afc, 0x47d0, 0x9a, 0x7f, 0x39, 0x6a, 0xa, 0xcf, 0xb4, 0x3d); // {522e34a4-07f7-40a1-94d0-1bfe832efc3a} static const GUID <> = { 0x522e34a4, 0x07f7, 0x40a1, { 0x94, 0xd0, 0x1b, 0xfe, 0x83, 0x2e, 0xfc, 0x3a } }; // {522e34a4-07f7-40a1-94d0-1bfe832efc3a} DEFINE_GUID(<>, 0x522e34a4, 0x07f7, 0x40a1, 0x94, 0xd0, 0x1b, 0xfe, 0x83, 0x2e, 0xfc, 0x3a); // {CA3FDCA2-BFBE-4eed-90D7-0CAEF0A1BDA1} static const GUID <> = { 0xca3fdca2, 0xbfbe, 0x4eed, { 0x90, 0xd7, 0xc, 0xae, 0xf0, 0xa1, 0xbd, 0xa1 } }; // {CA3FDCA2-BFBE-4eed-90D7-0CAEF0A1BDA1} DEFINE_GUID(<>, 0xca3fdca2, 0xbfbe, 0x4eed, 0x90, 0xd7, 0xc, 0xae, 0xf0, 0xa1, 0xbd, 0xa1); // {A879E3C4-AF77-44fb-8F37-EBD1487CF920} static const GUID <> = { 0xa879e3c4, 0xaf77, 0x44fb, { 0x8f, 0x37, 0xeb, 0xd1, 0x48, 0x7c, 0xf9, 0x20 } }; // {A879E3C4-AF77-44fb-8F37-EBD1487CF920} DEFINE_GUID(<>, 0xa879e3c4, 0xaf77, 0x44fb, 0x8f, 0x37, 0xeb, 0xd1, 0x48, 0x7c, 0xf9, 0x20); // {B72F8FD8-0FAB-4dd9-BDBF-245A6CE1485B} static const GUID <> = { 0xb72f8fd8, 0xfab, 0x4dd9, { 0xbd, 0xbf, 0x24, 0x5a, 0x6c, 0xe1, 0x48, 0x5b } }; // {B72F8FD8-0FAB-4dd9-BDBF-245A6CE1485B} DEFINE_GUID(<>, 0xb72f8fd8, 0xfab, 0x4dd9, 0xbd, 0xbf, 0x24, 0x5a, 0x6c, 0xe1, 0x48, 0x5b); // {8DE9C74C-605A-4acd-BEE3-2B222AA2D23D} static const GUID <> = { 0x8de9c74c, 0x605a, 0x4acd, { 0xbe, 0xe3, 0x2b, 0x22, 0x2a, 0xa2, 0xd2, 0x3d } }; // {8DE9C74C-605A-4acd-BEE3-2B222AA2D23D} DEFINE_GUID(<>, 0x8de9c74c, 0x605a, 0x4acd, 0xbe, 0xe3, 0x2b, 0x22, 0x2a, 0xa2, 0xd2, 0x3d); // {116F8D13-101E-4fa5-84D4-FF8279381935} static const GUID <> = { 0x116f8d13, 0x101e, 0x4fa5, { 0x84, 0xd4, 0xff, 0x82, 0x79, 0x38, 0x19, 0x35 } }; // {116F8D13-101E-4fa5-84D4-FF8279381935} DEFINE_GUID(<>, 0x116f8d13, 0x101e, 0x4fa5, 0x84, 0xd4, 0xff, 0x82, 0x79, 0x38, 0x19, 0x35); // {52F15C89-5A17-48e1-BBCD-46A3F89C7CC2} static const GUID <> = { 0x52f15c89, 0x5a17, 0x48e1, { 0xbb, 0xcd, 0x46, 0xa3, 0xf8, 0x9c, 0x7c, 0xc2 } }; // {52F15C89-5A17-48e1-BBCD-46A3F89C7CC2} DEFINE_GUID(<>, 0x52f15c89, 0x5a17, 0x48e1, 0xbb, 0xcd, 0x46, 0xa3, 0xf8, 0x9c, 0x7c, 0xc2); // {E03E85B0-7BE3-4000-BA98-6C13DE9FA486} static const GUID <> = { 0xe03e85b0, 0x7be3, 0x4000, { 0xba, 0x98, 0x6c, 0x13, 0xde, 0x9f, 0xa4, 0x86 } }; // {E03E85B0-7BE3-4000-BA98-6C13DE9FA486} DEFINE_GUID(<>, 0xe03e85b0, 0x7be3, 0x4000, 0xba, 0x98, 0x6c, 0x13, 0xde, 0x9f, 0xa4, 0x86); // {D957171F-4BF9-4de2-BCD5-C70A7CA55836} static const GUID <> = { 0xd957171f, 0x4bf9, 0x4de2, { 0xbc, 0xd5, 0xc7, 0xa, 0x7c, 0xa5, 0x58, 0x36 } }; // {D957171F-4BF9-4de2-BCD5-C70A7CA55836} DEFINE_GUID(<>, 0xd957171f, 0x4bf9, 0x4de2, 0xbc, 0xd5, 0xc7, 0xa, 0x7c, 0xa5, 0x58, 0x36); // {5088B39A-29B4-4d9d-8245-4EE289222F66} static const GUID <> = { 0x5088b39a, 0x29b4, 0x4d9d, { 0x82, 0x45, 0x4e, 0xe2, 0x89, 0x22, 0x2f, 0x66 } }; // {5088B39A-29B4-4d9d-8245-4EE289222F66} DEFINE_GUID(<>, 0x5088b39a, 0x29b4, 0x4d9d, 0x82, 0x45, 0x4e, 0xe2, 0x89, 0x22, 0x2f, 0x66); */