]> wimlib.net Git - wimlib/blobdiff - include/wimlib.h
v1.14.4
[wimlib] / include / wimlib.h
index c032429d6e9d1863fd72f2273f7bcee55b5f0e86..84f1e2eca6742dafb8bad725a02beaf6efdfcd39 100644 (file)
 /**
  * @mainpage
  *
 /**
  * @mainpage
  *
- * This is the documentation for the library interface of wimlib 1.13.5, a C
+ * This is the documentation for the library interface of wimlib 1.14.4, a C
  * library for creating, modifying, extracting, and mounting files in the
  * Windows Imaging (WIM) format.  This documentation is intended for developers
  * only.  If you have installed wimlib and want to know how to use the @b
  * wimlib-imagex program, please see the manual pages and also the <a
  * library for creating, modifying, extracting, and mounting files in the
  * Windows Imaging (WIM) format.  This documentation is intended for developers
  * only.  If you have installed wimlib and want to know how to use the @b
  * wimlib-imagex program, please see the manual pages and also the <a
- * href="https://wimlib.net/git/?p=wimlib;a=blob;f=README">README file</a>.
+ * href="https://wimlib.net/git/?p=wimlib;a=blob;f=README.md">README file</a>.
  *
  * @section sec_installing Installing
  *
  *
  * @section sec_installing Installing
  *
@@ -30,9 +30,8 @@
  * @subsection Windows
  *
  * Download the Windows binary distribution with the appropriate architecture
  * @subsection Windows
  *
  * Download the Windows binary distribution with the appropriate architecture
- * (i686 or x86_64 --- also called "x86" and "amd64" respectively) from
- * https://wimlib.net.  Link your program with libwim-15.dll.  If needed by your
- * programming language or development environment, the import library
+ * from https://wimlib.net.  Link your program with libwim-15.dll.  If needed by
+ * your programming language or development environment, the import library
  * libwim.lib and C/C++ header wimlib.h can be found in the directory "devel" in
  * the ZIP file.
  *
  * libwim.lib and C/C++ header wimlib.h can be found in the directory "devel" in
  * the ZIP file.
  *
 #include <stdint.h>
 #include <time.h>
 
 #include <stdint.h>
 #include <time.h>
 
+#ifdef BUILDING_WIMLIB
+  /*
+   * On i386, gcc assumes that the stack is 16-byte aligned at function entry.
+   * However, some compilers (e.g. MSVC) and programming languages (e.g. Delphi)
+   * only guarantee 4-byte alignment when calling functions.  This is mainly an
+   * issue on Windows, but it can occur on Linux too.  Work around this ABI
+   * incompatibility by realigning the stack pointer when entering the library.
+   * This prevents crashes in SSE/AVX code.
+   */
+#  if defined(__GNUC__) && defined(__i386__)
+#    define WIMLIB_ALIGN_STACK  __attribute__((force_align_arg_pointer))
+#  else
+#    define WIMLIB_ALIGN_STACK
+#  endif
+#  ifdef _WIN32
+#    define WIMLIBAPI __declspec(dllexport) WIMLIB_ALIGN_STACK
+#  else
+#    define WIMLIBAPI __attribute__((visibility("default"))) WIMLIB_ALIGN_STACK
+#  endif
+#else
+#  define WIMLIBAPI
+#endif
+
 /** @addtogroup G_general
  * @{ */
 
 /** @addtogroup G_general
  * @{ */
 
 #define WIMLIB_MAJOR_VERSION 1
 
 /** Minor version of the library (for example, the 2 in 1.2.5). */
 #define WIMLIB_MAJOR_VERSION 1
 
 /** Minor version of the library (for example, the 2 in 1.2.5). */
-#define WIMLIB_MINOR_VERSION 13
+#define WIMLIB_MINOR_VERSION 14
 
 /** Patch version of the library (for example, the 5 in 1.2.5). */
 
 /** Patch version of the library (for example, the 5 in 1.2.5). */
