+/* API function documented in wimlib.h */
+WIMLIBAPI u32
+wimlib_get_version(void)
+{
+ return (WIMLIB_MAJOR_VERSION << 20) |
+ (WIMLIB_MINOR_VERSION << 10) |
+ WIMLIB_PATCH_VERSION;
+}
+
+static bool lib_initialized = false;
+static pthread_mutex_t lib_initialization_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* API function documented in wimlib.h */
+WIMLIBAPI int
+wimlib_global_init(int init_flags)
+{
+ int ret = 0;
+
+ if (lib_initialized)
+ goto out;
+
+ pthread_mutex_lock(&lib_initialization_mutex);
+
+ if (lib_initialized)
+ goto out_unlock;
+
+#ifdef ENABLE_ERROR_MESSAGES
+ if (!wimlib_error_file)
+ wimlib_error_file = stderr;
+#endif
+
+ ret = WIMLIB_ERR_INVALID_PARAM;
+ if (init_flags & ~(WIMLIB_INIT_FLAG_ASSUME_UTF8 |
+ WIMLIB_INIT_FLAG_DONT_ACQUIRE_PRIVILEGES |
+ WIMLIB_INIT_FLAG_STRICT_CAPTURE_PRIVILEGES |
+ WIMLIB_INIT_FLAG_STRICT_APPLY_PRIVILEGES |
+ WIMLIB_INIT_FLAG_DEFAULT_CASE_SENSITIVE |
+ WIMLIB_INIT_FLAG_DEFAULT_CASE_INSENSITIVE))
+ goto out_unlock;
+
+ ret = WIMLIB_ERR_INVALID_PARAM;
+ if ((init_flags & (WIMLIB_INIT_FLAG_DEFAULT_CASE_SENSITIVE |
+ WIMLIB_INIT_FLAG_DEFAULT_CASE_INSENSITIVE))
+ == (WIMLIB_INIT_FLAG_DEFAULT_CASE_SENSITIVE |
+ WIMLIB_INIT_FLAG_DEFAULT_CASE_INSENSITIVE))
+ goto out_unlock;
+
+ libxml_global_init();
+ if (!(init_flags & WIMLIB_INIT_FLAG_ASSUME_UTF8)) {
+ wimlib_mbs_is_utf8 = test_locale_ctype_utf8();
+ #ifdef WITH_NTFS_3G
+ if (!wimlib_mbs_is_utf8)
+ libntfs3g_global_init();
+ #endif
+ }
+#ifdef __WIN32__
+ ret = win32_global_init(init_flags);
+ if (ret)
+ goto out_unlock;
+#endif
+ iconv_global_init();
+ init_upcase();
+ if (init_flags & WIMLIB_INIT_FLAG_DEFAULT_CASE_SENSITIVE)
+ default_ignore_case = false;
+ else if (init_flags & WIMLIB_INIT_FLAG_DEFAULT_CASE_INSENSITIVE)
+ default_ignore_case = true;
+ lib_initialized = true;
+ ret = 0;
+out_unlock:
+ pthread_mutex_unlock(&lib_initialization_mutex);
+out:
+ return ret;
+}
+
+/* API function documented in wimlib.h */
+WIMLIBAPI void
+wimlib_global_cleanup(void)
+{
+ if (!lib_initialized)
+ return;
+
+ pthread_mutex_lock(&lib_initialization_mutex);
+
+ if (!lib_initialized)
+ goto out_unlock;
+
+ libxml_global_cleanup();
+ iconv_global_cleanup();
+#ifdef __WIN32__
+ win32_global_cleanup();
+#endif
+
+ wimlib_set_error_file(NULL);
+ lib_initialized = false;
+
+out_unlock:
+ pthread_mutex_unlock(&lib_initialization_mutex);
+}