/* * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* $Id$ */ #ifndef __KHIMAIRA_KMM_H #define __KHIMAIRA_KMM_H #include #include /*! \defgroup kmm NetIDMgr Module Manager @{*/ /*! \brief A handle to a module. */ typedef khm_handle kmm_module; /*! \brief A handle to a plugin. */ typedef khm_handle kmm_plugin; /*! \name Limits @{*/ /*! \brief Maximum number of characters in a name in KMM including the terminating NULL */ #define KMM_MAXCCH_NAME 256 /*! \brief Maximum number of bytes in a name in KMM including the terminating NULL */ #define KMM_MAXCB_NAME (sizeof(wchar_t) * KMM_MAXCCH_NAME) /*! \brief Maximum number of characters in a description in KMM including the terminating NULL */ #define KMM_MAXCCH_DESC 512 /*! \brief Maximum number of bytes in a description in KMM including the terminating NULL */ #define KMM_MAXCB_DESC (sizeof(wchar_t) * KMM_MAXCCH_NAME) /*! \brief Maximum number of characters in a vendor string in KMM including the terminating NULL */ #define KMM_MAXCCH_VENDOR 256 /*! \brief Maximum number of bytes in a vendor string in KMM including the terminating NULL */ #define KMM_MAXCB_VENDOR (sizeof(wchar_t) * KMM_MAXCCH_VENDOR) /*! \brief Maximum number of characters in a support URI in KMM including the terminating NULL */ #define KMM_MAXCCH_SUPPORT 256 /*! \brief Maximum number of bytes in a vendor string in KMM including the terminating NULL */ #define KMM_MAXCB_SUPPORT (sizeof(wchar_t) * KMM_MAXCCH_SUPPORT) /*! \brief Maximum number of dependencies per plugin */ #define KMM_MAX_DEPENDENCIES 8 /*! \brief Maximum number of dependants per plugin */ #define KMM_MAX_DEPENDANTS 32 /*! \brief Maximum number of characters a dependency string including trailing double NULL */ #define KMM_MAXCCH_DEPS (KMM_MAXCCH_NAME * KMM_MAX_DEPENDENCIES + 1) /*! \brief Maximum number of bytes in a dependency string including trailing double NULL */ #define KMM_MAXCB_DEPS (sizeof(wchar_t) * KMM_MAXCCH_DEPS) /*@}*/ /* Limits */ /*! \brief Plugin registration \see ::khm_cred_provider */ typedef struct tag_kmm_plugin_reg { wchar_t * name; /*!< Name of the plugin. Maximum of KMM_MAXCCH_NAME characters including the terminating NULL. Required. */ wchar_t * module; /*!< Name of module that owns the plugin. Maximum of KMM_MAXCCH_NAME characters including terminating NULL. Required. */ khm_int32 type; /*!< Type plugin type. One of KHM_PITYPE_*. Required. */ khm_int32 flags; /*!< Unused. Set to 0 */ kmq_callback_t msg_proc; /*!< Message processor. Required. */ wchar_t * dependencies; /*!< Dependencies. Note that this is a multi string. (you can use the KHC multi string functions to manipulate multi strings or to convert a comma separated list of dependencies to a multi string). Each string in the multi string is a name of a plugin that this plugin depends on. Optional (set to NULL if this plugin has no dependencies). Maximum of KMM_MAXCCH_DEPS characters including terminating double NULL.*/ wchar_t * description; /*!< Description of the plugin. Maximum of KMM_MAXCCH_DESC characters including the terminating NULL. Localized. Optional (set to NULL if not provided) */ #ifdef _WIN32 HICON icon; /*!< Icon used to represent the plugin. Optional. (set to NULL if not provided) */ #endif } kmm_plugin_reg; /*! \brief Plugin information */ typedef struct tag_kmm_plugin_info { kmm_plugin_reg reg; /*!< Registration info */ khm_int32 state; /*!< Current status of the plugin. One of ::_kmm_plugin_states */ khm_int32 failure_count; /*!< Number of recorded failures in the plugin */ FILETIME failure_time; /*!< Time of first recorded failure */ khm_int32 failure_reason; /*!< The reason for the first recorded failure */ kmm_plugin h_plugin; /*!< Handle to plugin */ khm_int32 flags; /*!< Flags for the plugin. Currently this can only specify ::KMM_PLUGIN_FLAG_DISABLED. */ } kmm_plugin_info; /*! \brief The plugin is disabled This flag will be set in the \a flags field of the ::kmm_plugin_info structure for a plugin that has been marked as disabled. If the plugin is currently running, but marked as disabled for future sessions, then this bit will be set in \a flags , but the \a state of the plugin will indicate that the plugin is running. */ #define KMM_PLUGIN_FLAG_DISABLED 0x00000400 /*! \name Plugin types @{*/ /*! \brief A credentials provider \see \ref pi_pt_cred for more information. */ #define KHM_PITYPE_CRED 1 /*! \brief A identity provider \see \ref pi_pt_cred for more information */ #define KHM_PITYPE_IDENT 2 /*! \brief A configuration provider \see \ref pi_pt_conf for more information. */ #define KHM_PITYPE_CONFIG 3 /*! \brief Undefined plugin type The plugin doesn't provide any credential type. */ #define KHM_PITYPE_MISC 4 /*@}*/ /*! \brief Plugin states */ enum _kmm_plugin_states { KMM_PLUGIN_STATE_FAIL_INIT = -6, /*!< Failed to initialize */ KMM_PLUGIN_STATE_FAIL_UNKNOWN = -5, /*!< Failed due to unknown reasons */ KMM_PLUGIN_STATE_FAIL_MAX_FAILURE = -4, /*!< The plugin has reached the maximum number of failures and cannot be initialized until the failure count is reset */ KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED = -3, /*!< Failed because the plugin was not registered and automatic registration failed. */ KMM_PLUGIN_STATE_FAIL_DISABLED = -2,/*!< Failed because plugin was disabled by the user. */ KMM_PLUGIN_STATE_FAIL_LOAD = -1, /*!< The plugin failed to load due to some unknown reason. */ KMM_PLUGIN_STATE_NONE = 0, /*!< Unknown state */ KMM_PLUGIN_STATE_PLACEHOLDER, /*!< Placeholder. The plugin hasn't been provided by anyone yet, but the plugin record has been created to keep track of dependencies. */ KMM_PLUGIN_STATE_REG, /*!< The plugin is registered but not initialized */ KMM_PLUGIN_STATE_PREINIT, /*!< The plugin is in the process of being initialized */ KMM_PLUGIN_STATE_HOLD, /*!< On hold. One or more dependencies of this plugin has not been resolved */ KMM_PLUGIN_STATE_INIT, /*!< The plugin was initialized */ KMM_PLUGIN_STATE_RUNNING, /*!< The plugin is running */ KMM_PLUGIN_STATE_EXITED /*!< The plugin has been stopped. */ }; /*! \brief Module registration */ typedef struct tag_kmm_module_reg { wchar_t * name; /*!< Identifier for the module */ wchar_t * path; /*!< Full pathname to module binary */ wchar_t * description; /*!< Description of module */ wchar_t * vendor; /*!< Vendor/copyright string */ wchar_t * support; /*!< Support URL/contact */ khm_int32 n_plugins; /*!< Number of plugins that are active */ kmm_plugin_reg * plugin_reg_info; /*!< Array of kmm_plugin_reg records for each active plugin */ } kmm_module_reg; /*! \brief Module information record */ typedef struct tag_kmm_module_info { kmm_module_reg reg; /*!< Registration info */ khm_ui_4 language; /*!< Currently loaded langugage */ khm_int32 state; /*!< Current status of the module */ khm_version file_version; /*!< File version for the module */ khm_version product_version; /*!< Product version for the module */ khm_int32 failure_count; /*!< Number of times the module has failed to load */ FILETIME failure_time; /*!< Time of first recorded failure */ khm_int32 failure_reason; /*!< Reason for first failure. One of the module status values */ kmm_module h_module; /*!< Handle to the module. */ } kmm_module_info; /*! \brief Module states */ enum KMM_MODULE_STATES { KMM_MODULE_STATE_FAIL_INCOMPAT=-12, /*!< The library containing the module was not compatible with this version of NetIDMgr. */ KMM_MODULE_STATE_FAIL_INV_MODULE=-11, /*!< The library containing the module was invalid. */ KMM_MODULE_STATE_FAIL_UNKNOWN=-10, /*!< Module could not be loaded due to unknown reasons. */ KMM_MODULE_STATE_FAIL_MAX_FAILURE=-9,/*!< The module has failed too many times already. Not attempting to restart it again */ KMM_MODULE_STATE_FAIL_DUPLICATE=-8, /*!< An attempt was made to load the same module twice. */ KMM_MODULE_STATE_FAIL_NOT_REGISTERED=-7, /*!< The module is not found among the registered module list */ KMM_MODULE_STATE_FAIL_NO_PLUGINS=-6,/*!< The module provided no plugins, or all the plugins that are provided are disabled */ KMM_MODULE_STATE_FAIL_DISABLED=-5, /*!< Module is disabled and cannot be loaded */ KMM_MODULE_STATE_FAIL_LOAD=-4, /*!< The module failed to initialize */ KMM_MODULE_STATE_FAIL_INVALID=-3, /*!< The module was invalid. Typically caused by the required entrypoints not being present */ KMM_MODULE_STATE_FAIL_SIGNATURE=-2, /*!< The module failed to load due to an unverifiable signature */ KMM_MODULE_STATE_FAIL_NOT_FOUND=-1, /*!< The module was not found */ KMM_MODULE_STATE_NONE=0, /*!< Unknown state. The handle is possibly invalid */ KMM_MODULE_STATE_PREINIT, /*!< The module is being loaded. init_module() hasn't been called yet */ KMM_MODULE_STATE_INIT, /*!< In init_module() */ KMM_MODULE_STATE_INITPLUG, /*!< Initializing plugins */ KMM_MODULE_STATE_RUNNING, /*!< Running */ KMM_MODULE_STATE_EXITPLUG, /*!< Currently exiting plugins */ KMM_MODULE_STATE_EXIT, /*!< Currently exiting */ KMM_MODULE_STATE_EXITED /*!< Exited */ }; /*! \brief Start the Module Manager \note Only called by the NetIDMgr core. */ KHMEXP void KHMAPI kmm_init(void); /*! \brief Stop the Module Manager \note Only called by the NetIDMgr core. */ KHMEXP void KHMAPI kmm_exit(void); /*! \brief Return the plugin handle for the current plugin The returned handle represents the plugin which owns the current thread. The returned handle must be released by calling kmm_release_plugin(). Returns NULL if the current thread is not owned by any plugin. */ KHMEXP kmm_plugin KHMAPI kmm_this_plugin(void); /*! \brief Return the module handle for the current module The returned handle represents the module which owns the current thread. The returned handle must be released by calling kmm_release_module() */ KHMEXP kmm_module KHMAPI kmm_this_module(void); /*! \name Flags for kmm_load_module() @{*/ /*!\brief Load synchronously If this flag is set, then the function waits for the module to be loaded. The default is to load the module asynchronously. When loading a module asynchronously, the kmm_load_module() function returns KHM_ERROR_SUCCESS and exits without waiting for the module to load. If \a result is not NULL, it will receive a valid handle to the module. When loading a module synchronously, kmm_load_module() will wait for the module to completely load. If it fails to load properly, it will return an error code and set \a result to NULL. */ #define KMM_LM_FLAG_SYNC 1 /*! \brief Do not load Indicates that the module shouldn't actually be loaded. If the specified module name identifies a module that has already been loaded, then the function returns a held handle to the existing module (use kmm_release_module() to free the handle). Otherwise, the function returns KHM_ERROR_NOT_FOUND. */ #define KMM_LM_FLAG_NOLOAD 2 /*@}*/ /*! \brief Load a module The \a modulename parameter specifies a module to load. Depending on the configuration, not all of the plugins that are provided by the module may be loaded. If no plugins are successfully loaded, the module will be immediately unloaded. If the module is currently loaded or is being loaded, then a valid handle to the existing module is returned. When called with KMM_LM_FLAG_SYNC, the function does not return until the module and the associated plugins are all initialized, or an error occurs. If the KMM_LM_FLAG_NOLOAD flag is set, then a handle to an existing instance of the module will be returned. If the module hasn't been loaded yet, then no handle is returned and the function returns KHM_ERROR_NOT_FOUND. See the associated NetIDMgr Module Manager documentation on the sequence of events associated with loading a module. \param[in] modulename Name of the module. The module should have been registered under this name prior to the call. \param[in] flags Combination of KMM_LM_FLAG_* \param[out] result Receives a handle to the loaded module. If the result is not required, set this to NULL. If \a result is not NULL, and km_load_module() returns KHM_ERROR_SUCCESS, then kmm_release_module() must be called to release the handle to the module. Otherwise, \a result receives NULL. If a handle is returned, it will be valid regardless of whether the module fails to load or not. You can use kmm_get_module_state() to query the progress of the loading process. See ::KMM_LM_FLAG_SYNC. \retval KHM_ERROR_SUCCESS The call succeeded. If \a KMM_LM_FLAG_SYNC was specified, this means that the module was successfully loaded. Otherwise, it only means that the module has been queued up for loading. Use kmm_get_module_state() to determine if it was successfully loaded. If \a result is not NULL, a valid handle is returned. \retval KHM_ERROR_EXISTS The module is already loaded or has been already queued for loading. If \a result is not NULL, a valid handle to the existing module instance is returned. \retval KHM_ERROR_NOT_FOUND If called with KMM_LM_FLAG_NOLOAD, indicates that the module has not been loaded. Otherwise only returned when called with KMM_LM_FLAG_SYNC. The module image was not found. No handle is returned. \retval KHM_ERROR_INVALID_SIGNATURE Only returned when called with KMM_LM_FLAG_SYNC. The module was signed with an invalid certificate. No handle is returned. \retval KHM_ERROR_UNKNOWN Only returned when called with KMM_LM_FLAG_SYNC. Some other error has occured. No handle is returned. \see \ref pi_fw_pm_load \see ::KMM_LM_FLAG_SYNC, ::KMM_LM_FLAG_NOLOAD */ KHMEXP khm_int32 KHMAPI kmm_load_module(wchar_t * modname, khm_int32 flags, kmm_module * result); /*! \brief Hold a handle to a module Use kmm_release_module() to release the hold. */ KHMEXP khm_int32 KHMAPI kmm_hold_module(kmm_module module); /*! \brief Release a handle to a module Release a held referece to a module that was returned in a call to kmm_load_module(). */ KHMEXP khm_int32 KHMAPI kmm_release_module(kmm_module m); /*! \brief Query the state of a module When loading a module asynchronously you can query the state of the loading process using this. The return value is a status indicator. \return The return value is one of the ::KMM_MODULE_STATES enumerations. */ KHMEXP khm_int32 KHMAPI kmm_get_module_state(kmm_module m); /*! \brief Unload a module See the associated NetIDMgr Module Manager documentation on the sequence of events associated with unloading a module. \see \ref pi_fw_pm_unload */ KHMEXP khm_int32 KHMAPI kmm_unload_module(kmm_module module); /*! \brief Loads the default modules as specified in the configuration The configuration can specify the default set of modules to load. This function dispatches the necessary message for loading these modules and reutnrs. */ KHMEXP khm_int32 KHMAPI kmm_load_default_modules(void); /*! \brief Checks whether there are any pending loads Returns TRUE if there are modules still waiting to be loaded. */ KHMEXP khm_boolean KHMAPI kmm_load_pending(void); #ifdef _WIN32 /*! \brief Returns the Windows module handle from a handle to a NetIDMgr module. Although it is possible to obtain the Windows module handle and use it to call Windows API functions, it is not recommended to do so. This is because that might cause the state of the module to change in ways which are inconsistent from the internal data structures that kmm maintains. */ KHMEXP HMODULE KHMAPI kmm_get_hmodule(kmm_module m); #endif /*! \brief Hold a plugin Obtains a hold on a plugin. The plugin handle will remain valid until the hold is released with a call to kmm_release_plugin(). No guarantees are made on the handle once the handle is released. */ KHMEXP khm_int32 KHMAPI kmm_hold_plugin(kmm_plugin p); /*! \brief Release a plugin Releases a hold on a plugin obtained through a call to kmm_hold_plugin(). The plugin handle should no longer be considered valied once this is called. */ KHMEXP khm_int32 KHMAPI kmm_release_plugin(kmm_plugin p); /*! \brief Provide a plugin This function must be called for each plugin that the module provides. Note that this function returns immediately and does not initialize the plugin. All plugins that are provided by a module will be initialized once the init_module() function returns. If the plugin has dependencies, it will be kept in a held state until the plugins that it depends on are successfully initialized. If the dependencies are not resolved (the dependent plugins are not loaded), then plugin will not be initialized. If the plugin is not registered and \a plugin contains enough information to perform the registration, then it will be automatically registered. However, if the plugin is not registered and cannot be registered using the provided information, the plugin will not be initialized properly. Note that automatic registration will always register the plugin in the user configuration store. The \a name and \a msg_proc members of \a plugin are required to have valid values. The \a icon member may optionally be specified. The other fields can be specified if the plugin should be automatically registered, however, the \a module field will be ignored and will be determined by the \a module handle. \param[in] module Handle to this module that is providing the plugin. \param[in] plugin A plugin descriptor. \retval KHM_ERROR_SUCCESS Succeeded. \retval KHM_ERROR_INVALID_OPERATION The function was not called during init_module() \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_DUPLICATE The plugin was already provided \note This can only be called when handing init_module() */ KHMEXP khm_int32 KHMAPI kmm_provide_plugin(kmm_module module, kmm_plugin_reg * plugin); /*! \brief Query the state of a plugin. \return One of ::_kmm_plugin_states */ KHMEXP khm_int32 KHMAPI kmm_get_plugin_state(wchar_t * plugin); /*! \defgroup kmm_reg Registration The functions for managing plugin and module registration. These functions are also available as static linked libraries for use by external applications which must register or unregister plugins or modules. @{*/ /*! \brief Obtain the configuration space for a named plugin Note that the named plugin does not have to actually exist. Configuration spaces for plugins are based solely on the plugin name and hence can be accessed regardless of whether the specific plugin is loaded or not. \param[in] flags Controls the options for opening the configuration space. If KHM_FLAG_CREATE is specified, then the configuration space for the plugin named \a plugin wil be created if it doesn't already exist. The \a flags parameter is directly passed into a call to khc_open_space(). \param[in] plugin Name of the plugin. The name can not contain slashes. \param[out] result Receives a configuration space handle. The calling application should free the handle using khc_close_space(). \see khc_open_space() \see khc_close_space() */ KHMEXP khm_int32 KHMAPI kmm_get_plugin_config(wchar_t * plugin, khm_int32 flags, khm_handle * result); /*! \brief Obtain the configuration space for a named module The named module does not have to actually exist. Configuration spaces for modules are based on the basename of the module (including the extension). \param[in] module Name of the module. \param[in] flags The flags used to call khc_open_space(). You can use this to specify a particular configuration store if needed. \param[out] result Receives the handle to a configuration space if successful. Call khc_close_space() to close the handle. \see khc_open_space() \see khc_close_space() */ KHMEXP khm_int32 KHMAPI kmm_get_module_config(wchar_t * module, khm_int32 flags, khm_handle * result); /*! \brief Retrieve a handle to the configuration space for plugins The configuration space for plugins is a container which holds the configuration subspaces for all the plugins. This is the config space which must be used to load a configuration space for a plugin. \param[in] flags The flags to pass in to the call to khc_open_space(). The flags can be used to select a specific configuration store if needed. \param[out] result Receives a handle to the configuration space. Call khc_close_space() to close the handle \see khc_open_space() \see khc_close_space() */ KHMEXP khm_int32 KHMAPI kmm_get_plugins_config(khm_int32 flags, khm_handle * result); /*! \brief Retrieve the handle to the configuration space for modules The configuration space for modules is a container which hold the configuration subspaces for all the modules. Each module registration ends up in this subspace. \param[in] flags The flags to pass in to the call to khc_open_space(). The flags can be used to select a specific configuration store if needed. \param[out] result Receives a handle to the configuration space. Call khc_close_space() to close the handle. \see khc_open_space() \see khc_close_space() */ KHMEXP khm_int32 KHMAPI kmm_get_modules_config(khm_int32 flags, khm_handle * result); /*! \brief Return information about a loaded module The retrieves a block of information about a module. Refer to ::kmm_module_info for information about the format of the returned data. Note that the size of the required buffer is actually greater than the size of the ::kmm_module_info structure and accomodates the ::kmm_plugin_info structures and strings required to complete the information block. Call the function with \a buffer set to NULL and \a cb_buffer pointing at a khm_size variable to obtain the required size of the buffer. \param[in] module_name Name of a module \param[in] flags Flags indicating which types of information to return \param[out] buffer Points to a buffer that recieves information. Set this to NULL if only the size of the buffer is required. \param[in,out] On entry, contains the size of the buffer pointed to by \a buffer if \a buffer is not NULL. On exit, contains the required size of the buffer or the number of actual bytes copied. \retval KHM_ERROR_SUCCESS The requested information was copied \retval KHM_ERROR_INVALID_PARAM One of the parameters was invalid \retval KHM_ERROR_TOO_LONG The buffer was not large enough or was NULL. The number of bytes requied is in \a cb_buffer. \retval KHM_ERROR_NOT_FOUND The specified module is not a registered module. */ KHMEXP khm_int32 KHMAPI kmm_get_module_info(wchar_t * module_name, khm_int32 flags, kmm_module_info * buffer, khm_size * cb_buffer); /*! \brief Get information about a module Similar to kmm_get_module_info(), but uses a module handle instead of a name, and uses internal buffers for providing string fields. The information that is returned should be freed using a call to kmm_release_module_info_i(). \see kmm_release_module_info_i() */ KHMEXP khm_int32 KHMAPI kmm_get_module_info_i(kmm_module module, kmm_module_info * info); /*! \brief Release module information Releases the information returned by a previous call to kmm_get_module_info_i(). The contents of the ::kmm_module_info structure should not have been modified in any way between calling kmm_get_module_info_i() and kmm_release_module_info_i(). */ KHMEXP khm_int32 KHMAPI kmm_release_module_info_i(kmm_module_info * info); /*! \brief Obtain information about a plugin Retrieve a block of information about a plugin. See ::kmm_plugin_info for details about what information can be returned. Note that some fields may not be available if the module is not loaded. Note that the size of the required buffer is greater than the size of the ::kmm_plugin_info structure and accounts for strings as well. Call kmm_get_plugin_info() with \a buffer set to NULL and \a cb_buffer set to point to a variable of type \a khm_size to obtain the required size of the structure. \param[in] plugin_name Name of the plugin \param[out] buffer The buffer to receive the plugin information. Set to \a NULL if only the size of the buffer is required. \param[in,out] cb_buffer On entry, points to variable that specifies the size of the buffer pointed to by \a buffer is \a buffer is not \a NULL. On exit, holds the number of bytes copied or the required size of the buffer. \retval KHM_ERROR_SUCCESS The requested information was successfully copied to the \a buffer \retval KHM_ERROR_TOO_LONG The buffer was either \a NULL or insufficient to hold the requested information. The required size of the buffer was stored in \a cb_buffer \retval KHM_ERROR_INVALID_PARAM One or more parameters were invlaid. \retval KHM_ERROR_NOT_FOUND The specified plugin was not found among the registered plugins. */ KHMEXP khm_int32 KHMAPI kmm_get_plugin_info(wchar_t * plugin_name, kmm_plugin_info * buffer, khm_size * cb_buffer); /*! \brief Obtain information about a plugin using a plugin handle Similar to kmm_get_plugin_info() but uses a plugin handle instead of a plugin name. If the call is successful, the \a info structure will be filled with information about the plugin. The returned info should not be modified in any way and may contain pointers to internal buffers. The returned information must be released with a call to kmm_release_plugin_info_i(). */ KHMEXP khm_int32 KHMAPI kmm_get_plugin_info_i(kmm_plugin p, kmm_plugin_info * info); /*! \brief Release plugin information returned by kmm_get_plugin_info_i The information returned by kmm_get_plugin_info_i() should not be modified in any way before calling kmm_release_plugin_info_i(). Once the call completes, the contents of \a info will be initialized to zero. */ KHMEXP khm_int32 KHMAPI kmm_release_plugin_info_i(kmm_plugin_info * info); /*! \brief Enumerates plugins Enumerates through known plugins. This list may not include plugins which were not loaded by NetIDMgr in this session. If the call is successful, a handle to the next plugin in the list will be placed in \a p_next. The returned handle must be freed with a call to kmm_release_plugin(). If the \a p parameter is set to NULL, then the first plugin handle will be placed in \a p_next. The handles will not be returned in any specific order. In addition, the enumeration may not include all known plugins if the list of plugins changes during enumeration. */ KHMEXP khm_int32 KHMAPI kmm_get_next_plugin(kmm_plugin p, kmm_plugin * p_next); /*! \brief Enables or disables a plugin This function currently does not take effect immediately. However it marks the plugin as enabled or disabled so that the next time NetIDMgr starts, the module manager will act accordingly. \param[in] p Handle to the plugin \param[in] enable If non-zero, the plugin will be marked as enabled. Otherwise the plugin will be marked as disabled. */ KHMEXP khm_int32 KHMAPI kmm_enable_plugin(kmm_plugin p, khm_boolean enable); /*! \brief Register a plugin The \a plugin member defines the plugin to be registered. The \a msg_proc and \a icon members of the structure are ignored. At the time kmm_register_plugin() is called, the module specified by \a module member of the \a plugin parameter must have been already registered. Otherwise the function call fails. If the plugin has already been registered, then all the fields in the plugin registration will be updated to be in sync with the information provided in the \a plugin parameter. The failure counts and associated statistics will not be reset when the configuration information is updated. If the plugin has not been registered, the a new registration entry is created in the configuration space indicated by the \a config_flags parameter. In addition, the plugin will be added to the list of plugins associated with the owning module. Note that the module that owns the plugin must be registered in the same configuration store as the plugin. \param[in] plugin Registration info for the plugin. The \a msg_proc and \a icon members are ignored. All other fields are required. The \a description member should be localized to the system locale when registering a plugin in the machine configuration store and should be localized to the user locale when registering a plugin in the user configuration store. \param[in] config_flags Flags for the configuration provider. These flags are used verbatim to call khc_open_space(), hence they may be used to pick whether or not the registration is per machine or per user. \see kmm_register_module() */ KHMEXP khm_int32 KHMAPI kmm_register_plugin(kmm_plugin_reg * plugin, khm_int32 config_flags); /*! \brief Register a module The \a module parameter specifies the parameters for the module registration. The \a plugin_info member should point to an array of ::kmm_plugin_info structures unless the \a n_plugins member is zero, in which case \a plugin_info can be \a NULL. Plugins can be registered separately using kmm_register_plugin(). \param[in] module Information about the module. The name and path fields are required. The \a plugin_info field can only be \a NULL if \a n_plugins is zero. \param[in] config_flags Flags used to call khc_open_space(). This can be used to choose the configuration store in which the module registration will be performed. */ KHMEXP khm_int32 KHMAPI kmm_register_module(kmm_module_reg * module, khm_int32 config_flags); /*! \brief Unregister a plugin Registration information associated with the plugin will be removed. In addtion, the plugin will be removed from the list of plugins provided by the owner module. \param[in] plugin Names the plugin to be removed \param[in] config_flags Flags used to call khc_open_space(). Can be used to choose the configuraiton store that is affected by the call. \note kmm_unregister_plugin() has no effect on whether the plugin is loaded or not. The caller must make sure that the plugin is unloaded and the associated module is either also unloaded or in a state where the plugin can be unregistered. */ KHMEXP khm_int32 KHMAPI kmm_unregister_plugin(wchar_t * plugin, khm_int32 config_flags); /*! \brief Unregister a module Registration information associated with the module as well as all the plugins provided by the module will be removed from the configuration store. \param[in] module Names the module to be removed \param[in] config_flags Flags used to call khc_open_space(). Can be used to choose the configuration store affected by the call. \note kmm_unregister_module() has no effect on the loaded state of the module. The caller should make sure that the module is unloaded and in a state where it can be unregistered. */ KHMEXP khm_int32 KHMAPI kmm_unregister_module(wchar_t * module, khm_int32 config_flags); /*@}*/ /* kmm_reg */ /*! \defgroup kmm_loc Internationalization support See \ref pi_localization for more information about internationalization. @{*/ /*! \brief Locale descriptor record See kmm_set_locale() */ typedef struct tag_kmm_module_locale { khm_ui_4 language; /*!< A language ID. On Windows, you can use the MAKELANGID macro to generate this value. */ wchar_t * filename; /*!< The filename corresponding to this language. Use NULL to indicate that resources for this language are to be found in the main module. */ khm_int32 flags; /*!< Flags. Combination of KMM_MLOC_FLAG_* */ } kmm_module_locale; #define LOCALE_DEF(language_id, filename, flags) {language_id, filename, flags} /*! \brief Default (fallback) locale */ #define KMM_MLOC_FLAG_DEFAULT 1 /*! \brief Sets the locale for a loaded module. The given locale records are searched in the given order until a locale that matches the current user locale is found. If no locales match, then the first locale with the ::KMM_MLOC_FLAG_DEFAULT flag set will be loaded. If no locales have that flag set, then the first locale is loaded. You can obtain a handle to the loaded library using kmm_get_resource_hmodule(). This function does not return until a matched library is loaded. Note that the ::kmm_module_locale structure only specifies a module name for the resource module. This resource module must exist in the same directory as the \a module. \param[in] module The module handle \param[in] locales An array of ::kmm_module_locale objects \param[in] n_locales The number of objects in the array pointed to by \a locales \retval KHM_ERROR_SUCCESS Succeeded. \retval KHM_ERROR_NOT_FOUND A matching locale resource library was not found. \retval KHM_ERROR_INVALID_OPERATION The function was called on a module which is currently not being initalized. \see \ref pi_localization \see kmm_get_resource_hmodule() \note This can only be called when handing init_module() */ KHMEXP khm_int32 KHMAPI kmm_set_locale_info(kmm_module module, kmm_module_locale * locales, khm_int32 n_locales); #ifdef _WIN32 /*! \brief Return the Windows module handle of the resource library of a NetIDMgr module. NetIDMgr allows the specification of an alternate resource library that will be used to load localized resources from. This function returns a handle to this library. While you can use the convenience macros to access resources in a localization library using the module handle, it is recommended, for performance reasons, to use this function to obtain the handle to the resource library and then use that handle in calls to LoadString, LoadImage etc. directly. */ KHMEXP HMODULE KHMAPI kmm_get_resource_hmodule(kmm_module m); /*! \name Convenience Macros @{*/ /*! \brief Convenience macro for using calling LoadAccelerators using a module handle \param[in] module A handle to a loaded module. The corresponding resource module will be located through a call to kmm_get_resource_hmodule() */ #define kmm_LoadAccelerators(module, lpTableName) \ (LoadAccelerators(kmm_get_resource_hmodule(module), lpTableName)) /*! \brief Convenience macro for using calling LoadBitmap using a module handle \param[in] module A handle to a loaded module. The corresponding resource module will be located through a call to kmm_get_resource_hmodule() */ #define kmm_LoadBitmap(module, lpBitmapName) \ (LoadBitmap(kmm_get_resource_hmodule(module), lpBitmapName)) /*! \brief Convenience macro for using calling LoadImage using a module handle \param[in] module A handle to a loaded module. The corresponding resource module will be located through a call to kmm_get_resource_hmodule() */ #define kmm_LoadImage(module, lpszName, uType, cxDesired, cyDesired, fuLoad) \ (LoadImage(kmm_get_resource_hmodule(module), lpszName, uType, cxDesired, cyDesired, fuLoad)) /*! \brief Convenience macro for using calling LoadCursor using a module handle \param[in] module A handle to a loaded module. The corresponding resource module will be located through a call to kmm_get_resource_hmodule() */ #define kmm_LoadCursor(module, lpCursorName) \ (LoadCursor(kmm_get_resource_hmodule(module), lpCursorName)) /*! \brief Convenience macro for using calling LoadIcon using a module handle \param[in] module A handle to a loaded module. The corresponding resource module will be located through a call to kmm_get_resource_hmodule() */ #define kmm_LoadIcon(module, lpIconName) \ (LoadIcon(kmm_get_resource_hmodule(module), lpIconName)) /*! \brief Convenience macro for using calling LoadMenu using a module handle \param[in] module A handle to a loaded module. The corresponding resource module will be located through a call to kmm_get_resource_hmodule() */ #define kmm_LoadMenu(module, lpMenuName) \ (LoadMenu(kmm_get_resource_hmodule(module), lpMenuName)) /*! \brief Convenience macro for using calling LoadString using a module handle \param[in] module A handle to a loaded module. The corresponding resource module will be located through a call to kmm_get_resource_hmodule() */ #define kmm_LoadString(module, uID, lpBuffer, nBufferMax) \ (LoadString(kmm_get_resource_hmodule(module), uID, lpBuffer, nBufferMax)) /*@}*/ /* Convenience Macros */ #endif /*@}*/ /* group kmm_loc */ /*@}*/ /* group kmm */ #endif