Preferences are accessed via the IAccPreferences class. Callers can obtain an IAccPreferences object via IAccSession get_Prefs(). This object may be used for getting, setting, and enumerating host-based and local preferences.
Preferences are referenced by "specifier." A specifier is a period-delimited string. Specifiers may not contain these characters: space, period, per cent. If a specifier must contain a disallowed character, it can be escaped (%2E and %25 are used in user names, for example). Preferences that AIMCC knows about--even if they are not stored by AIMCC--begin with "aimcc." Applications may use their own domain prefix to access private preferences through AIMCC's APIs. Specific preference specifiers are documented elsewhere.
When calling GetValue(), GetDefaultValue() or GetChildSpecifiers(), the caller is responsible for releasing the returned value.
Applications must create a subclass of IAccPreferencesHook or IAccPreferencesHook2 to provide an object that handles storage/retrieval of local preferences. This design also allows applications with existing preferences stores to map their prefs to AIMCC specifiers for use by AIMCC (for example, AIMCC reads various connection settings). During initial development, it's possible to do without an IAccPreferencesHook, but any full-featured application will need it. C++ developers can get started using CAccPrefsHook in file AccSupport.h. Register a preferences hook object with an IAccSession by calling put_PrefsHook().
OnPreferenceChange
This is called when the value of a preference changes (or an attempt to change it fails). The HRESULT is one of the following:
S_OK - means the value was changed (though it may get changed back if it must be committed)
other error HRESULTs
OnPreferenceResult
This is called when data requested via RequestValue() arrives (or a request fails).
OnPreferenceInvalid
OnPreferenceInvalid is fired if a preference is no longer valid (e.g., a file path points to a file that no longer exists). The app is responsible for notifying the user, if necessary, and deleting the pref, if necessary.
Applications are responsible for knowing the context of a preference access call. For example, if an application implements preference storage as "per user" or "per set," as opposed to "global," it is responsible for matching calls to the appropriate user or set.
GetValue()
The application-provided GetValue() should return one of the following:
S_OK - means a value was returned
ACC_E_NO_DATA - means data for the specifier was not found
other error HRESULTs
GetDefaultValue()
The application-provided object is responsible for generating default values for its own preferences. It should return one of the following:
S_OK - means a value was returned
ACC_E_NO_DATA - means the specifier is unknown or there is no default
other error HRESULTs
SetValue()
The application-provided SetValue() is used for local prefs storage. This function should store any preference that it is asked to store--even if it doesn't recognize the specifier--because some preferences may be used internally by AIMCC. If data must be saved asynchronously, the application-provided SetValue() should return a success result code and then fire OnPreferenceChange when the result of saving the data is known. It should return one of the following:
S_OK - means the value was changed (though it may get changed back if it must be committed)
ACC_S_NO_CHANGE - means the value was the same as that already saved
E_FAIL - means it was not handled
other error HRESULTs
Reset()
For some preferences, this will have no effect; for others, this will have the effect of either removing the value or resetting to the default value. If a "." is appended to the specifier, Reset() is recursive (i.e., any children are also reset). Recursion is handled by AIMCC. If data must be reset asynchronously, OnPreferenceChange is called, and then it's called again if the transaction failed. The application-provided Reset() should return one of the following:
S_OK - means the value was reset (though it may get rolled back if it is asynchronous)
ACC_S_NO_CHANGE - means the value did not change
other error HRESULTs
GetChildSpecifiers()
This is used in preference iteration. Given a partial specifier, this returns the immediate children under that specifier. This function is used for debugging and in getting indexed preferences (e.g., buddies, away messages, etc.). It should return one of the following:
S_OK - means child specifiers were returned
other error HRESULTs
GetSecureValue()
SetSecureValue()
ResetSecure()
These IAccPreferencesHook2 secure methods work very much like their IAccPreferencesHook non-secure counterparts. The difference is they should be used with a secure backing store. See below.
IAccPreferencesHook2 was introduced in AIMCC 1.3 to support secure preferences storage (e.g., storage of passwords). Implementation of IAccPreferencesHook2 is optional.
For some accounts, login with a password hash fails. IAccPreferencesHook2 allows for storage of actual passwords, so at login actual passwords are sent to AOL servers (over SSL) instead of hashes. Hashed passwords that have already been saved will continue to work whether or not IAccPreferencesHook2 is implemented.
Applications that choose not to implement IAccPreferencesHook2 will continue to store password hashes. When calling SetValue("aimcc.connect.host.password",...), AIMCC hashes the password before calling the application's preferences hook with SetValue("aimcc.connect.host.passwordHash",...).
IAccPreferences SetValue() is no different for secure and non-secure preferences. IAccPreferences GetValue() fails for secure preferences.
In future, IAccPreferencesHook2 may be used for secure values besides passwords.
When getting and setting IAccIm's, AIMCC flattens/unflattens the data on behalf of the application's preferences hook.
rev. 2007/05/02