-#define WIMLIB_PATCH_VERSION 5
+#define WIMLIB_PATCH_VERSION 4
 
 #ifdef __cplusplus
 extern "C" {
 
 #ifdef __cplusplus
 extern "C" {
@@ -1399,20 +1421,23 @@ struct wimlib_wim_info {
  *    sha1_hash.  This case can only occur with wimlib_iterate_dir_tree(), never
  *    wimlib_iterate_lookup_table().
  *
  *    sha1_hash.  This case can only occur with wimlib_iterate_dir_tree(), never
  *    wimlib_iterate_lookup_table().
  *
- * 2. Otherwise we know the sha1_hash, the uncompressed_size, the
- *    reference_count, and the is_metadata flag.  In addition:
+ * 2. Otherwise we know the uncompressed_size, the reference_count, and the
+ *    is_metadata flag.  In addition:
  *
  *    A. If the blob is located in a non-solid WIM resource, then we also know
  *
  *    A. If the blob is located in a non-solid WIM resource, then we also know
- *       the compressed_size and offset.
+ *       the sha1_hash, compressed_size, and offset.
  *
  *    B. If the blob is located in a solid WIM resource, then we also know the
  *
  *    B. If the blob is located in a solid WIM resource, then we also know the
- *       offset, raw_resource_offset_in_wim, raw_resource_compressed_size, and
- *       raw_resource_uncompressed_size.  But the "offset" is actually the
- *       offset in the uncompressed solid resource rather than the offset from
- *       the beginning of the WIM file.
+ *       sha1_hash, offset, raw_resource_offset_in_wim,
+ *       raw_resource_compressed_size, and raw_resource_uncompressed_size.  But
+ *       the "offset" is actually the offset in the uncompressed solid resource
+ *       rather than the offset from the beginning of the WIM file.
  *
  *
- *    C. If the blob is *not* located in any type of WIM resource, then we don't
- *       know any additional information.
+ *    C. If the blob is *not* located in any type of WIM resource, for example
+ *       if it's in a external file that was scanned by wimlib_add_image(), then
+ *       we usually won't know any more information.  The sha1_hash might be
+ *       known, and prior to wimlib v1.13.6 it always was; however, in wimlib
+ *       v1.13.6 and later, the sha1_hash might not be known in this case.
  *
  * Unknown or irrelevant fields are left zeroed.
  */
  *
  * Unknown or irrelevant fields are left zeroed.
  */
@@ -1432,7 +1457,8 @@ struct wimlib_resource_entry {
         * of this blob within that solid resource when uncompressed.  */
        uint64_t offset;
 
         * of this blob within that solid resource when uncompressed.  */
        uint64_t offset;
 
-       /** The SHA-1 message digest of the blob's uncompressed contents.  */
+       /** If this blob is located in a WIM resource, then this is the SHA-1
+        * message digest of the blob's uncompressed contents.  */
        uint8_t sha1_hash[20];
 
        /** If this blob is located in a WIM resource, then this is the part
        uint8_t sha1_hash[20];
 
        /** If this blob is located in a WIM resource, then this is the part
@@ -2634,7 +2660,7 @@ enum wimlib_error_code {
  * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION
  *     The WIM already contains an image with the requested name.
  */
  * @retval ::WIMLIB_ERR_IMAGE_NAME_COLLISION
  *     The WIM already contains an image with the requested name.
  */
-extern int
+WIMLIBAPI int
 wimlib_add_empty_image(WIMStruct *wim,
                       const wimlib_tchar *name,
                       int *new_idx_ret);
 wimlib_add_empty_image(WIMStruct *wim,
                       const wimlib_tchar *name,
                       int *new_idx_ret);
@@ -2690,7 +2716,7 @@ wimlib_add_empty_image(WIMStruct *wim,
  * In addition, if ::WIMLIB_ADD_FLAG_VERBOSE is specified in @p add_flags, it
  * will receive ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY.
  */
  * In addition, if ::WIMLIB_ADD_FLAG_VERBOSE is specified in @p add_flags, it
  * will receive ::WIMLIB_PROGRESS_MSG_SCAN_DENTRY.
  */
-extern int
+WIMLIBAPI int
 wimlib_add_image(WIMStruct *wim,
                 const wimlib_tchar *source,
                 const wimlib_tchar *name,
 wimlib_add_image(WIMStruct *wim,
                 const wimlib_tchar *source,
                 const wimlib_tchar *name,
@@ -2707,7 +2733,7 @@ wimlib_add_image(WIMStruct *wim,
  * same as wimlib_add_image().  See the documentation for <b>wimcapture</b> for
  * full details on how this mode works.
  */
  * same as wimlib_add_image().  See the documentation for <b>wimcapture</b> for
  * full details on how this mode works.
  */
-extern int
+WIMLIBAPI int
 wimlib_add_image_multisource(WIMStruct *wim,
                             const struct wimlib_capture_source *sources,
                             size_t num_sources,
 wimlib_add_image_multisource(WIMStruct *wim,
                             const struct wimlib_capture_source *sources,
                             size_t num_sources,
@@ -2724,7 +2750,7 @@ wimlib_add_image_multisource(WIMStruct *wim,
  * This just builds an appropriate ::wimlib_add_command and passes it to
  * wimlib_update_image().
  */
  * This just builds an appropriate ::wimlib_add_command and passes it to
  * wimlib_update_image().
  */
-extern int
+WIMLIBAPI int
 wimlib_add_tree(WIMStruct *wim, int image,
                const wimlib_tchar *fs_source_path,
                const wimlib_tchar *wim_target_path, int add_flags);
 wimlib_add_tree(WIMStruct *wim, int image,
                const wimlib_tchar *fs_source_path,
                const wimlib_tchar *wim_target_path, int add_flags);
@@ -2757,7 +2783,7 @@ wimlib_add_tree(WIMStruct *wim, int image,
  * @retval ::WIMLIB_ERR_NOMEM
  *     Insufficient memory to allocate a new ::WIMStruct.
  */
  * @retval ::WIMLIB_ERR_NOMEM
  *     Insufficient memory to allocate a new ::WIMStruct.
  */
-extern int
+WIMLIBAPI int
 wimlib_create_new_wim(enum wimlib_compression_type ctype, WIMStruct **wim_ret);
 
 /**
 wimlib_create_new_wim(enum wimlib_compression_type ctype, WIMStruct **wim_ret);
 
 /**
@@ -2788,7 +2814,7 @@ wimlib_create_new_wim(enum wimlib_compression_type ctype, WIMStruct **wim_ret);
  * If this function fails when @p image was ::WIMLIB_ALL_IMAGES, then it's
  * possible that some but not all of the images were deleted.
  */
  * If this function fails when @p image was ::WIMLIB_ALL_IMAGES, then it's
  * possible that some but not all of the images were deleted.
  */
-extern int
+WIMLIBAPI int
 wimlib_delete_image(WIMStruct *wim, int image);
 
 /**
 wimlib_delete_image(WIMStruct *wim, int image);
 
 /**
@@ -2799,7 +2825,7 @@ wimlib_delete_image(WIMStruct *wim, int image);
  * This just builds an appropriate ::wimlib_delete_command and passes it to
  * wimlib_update_image().
  */
  * This just builds an appropriate ::wimlib_delete_command and passes it to
  * wimlib_update_image().
  */
-extern int
+WIMLIBAPI int
 wimlib_delete_path(WIMStruct *wim, int image,
                   const wimlib_tchar *path, int delete_flags);
 
 wimlib_delete_path(WIMStruct *wim, int image,
                   const wimlib_tchar *path, int delete_flags);
 
@@ -2871,7 +2897,7 @@ wimlib_delete_path(WIMStruct *wim, int image,
  * indicate failure (for different reasons) to read the metadata resource for an
  * image in @p src_wim that needed to be exported.
  */
  * indicate failure (for different reasons) to read the metadata resource for an
  * image in @p src_wim that needed to be exported.
  */
-extern int
+WIMLIBAPI int
 wimlib_export_image(WIMStruct *src_wim, int src_image,
                    WIMStruct *dest_wim,
                    const wimlib_tchar *dest_name,
 wimlib_export_image(WIMStruct *src_wim, int src_image,
                    WIMStruct *dest_wim,
                    const wimlib_tchar *dest_name,
@@ -2990,7 +3016,7 @@ wimlib_export_image(WIMStruct *src_wim, int src_image,
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_METADATA messages, then
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END.
  */
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_METADATA messages, then
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END.
  */
-extern int
+WIMLIBAPI int
 wimlib_extract_image(WIMStruct *wim, int image,
                     const wimlib_tchar *target, int extract_flags);
 
 wimlib_extract_image(WIMStruct *wim, int image,
                     const wimlib_tchar *target, int extract_flags);
 
@@ -3032,7 +3058,7 @@ wimlib_extract_image(WIMStruct *wim, int image,
  * @retval ::WIMLIB_ERR_NOT_PIPABLE
  *     The WIM being piped over @p pipe_fd is a normal WIM, not a pipable WIM.
  */
  * @retval ::WIMLIB_ERR_NOT_PIPABLE
  *     The WIM being piped over @p pipe_fd is a normal WIM, not a pipable WIM.
  */
-extern int
+WIMLIBAPI int
 wimlib_extract_image_from_pipe(int pipe_fd,
                               const wimlib_tchar *image_num_or_name,
                               const wimlib_tchar *target, int extract_flags);
 wimlib_extract_image_from_pipe(int pipe_fd,
                               const wimlib_tchar *image_num_or_name,
                               const wimlib_tchar *target, int extract_flags);
@@ -3046,7 +3072,7 @@ wimlib_extract_image_from_pipe(int pipe_fd,
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, in addition to
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN.
  */
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS, in addition to
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_SPWM_PART_BEGIN.
  */
-extern int
+WIMLIBAPI int
 wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
                                             const wimlib_tchar *image_num_or_name,
                                             const wimlib_tchar *target,
 wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
                                             const wimlib_tchar *image_num_or_name,
                                             const wimlib_tchar *target,
@@ -3073,7 +3099,7 @@ wimlib_extract_image_from_pipe_with_progress(int pipe_fd,
  * cannot read the path list file (e.g. ::WIMLIB_ERR_OPEN, ::WIMLIB_ERR_STAT,
  * ::WIMLIB_ERR_READ).
  */
  * cannot read the path list file (e.g. ::WIMLIB_ERR_OPEN, ::WIMLIB_ERR_STAT,
  * ::WIMLIB_ERR_READ).
  */
-extern int
+WIMLIBAPI int
 wimlib_extract_pathlist(WIMStruct *wim, int image,
                        const wimlib_tchar *target,
                        const wimlib_tchar *path_list_file,
 wimlib_extract_pathlist(WIMStruct *wim, int image,
                        const wimlib_tchar *target,
                        const wimlib_tchar *path_list_file,
@@ -3148,7 +3174,7 @@ wimlib_extract_pathlist(WIMStruct *wim, int image,
  * If a progress function is registered with @p wim, then it will receive
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS.
  */
  * If a progress function is registered with @p wim, then it will receive
  * ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS.
  */
-extern int
+WIMLIBAPI int
 wimlib_extract_paths(WIMStruct *wim,
                     int image,
                     const wimlib_tchar *target,
 wimlib_extract_paths(WIMStruct *wim,
                     int image,
                     const wimlib_tchar *target,
@@ -3170,7 +3196,7 @@ wimlib_extract_paths(WIMStruct *wim,
  * @retval ::WIMLIB_ERR_WRITE
  *     Failed to write the data to the requested file.
  */
  * @retval ::WIMLIB_ERR_WRITE
  *     Failed to write the data to the requested file.
  */
-extern int
+WIMLIBAPI int
 wimlib_extract_xml_data(WIMStruct *wim, FILE *fp);
 
 /**
 wimlib_extract_xml_data(WIMStruct *wim, FILE *fp);
 
 /**
@@ -3185,7 +3211,7 @@ wimlib_extract_xml_data(WIMStruct *wim, FILE *fp);
  * @param wim
  *     Pointer to the ::WIMStruct to release.  If @c NULL, no action is taken.
  */
  * @param wim
  *     Pointer to the ::WIMStruct to release.  If @c NULL, no action is taken.
  */
-extern void
+WIMLIBAPI void
 wimlib_free(WIMStruct *wim);
 
 /**
 wimlib_free(WIMStruct *wim);
 
 /**
@@ -3201,7 +3227,7 @@ wimlib_free(WIMStruct *wim);
  *     "None", "LZX", or "XPRESS".  If the value was unrecognized, then
  *     the resulting string will be "Invalid".
  */
  *     "None", "LZX", or "XPRESS".  If the value was unrecognized, then
  *     the resulting string will be "Invalid".
  */
-extern const wimlib_tchar *
+WIMLIBAPI const wimlib_tchar *
 wimlib_get_compression_type_string(enum wimlib_compression_type ctype);
 
 /**
 wimlib_get_compression_type_string(enum wimlib_compression_type ctype);
 
 /**
@@ -3217,7 +3243,7 @@ wimlib_get_compression_type_string(enum wimlib_compression_type ctype);
  *     the value was unrecognized, then the resulting string will be "Unknown
  *     error".
  */
  *     the value was unrecognized, then the resulting string will be "Unknown
  *     error".
  */
-extern const wimlib_tchar *
+WIMLIBAPI const wimlib_tchar *
 wimlib_get_error_string(enum wimlib_error_code code);
 
 /**
 wimlib_get_error_string(enum wimlib_error_code code);
 
 /**
@@ -3226,7 +3252,7 @@ wimlib_get_error_string(enum wimlib_error_code code);
  * Get the description of the specified image.  Equivalent to
  * <tt>wimlib_get_image_property(wim, image, "DESCRIPTION")</tt>.
  */
  * Get the description of the specified image.  Equivalent to
  * <tt>wimlib_get_image_property(wim, image, "DESCRIPTION")</tt>.
  */
-extern const wimlib_tchar *
+WIMLIBAPI const wimlib_tchar *
 wimlib_get_image_description(const WIMStruct *wim, int image);
 
 /**
 wimlib_get_image_description(const WIMStruct *wim, int image);
 
 /**
@@ -3237,7 +3263,7 @@ wimlib_get_image_description(const WIMStruct *wim, int image);
  * wimlib_get_image_name() will return an empty string if the image is unnamed
  * whereas wimlib_get_image_property() may return @c NULL in that case.
  */
  * wimlib_get_image_name() will return an empty string if the image is unnamed
  * whereas wimlib_get_image_property() may return @c NULL in that case.
  */
-extern const wimlib_tchar *
+WIMLIBAPI const wimlib_tchar *
 wimlib_get_image_name(const WIMStruct *wim, int image);
 
 /**
 wimlib_get_image_name(const WIMStruct *wim, int image);
 
 /**
@@ -3268,7 +3294,7 @@ wimlib_get_image_name(const WIMStruct *wim, int image);
  *     no such property.  The string may not remain valid after later library
  *     calls, so the caller should duplicate it if needed.
  */
  *     no such property.  The string may not remain valid after later library
  *     calls, so the caller should duplicate it if needed.
  */
-extern const wimlib_tchar *
+WIMLIBAPI const wimlib_tchar *
 wimlib_get_image_property(const WIMStruct *wim, int image,
                          const wimlib_tchar *property_name);
 
 wimlib_get_image_property(const WIMStruct *wim, int image,
                          const wimlib_tchar *property_name);
 
@@ -3283,7 +3309,7 @@ wimlib_get_image_property(const WIMStruct *wim, int image,
  * 20) | (WIMLIB_MINOR_VERSION << 10) | WIMLIB_PATCH_VERSION)</c> for the
  * corresponding header file.
  */
  * 20) | (WIMLIB_MINOR_VERSION << 10) | WIMLIB_PATCH_VERSION)</c> for the
  * corresponding header file.
  */
-extern uint32_t
+WIMLIBAPI uint32_t
 wimlib_get_version(void);
 
 /**
 wimlib_get_version(void);
 
 /**
@@ -3293,7 +3319,7 @@ wimlib_get_version(void);
  * PACKAGE_VERSION string that was set at build time.  (This allows a beta
  * release to be distinguished from an official release.)
  */
  * PACKAGE_VERSION string that was set at build time.  (This allows a beta
  * release to be distinguished from an official release.)
  */
-extern const wimlib_tchar *
+WIMLIBAPI const wimlib_tchar *
 wimlib_get_version_string(void);
 
 /**
 wimlib_get_version_string(void);
 
 /**
@@ -3310,7 +3336,7 @@ wimlib_get_version_string(void);
  *
  * @return 0
  */
  *
  * @return 0
  */
-extern int
+WIMLIBAPI int
 wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info);
 
 /**
 wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info);
 
 /**
@@ -3340,7 +3366,7 @@ wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info);
  * @retval ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE
  *     Failed to read the XML document from the WIM file.
  */
  * @retval ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE
  *     Failed to read the XML document from the WIM file.
  */
-extern int
+WIMLIBAPI int
 wimlib_get_xml_data(WIMStruct *wim, void **buf_ret, size_t *bufsize_ret);
 
 /**
 wimlib_get_xml_data(WIMStruct *wim, void **buf_ret, size_t *bufsize_ret);
 
 /**
@@ -3361,7 +3387,7 @@ wimlib_get_xml_data(WIMStruct *wim, void **buf_ret, size_t *bufsize_ret);
  *     ::WIMLIB_INIT_FLAG_STRICT_CAPTURE_PRIVILEGES were specified in @p
  *     init_flags, but the corresponding privileges could not be acquired.
  */
  *     ::WIMLIB_INIT_FLAG_STRICT_CAPTURE_PRIVILEGES were specified in @p
  *     init_flags, but the corresponding privileges could not be acquired.
  */
-extern int
+WIMLIBAPI int
 wimlib_global_init(int init_flags);
 
 /**
 wimlib_global_init(int init_flags);
 
 /**
@@ -3370,7 +3396,7 @@ wimlib_global_init(int init_flags);
  * Cleanup function for wimlib.  You are not required to call this function, but
  * it will release any global resources allocated by the library.
  */
  * Cleanup function for wimlib.  You are not required to call this function, but
  * it will release any global resources allocated by the library.
  */
-extern void
+WIMLIBAPI void
 wimlib_global_cleanup(void);
 
 /**
 wimlib_global_cleanup(void);
 
 /**
@@ -3389,7 +3415,7 @@ wimlib_global_cleanup(void);
  *     if there is no image named @p name in @p wim.  If @p name is @c NULL or
  *     the empty string, then @c false is returned.
  */
  *     if there is no image named @p name in @p wim.  If @p name is @c NULL or
  *     the empty string, then @c false is returned.
  */
-extern bool
+WIMLIBAPI bool
 wimlib_image_name_in_use(const WIMStruct *wim, const wimlib_tchar *name);
 
 /**
 wimlib_image_name_in_use(const WIMStruct *wim, const wimlib_tchar *name);
 
 /**
@@ -3436,7 +3462,7 @@ wimlib_image_name_in_use(const WIMStruct *wim, const wimlib_tchar *name);
  * indicate failure (for different reasons) to read the metadata resource for an
  * image over which iteration needed to be done.
  */
  * indicate failure (for different reasons) to read the metadata resource for an
  * image over which iteration needed to be done.
  */
-extern int
+WIMLIBAPI int
 wimlib_iterate_dir_tree(WIMStruct *wim, int image, const wimlib_tchar *path,
                        int flags,
                        wimlib_iterate_dir_tree_callback_t cb, void *user_ctx);
 wimlib_iterate_dir_tree(WIMStruct *wim, int image, const wimlib_tchar *path,
                        int flags,
                        wimlib_iterate_dir_tree_callback_t cb, void *user_ctx);
@@ -3470,7 +3496,7 @@ wimlib_iterate_dir_tree(WIMStruct *wim, int image, const wimlib_tchar *path,
  * @return 0 if all calls to @p cb returned 0; otherwise the first nonzero value
  * that was returned from @p cb.
  */
  * @return 0 if all calls to @p cb returned 0; otherwise the first nonzero value
  * that was returned from @p cb.
  */
-extern int
+WIMLIBAPI int
 wimlib_iterate_lookup_table(WIMStruct *wim, int flags,
                            wimlib_iterate_lookup_table_callback_t cb,
                            void *user_ctx);
 wimlib_iterate_lookup_table(WIMStruct *wim, int flags,
                            wimlib_iterate_lookup_table_callback_t cb,
                            void *user_ctx);
@@ -3511,7 +3537,7 @@ wimlib_iterate_lookup_table(WIMStruct *wim, int flags,
  * an easy-to-use wrapper around this that has some advantages (e.g.  extra
  * sanity checks).
  */
  * an easy-to-use wrapper around this that has some advantages (e.g.  extra
  * sanity checks).
  */
-extern int
+WIMLIBAPI int
 wimlib_join(const wimlib_tchar * const *swms,
            unsigned num_swms,
            const wimlib_tchar *output_path,
 wimlib_join(const wimlib_tchar * const *swms,
            unsigned num_swms,
            const wimlib_tchar *output_path,
@@ -3529,7 +3555,7 @@ wimlib_join(const wimlib_tchar * const *swms,
  * ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY messages when each of the split WIM
  * parts is opened.
  */
  * ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY messages when each of the split WIM
  * parts is opened.
  */
-extern int
+WIMLIBAPI int
 wimlib_join_with_progress(const wimlib_tchar * const *swms,
                          unsigned num_swms,
                          const wimlib_tchar *output_path,
 wimlib_join_with_progress(const wimlib_tchar * const *swms,
                          unsigned num_swms,
                          const wimlib_tchar *output_path,
@@ -3538,6 +3564,24 @@ wimlib_join_with_progress(const wimlib_tchar * const *swms,
                          wimlib_progress_func_t progfunc,
                          void *progctx);
 
                          wimlib_progress_func_t progfunc,
                          void *progctx);
 
+/**
+ * @ingroup G_general
+ *
+ * Load a UTF-8 or UTF-16LE encoded text file into memory.
+ *
+ * @param path
+ *     The path to the file, or NULL or "-" to use standard input.
+ * @param tstr_ret
+ *     On success, a buffer containing the file's text as a "wimlib_tchar"
+ *     string is returned here.  The buffer must be freed using free().
+ * @param tstr_nchars_ret
+ *     On success, the length of the text in "wimlib_tchar"s is returned here.
+ *
+ * @return 0 on success; a ::wimlib_error_code value on failure.
+ */
+WIMLIBAPI int
+wimlib_load_text_file(const wimlib_tchar *path,
+                     wimlib_tchar **tstr_ret, size_t *tstr_nchars_ret);
 
 /**
  * @ingroup G_mounting_wim_images
 
 /**
  * @ingroup G_mounting_wim_images
@@ -3614,7 +3658,7 @@ wimlib_join_with_progress(const wimlib_tchar * const *swms,
  * To unmount the image, call wimlib_unmount_image().  This may be done in a
  * different process.
  */
  * To unmount the image, call wimlib_unmount_image().  This may be done in a
  * different process.
  */
-extern int
+WIMLIBAPI int
 wimlib_mount_image(WIMStruct *wim,
                   int image,
                   const wimlib_tchar *dir,
 wimlib_mount_image(WIMStruct *wim,
                   int image,
                   const wimlib_tchar *dir,
@@ -3690,7 +3734,7 @@ wimlib_mount_image(WIMStruct *wim,
  * @retval ::WIMLIB_ERR_XML
  *     The XML data of the WIM was invalid.
  */
  * @retval ::WIMLIB_ERR_XML
  *     The XML data of the WIM was invalid.
  */
-extern int
+WIMLIBAPI int
 wimlib_open_wim(const wimlib_tchar *wim_file,
                int open_flags,
                WIMStruct **wim_ret);
 wimlib_open_wim(const wimlib_tchar *wim_file,
                int open_flags,
                WIMStruct **wim_ret);
@@ -3706,7 +3750,7 @@ wimlib_open_wim(const wimlib_tchar *wim_file,
  * progress function will receive ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY
  * messages while checking the WIM file's integrity.
  */
  * progress function will receive ::WIMLIB_PROGRESS_MSG_VERIFY_INTEGRITY
  * messages while checking the WIM file's integrity.
  */
-extern int
+WIMLIBAPI int
 wimlib_open_wim_with_progress(const wimlib_tchar *wim_file,
                              int open_flags,
                              WIMStruct **wim_ret,
 wimlib_open_wim_with_progress(const wimlib_tchar *wim_file,
                              int open_flags,
                              WIMStruct **wim_ret,
@@ -3772,7 +3816,7 @@ wimlib_open_wim_with_progress(const wimlib_tchar *wim_file,
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, and
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END.
  */
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, and
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END.
  */
-extern int
+WIMLIBAPI int
 wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads);
 
 /**
 wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads);
 
 /**
@@ -3795,7 +3839,7 @@ wimlib_overwrite(WIMStruct *wim, int write_flags, unsigned num_threads);
  * This function is deprecated; use wimlib_get_xml_data() or
  * wimlib_get_image_property() to query image information instead.
  */
  * This function is deprecated; use wimlib_get_xml_data() or
  * wimlib_get_image_property() to query image information instead.
  */
-extern void
+WIMLIBAPI void
 wimlib_print_available_images(const WIMStruct *wim, int image);
 
 /**
 wimlib_print_available_images(const WIMStruct *wim, int image);
 
 /**
@@ -3803,7 +3847,7 @@ wimlib_print_available_images(const WIMStruct *wim, int image);
  *
  * Print the header of the WIM file (intended for debugging only).
  */
  *
  * Print the header of the WIM file (intended for debugging only).
  */
-extern void
+WIMLIBAPI void
 wimlib_print_header(const WIMStruct *wim);
 
 /**
 wimlib_print_header(const WIMStruct *wim);
 
 /**
@@ -3847,7 +3891,7 @@ wimlib_print_header(const WIMStruct *wim);
  * This function can additionally return most values that can be returned by
  * wimlib_open_wim().
  */
  * This function can additionally return most values that can be returned by
  * wimlib_open_wim().
  */
-extern int
+WIMLIBAPI int
 wimlib_reference_resource_files(WIMStruct *wim,
                                const wimlib_tchar * const *resource_wimfiles_or_globs,
                                unsigned count,
 wimlib_reference_resource_files(WIMStruct *wim,
                                const wimlib_tchar * const *resource_wimfiles_or_globs,
                                unsigned count,
@@ -3874,7 +3918,7 @@ wimlib_reference_resource_files(WIMStruct *wim,
  *
  * @return 0 on success; a ::wimlib_error_code value on failure.
  */
  *
  * @return 0 on success; a ::wimlib_error_code value on failure.
  */
-extern int
+WIMLIBAPI int
 wimlib_reference_resources(WIMStruct *wim, WIMStruct **resource_wims,
                           unsigned num_resource_wims, int ref_flags);
 
 wimlib_reference_resources(WIMStruct *wim, WIMStruct **resource_wims,
                           unsigned num_resource_wims, int ref_flags);
 
@@ -3940,7 +3984,7 @@ wimlib_reference_resources(WIMStruct *wim, WIMStruct **resource_wims,
  * indicate failure (for different reasons) to read the metadata resource for
  * the template image.
  */
  * indicate failure (for different reasons) to read the metadata resource for
  * the template image.
  */
-extern int
+WIMLIBAPI int
 wimlib_reference_template_image(WIMStruct *wim, int new_image,
                                WIMStruct *template_wim, int template_image,
                                int flags);
 wimlib_reference_template_image(WIMStruct *wim, int new_image,
                                WIMStruct *template_wim, int template_image,
                                int flags);
@@ -3960,7 +4004,7 @@ wimlib_reference_template_image(WIMStruct *wim, int new_image,
  *     The value which will be passed as the third argument to calls to @p
  *     progfunc.
  */
  *     The value which will be passed as the third argument to calls to @p
  *     progfunc.
  */
-extern void
+WIMLIBAPI void
 wimlib_register_progress_function(WIMStruct *wim,
                                  wimlib_progress_func_t progfunc,
                                  void *progctx);
 wimlib_register_progress_function(WIMStruct *wim,
                                  wimlib_progress_func_t progfunc,
                                  void *progctx);
@@ -3974,7 +4018,7 @@ wimlib_register_progress_function(WIMStruct *wim,
  * This just builds an appropriate ::wimlib_rename_command and passes it to
  * wimlib_update_image().
  */
  * This just builds an appropriate ::wimlib_rename_command and passes it to
  * wimlib_update_image().
  */
-extern int
+WIMLIBAPI int
 wimlib_rename_path(WIMStruct *wim, int image,
                   const wimlib_tchar *source_path, const wimlib_tchar *dest_path);
 
 wimlib_rename_path(WIMStruct *wim, int image,
                   const wimlib_tchar *source_path, const wimlib_tchar *dest_path);
 
@@ -4008,7 +4052,7 @@ wimlib_rename_path(WIMStruct *wim, int image,
  *     images, an unnamed image must be specified by index to eliminate the
  *     ambiguity.)
  */
  *     images, an unnamed image must be specified by index to eliminate the
  *     ambiguity.)
  */
-extern int
+WIMLIBAPI int
 wimlib_resolve_image(WIMStruct *wim,
                     const wimlib_tchar *image_name_or_num);
 
 wimlib_resolve_image(WIMStruct *wim,
                     const wimlib_tchar *image_name_or_num);
 
@@ -4024,12 +4068,9 @@ wimlib_resolve_image(WIMStruct *wim,
  * This also enables error messages, as if by a call to
  * wimlib_set_print_errors(true).
  *
  * This also enables error messages, as if by a call to
  * wimlib_set_print_errors(true).
  *
- * @return 0 on success; a ::wimlib_error_code value on failure.
- *
- * @retval ::WIMLIB_ERR_UNSUPPORTED
- *     wimlib was compiled using the <c>--without-error-messages</c> option.
+ * @return 0
  */
  */
-extern int
+WIMLIBAPI int
 wimlib_set_error_file(FILE *fp);
 
 /**
 wimlib_set_error_file(FILE *fp);
 
 /**
@@ -4045,10 +4086,8 @@ wimlib_set_error_file(FILE *fp);
  *
  * @retval ::WIMLIB_ERR_OPEN
  *     The file named by @p path could not be opened for appending.
  *
  * @retval ::WIMLIB_ERR_OPEN
  *     The file named by @p path could not be opened for appending.
- * @retval ::WIMLIB_ERR_UNSUPPORTED
- *     wimlib was compiled using the <c>--without-error-messages</c> option.
  */
  */
-extern int
+WIMLIBAPI int
 wimlib_set_error_file_by_name(const wimlib_tchar *path);
 
 /**
 wimlib_set_error_file_by_name(const wimlib_tchar *path);
 
 /**
@@ -4059,7 +4098,7 @@ wimlib_set_error_file_by_name(const wimlib_tchar *path);
  *
  * Note that "description" is misspelled in the name of this function.
  */
  *
  * Note that "description" is misspelled in the name of this function.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_image_descripton(WIMStruct *wim, int image,
                            const wimlib_tchar *description);
 
 wimlib_set_image_descripton(WIMStruct *wim, int image,
                            const wimlib_tchar *description);
 
@@ -4070,7 +4109,7 @@ wimlib_set_image_descripton(WIMStruct *wim, int image,
  * (usually something like "Core" or "Ultimate").  Equivalent to
  * <tt>wimlib_set_image_property(wim, image, "FLAGS", flags)</tt>.
  */
  * (usually something like "Core" or "Ultimate").  Equivalent to
  * <tt>wimlib_set_image_property(wim, image, "FLAGS", flags)</tt>.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_image_flags(WIMStruct *wim, int image, const wimlib_tchar *flags);
 
 /**
 wimlib_set_image_flags(WIMStruct *wim, int image, const wimlib_tchar *flags);
 
 /**
@@ -4079,7 +4118,7 @@ wimlib_set_image_flags(WIMStruct *wim, int image, const wimlib_tchar *flags);
  * Change the name of a WIM image.  Equivalent to
  * <tt>wimlib_set_image_property(wim, image, "NAME", name)</tt>.
  */
  * Change the name of a WIM image.  Equivalent to
  * <tt>wimlib_set_image_property(wim, image, "NAME", name)</tt>.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_image_name(WIMStruct *wim, int image, const wimlib_tchar *name);
 
 /**
 wimlib_set_image_name(WIMStruct *wim, int image, const wimlib_tchar *name);
 
 /**
@@ -4119,7 +4158,7 @@ wimlib_set_image_name(WIMStruct *wim, int image, const wimlib_tchar *name);
  *     @p property_name has an unsupported format, or @p property_name included
  *     a bracketed index that was too high.
  */
  *     @p property_name has an unsupported format, or @p property_name included
  *     a bracketed index that was too high.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_image_property(WIMStruct *wim, int image,
                          const wimlib_tchar *property_name,
                          const wimlib_tchar *property_value);
 wimlib_set_image_property(WIMStruct *wim, int image,
                          const wimlib_tchar *property_name,
                          const wimlib_tchar *property_value);
@@ -4152,7 +4191,7 @@ wimlib_set_image_property(WIMStruct *wim, int image,
  *
  * @return 0
  */
  *
  * @return 0
  */
-extern int
+WIMLIBAPI int
 wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
                            void (*free_func)(void *),
                            void *(*realloc_func)(void *, size_t));
 wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
                            void (*free_func)(void *),
                            void *(*realloc_func)(void *, size_t));
@@ -4182,7 +4221,7 @@ wimlib_set_memory_allocator(void *(*malloc_func)(size_t),
  *     @p chunk_size was not 0 or a supported chunk size for the currently
  *     selected output compression type.
  */
  *     @p chunk_size was not 0 or a supported chunk size for the currently
  *     selected output compression type.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_output_chunk_size(WIMStruct *wim, uint32_t chunk_size);
 
 /**
 wimlib_set_output_chunk_size(WIMStruct *wim, uint32_t chunk_size);
 
 /**
@@ -4191,7 +4230,7 @@ wimlib_set_output_chunk_size(WIMStruct *wim, uint32_t chunk_size);
  * Similar to wimlib_set_output_chunk_size(), but set the chunk size for writing
  * solid resources.
  */
  * Similar to wimlib_set_output_chunk_size(), but set the chunk size for writing
  * solid resources.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_output_pack_chunk_size(WIMStruct *wim, uint32_t chunk_size);
 
 /**
 wimlib_set_output_pack_chunk_size(WIMStruct *wim, uint32_t chunk_size);
 
 /**
@@ -4213,7 +4252,7 @@ wimlib_set_output_pack_chunk_size(WIMStruct *wim, uint32_t chunk_size);
  * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
  *     @p ctype did not specify a valid compression type.
  */
  * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
  *     @p ctype did not specify a valid compression type.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_output_compression_type(WIMStruct *wim,
                                   enum wimlib_compression_type ctype);
 
 wimlib_set_output_compression_type(WIMStruct *wim,
                                   enum wimlib_compression_type ctype);
 
@@ -4223,7 +4262,7 @@ wimlib_set_output_compression_type(WIMStruct *wim,
  * Similar to wimlib_set_output_compression_type(), but set the compression type
  * for writing solid resources.  This cannot be ::WIMLIB_COMPRESSION_TYPE_NONE.
  */
  * Similar to wimlib_set_output_compression_type(), but set the compression type
  * for writing solid resources.  This cannot be ::WIMLIB_COMPRESSION_TYPE_NONE.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_output_pack_compression_type(WIMStruct *wim,
                                        enum wimlib_compression_type ctype);
 
 wimlib_set_output_pack_compression_type(WIMStruct *wim,
                                        enum wimlib_compression_type ctype);
 
@@ -4244,12 +4283,9 @@ wimlib_set_output_pack_compression_type(WIMStruct *wim,
  *     @c true if messages are to be printed; @c false if messages are not to
  *     be printed.
  *
  *     @c true if messages are to be printed; @c false if messages are not to
  *     be printed.
  *
- * @return 0 on success; a ::wimlib_error_code value on failure.
- *
- * @retval ::WIMLIB_ERR_UNSUPPORTED
- *     wimlib was compiled using the <c>--without-error-messages</c> option.
+ * @return 0
  */
  */
-extern int
+WIMLIBAPI int
 wimlib_set_print_errors(bool show_messages);
 
 /**
 wimlib_set_print_errors(bool show_messages);
 
 /**
@@ -4275,7 +4311,7 @@ wimlib_set_print_errors(bool show_messages);
  *     ::wimlib_wim_info.boot_index did not specify 0 or a valid 1-based image
  *     index in the WIM.
  */
  *     ::wimlib_wim_info.boot_index did not specify 0 or a valid 1-based image
  *     index in the WIM.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_wim_info(WIMStruct *wim, const struct wimlib_wim_info *info,
                    int which);
 
 wimlib_set_wim_info(WIMStruct *wim, const struct wimlib_wim_info *info,
                    int which);
 
@@ -4319,7 +4355,7 @@ wimlib_set_wim_info(WIMStruct *wim, const struct wimlib_wim_info *info,
  * receive ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages while writing each part;
  * these messages will report the progress of the current part only.
  */
  * receive ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages while writing each part;
  * these messages will report the progress of the current part only.
  */
-extern int
+WIMLIBAPI int
 wimlib_split(WIMStruct *wim,
             const wimlib_tchar *swm_name,
             uint64_t part_size,
 wimlib_split(WIMStruct *wim,
             const wimlib_tchar *swm_name,
             uint64_t part_size,
@@ -4362,7 +4398,7 @@ wimlib_split(WIMStruct *wim,
  * ::WIMLIB_PROGRESS_MSG_END_VERIFY_IMAGE, and
  * ::WIMLIB_PROGRESS_MSG_VERIFY_STREAMS.
  */
  * ::WIMLIB_PROGRESS_MSG_END_VERIFY_IMAGE, and
  * ::WIMLIB_PROGRESS_MSG_VERIFY_STREAMS.
  */
-extern int
+WIMLIBAPI int
 wimlib_verify_wim(WIMStruct *wim, int verify_flags);
 
 /**
 wimlib_verify_wim(WIMStruct *wim, int verify_flags);
 
 /**
@@ -4398,7 +4434,7 @@ wimlib_verify_wim(WIMStruct *wim, int verify_flags);
  * by using the @c umount or @c fusermount programs.  However, you need to call
  * this function if you want changes to be committed.
  */
  * by using the @c umount or @c fusermount programs.  However, you need to call
  * this function if you want changes to be committed.
  */
-extern int
+WIMLIBAPI int
 wimlib_unmount_image(const wimlib_tchar *dir, int unmount_flags);
 
 /**
 wimlib_unmount_image(const wimlib_tchar *dir, int unmount_flags);
 
 /**
@@ -4409,7 +4445,7 @@ wimlib_unmount_image(const wimlib_tchar *dir, int unmount_flags);
  * message.  In addition, if changes are committed from a read-write mount, the
  * progress function will receive ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages.
  */
  * message.  In addition, if changes are committed from a read-write mount, the
  * progress function will receive ::WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages.
  */
-extern int
+WIMLIBAPI int
 wimlib_unmount_image_with_progress(const wimlib_tchar *dir,
                                   int unmount_flags,
                                   wimlib_progress_func_t progfunc,
 wimlib_unmount_image_with_progress(const wimlib_tchar *dir,
                                   int unmount_flags,
                                   wimlib_progress_func_t progfunc,
@@ -4505,7 +4541,7 @@ wimlib_unmount_image_with_progress(const wimlib_tchar *dir,
  * indicate failure (for different reasons) to read the metadata resource for an
  * image that needed to be updated.
  */
  * indicate failure (for different reasons) to read the metadata resource for an
  * image that needed to be updated.
  */
-extern int
+WIMLIBAPI int
 wimlib_update_image(WIMStruct *wim,
                    int image,
                    const struct wimlib_update_command *cmds,
 wimlib_update_image(WIMStruct *wim,
                    int image,
                    const struct wimlib_update_command *cmds,
@@ -4573,7 +4609,7 @@ wimlib_update_image(WIMStruct *wim,
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, and
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END.
  */
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_BEGIN, and
  * ::WIMLIB_PROGRESS_MSG_WRITE_METADATA_END.
  */
-extern int
+WIMLIBAPI int
 wimlib_write(WIMStruct *wim,
             const wimlib_tchar *path,
             int image,
 wimlib_write(WIMStruct *wim,
             const wimlib_tchar *path,
             int image,
@@ -4600,7 +4636,7 @@ wimlib_write(WIMStruct *wim,
  *     @p fd was not seekable, but ::WIMLIB_WRITE_FLAG_PIPABLE was not
  *     specified in @p write_flags.
  */
  *     @p fd was not seekable, but ::WIMLIB_WRITE_FLAG_PIPABLE was not
  *     specified in @p write_flags.
  */
-extern int
+WIMLIBAPI int
 wimlib_write_to_fd(WIMStruct *wim,
                   int fd,
                   int image,
 wimlib_write_to_fd(WIMStruct *wim,
                   int fd,
                   int image,
@@ -4658,7 +4694,7 @@ struct wimlib_decompressor;
  * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
  *     @p ctype was neither a supported compression type nor -1.
  */
  * @retval ::WIMLIB_ERR_INVALID_COMPRESSION_TYPE
  *     @p ctype was neither a supported compression type nor -1.
  */
-extern int
+WIMLIBAPI int
 wimlib_set_default_compression_level(int ctype, unsigned int compression_level);
 
 /**
 wimlib_set_default_compression_level(int ctype, unsigned int compression_level);
 
 /**
@@ -4669,7 +4705,7 @@ wimlib_set_default_compression_level(int ctype, unsigned int compression_level);
  * compression type is invalid, or the @p max_block_size for that compression
  * type is invalid.
  */
  * compression type is invalid, or the @p max_block_size for that compression
  * type is invalid.
  */
-extern uint64_t
+WIMLIBAPI uint64_t
 wimlib_get_compressor_needed_memory(enum wimlib_compression_type ctype,
                                    size_t max_block_size,
                                    unsigned int compression_level);
 wimlib_get_compressor_needed_memory(enum wimlib_compression_type ctype,
                                    size_t max_block_size,
                                    unsigned int compression_level);
@@ -4744,7 +4780,7 @@ wimlib_get_compressor_needed_memory(enum wimlib_compression_type ctype,
  * @retval ::WIMLIB_ERR_NOMEM
  *     Insufficient memory to allocate the compressor.
  */
  * @retval ::WIMLIB_ERR_NOMEM
  *     Insufficient memory to allocate the compressor.
  */
-extern int
+WIMLIBAPI int
 wimlib_create_compressor(enum wimlib_compression_type ctype,
                         size_t max_block_size,
                         unsigned int compression_level,
 wimlib_create_compressor(enum wimlib_compression_type ctype,
                         size_t max_block_size,
                         unsigned int compression_level,
@@ -4770,7 +4806,7 @@ wimlib_create_compressor(enum wimlib_compression_type ctype,
  *     The size of the compressed data, in bytes, or 0 if the data could not be
  *     compressed to @p compressed_size_avail or fewer bytes.
  */
  *     The size of the compressed data, in bytes, or 0 if the data could not be
  *     compressed to @p compressed_size_avail or fewer bytes.
  */
-extern size_t
+WIMLIBAPI size_t
 wimlib_compress(const void *uncompressed_data, size_t uncompressed_size,
                void *compressed_data, size_t compressed_size_avail,
                struct wimlib_compressor *compressor);
 wimlib_compress(const void *uncompressed_data, size_t uncompressed_size,
                void *compressed_data, size_t compressed_size_avail,
                struct wimlib_compressor *compressor);
@@ -4781,7 +4817,7 @@ wimlib_compress(const void *uncompressed_data, size_t uncompressed_size,
  * @param compressor
  *     The compressor to free.  If @c NULL, no action is taken.
  */
  * @param compressor
  *     The compressor to free.  If @c NULL, no action is taken.
  */
-extern void
+WIMLIBAPI void
 wimlib_free_compressor(struct wimlib_compressor *compressor);
 
 /**
 wimlib_free_compressor(struct wimlib_compressor *compressor);
 
 /**
@@ -4817,7 +4853,7 @@ wimlib_free_compressor(struct wimlib_compressor *compressor);
  * @retval ::WIMLIB_ERR_NOMEM
  *     Insufficient memory to allocate the decompressor.
  */
  * @retval ::WIMLIB_ERR_NOMEM
  *     Insufficient memory to allocate the decompressor.
  */
-extern int
+WIMLIBAPI int
 wimlib_create_decompressor(enum wimlib_compression_type ctype,
                           size_t max_block_size,
                           struct wimlib_decompressor **decompressor_ret);
 wimlib_create_decompressor(enum wimlib_compression_type ctype,
                           size_t max_block_size,
                           struct wimlib_decompressor **decompressor_ret);
@@ -4849,7 +4885,7 @@ wimlib_create_decompressor(enum wimlib_compression_type ctype,
  * as the @p uncompressed_size parameter.  If this is not done correctly,
  * decompression may fail or the data may be decompressed incorrectly.
  */
  * as the @p uncompressed_size parameter.  If this is not done correctly,
  * decompression may fail or the data may be decompressed incorrectly.
  */
-extern int
+WIMLIBAPI int
 wimlib_decompress(const void *compressed_data, size_t compressed_size,
                  void *uncompressed_data, size_t uncompressed_size,
                  struct wimlib_decompressor *decompressor);
 wimlib_decompress(const void *compressed_data, size_t compressed_size,
                  void *uncompressed_data, size_t uncompressed_size,
                  struct wimlib_decompressor *decompressor);
@@ -4860,7 +4896,7 @@ wimlib_decompress(const void *compressed_data, size_t compressed_size,
  * @param decompressor
  *     The decompressor to free.  If @c NULL, no action is taken.
  */
  * @param decompressor
  *     The decompressor to free.  If @c NULL, no action is taken.
  */
-extern void
+WIMLIBAPI void
 wimlib_free_decompressor(struct wimlib_decompressor *decompressor);
 
 
 wimlib_free_decompressor(struct wimlib_decompressor *decompressor);