- if (w->fp)
- fclose(w->fp);
- if (w->out_fp)
- fclose(w->out_fp);
-
- free_lookup_table(w->lookup_table);
-
- FREE(w->filename);
- FREE(w->xml_data);
- free_wim_info(w->wim_info);
- if (w->image_metadata) {
- for (uint i = 0; i < w->hdr.image_count; i++)
- destroy_image_metadata(&w->image_metadata[i], NULL);
- FREE(w->image_metadata);
- }
-#ifdef WITH_NTFS_3G
- if (w->ntfs_vol) {
- DEBUG("Unmounting NTFS volume");
- ntfs_umount(w->ntfs_vol, FALSE);
+
+ /* The blob table and image metadata are freed immediately, but other
+ * members of the WIMStruct such as the input file descriptor are
+ * retained until no more exported resources reference the WIMStruct. */
+
+ free_blob_table(wim->blob_table);
+ wim->blob_table = NULL;
+ if (wim->image_metadata != NULL) {
+ for (int i = 0; i < wim->hdr.image_count; i++)
+ put_image_metadata(wim->image_metadata[i], NULL);
+ FREE(wim->image_metadata);
+ wim->image_metadata = NULL;
+ }
+
+ wim_decrement_refcnt(wim);
+}
+
+static bool
+test_locale_ctype_utf8(void)
+{
+#ifdef __WIN32__
+ return false;
+#else
+ char *ctype = nl_langinfo(CODESET);
+
+ return (!strstr(ctype, "UTF-8") ||
+ !strstr(ctype, "UTF8") ||
+ !strstr(ctype, "utf8") ||
+ !strstr(ctype, "utf-8"));
+#endif
+}
+
+/* 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;
+
+ xml_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