在查找处理WIM,ESD文件的库,除了Wimgapi 库还在找到一个开源库Wimlib 处理WIM,ESD格式数据.
Wimlib是一个开源的跨平台库,用于创建、提取和修改Windows映像(WIM)档案,Wimlib 及其命令行前端Wimlib-imagex 为微软提供免费的跨平台替代方案
Wimlib 更适合在Linux环境下使用,测试时部分功能无法在Windows环境下使用。
目录导读
WIMLIB描述
wimlib是一个开源的跨平台库,用于创建、提取和修改Windows映像(WIM)档案。WIM是一种文件归档格式,有点类似于ZIP(和许多其他文件归档格式);但与ZIP不同的是,它允许存储各种特定于Windows的元数据,允许在单个归档中存储多个"映像",自动对所有文件内容进行重复数据删除,并支持可选的固体压缩以获得更好的压缩比。wimlib及其命令行前端wimlib-imagex为微软提供免费的跨平台替代方案Wimgapi , ImageX ,以及DISM .除其他外,Wimlib:
- 在Windows和类UNIX系统(如Mac OS X和Linux)上提供快速可靠的文件归档。
- 允许非Windows操作系统的用户读写Windows映像(WIM)文件。
- 支持在Windows风格的文件系统(如NTFS)上正确归档文件,而不会犯常见错误,如未正确处理ACL、文件属性、链接和命名数据流。
- 允许从Linux等非Windows操作系统部署Windows操作系统。
- 为多个应用程序提供独立、高质量的开源压缩器和解压缩器压缩格式由微软使用,不像更开放的格式那样广为人知,易于在不同的应用程序和文件格式中重用(不仅仅是WIM)。
- wimlib作为源tarball(适用于UNIX/Linux)或现成的二进制文件(适用于Windows XP和更高版本)分发。该软件由一个C库和wimlib-imagex命令行前端及其相关文档。
摘抄自官网:详见 [https://wimlib.net/]
数据预处理
通过github下载的wimlib-1.14.3-windows-x86_64-bin 项目
将devel文件夹中的libwim.lib 和wimlib.h 添加到项目中,libwim-15.dll 放在可执行程序同级目录中。
libwim.lib必须设置为完整路径
cpp
#include "devel/wimlib.h"
#pragma comment(lib,"E:\\data-bank\\Git\\Mirror_Image_READ\\Mirror_Image_DAL\\devel\\libwim.lib")
///进度条宏定义
#define TO_PERCENT(numerator, denominator) \
((float)(((denominator) == 0) ? 0 : ((numerator) * 100 / (float)(denominator))))
获取镜像的相关信息
wimlib 库的使用和Wimgapi 库基本差不多,参数这些一看就很明白,wimlib.h 文件中也有参数说明,和所有的宏定义这些,但是:
wimlib 库在调用获取镜像XML信息时,与Wimgapi 有点不一样,传递的是一个FILE * 指针。
wimlib_extract_xml_data 方法描述:
cpp
/**
* @ingroup G_wim_information
*
* Similar to wimlib_get_xml_data(), but the XML document will be written to the
* specified standard C <c>FILE*</c> instead of retrieved in an in-memory
* buffer.
*
* @return 0 on success; a ::wimlib_error_code value on failure. This may
* return any error code which can be returned by wimlib_get_xml_data() as well
* as the following error codes:
*
* @retval ::WIMLIB_ERR_WRITE
* Failed to write the data to the requested file.
*/
WIMLIBAPI int
wimlib_extract_xml_data(WIMStruct *wim, FILE *fp);
实际调用:
cpp
//实际调用
/*
* 唯一能解释这个问题:https://www.cnblogs.com/wsk3q/p/16964667.html
* 异常 expression:(_osfile(fh) &fopen)
FILE *fp=fopen("text.txt","at+");
if (fp == NULL) {
qDebug("无法打开文件...\n");
goto out;
}
// fprintf(_file, "%s", "data-dsadsa"); // 写入数据到文件
// fseek(_file,0L,SEEK_SET);
// G_wim_information
ret =wimlib_extract_xml_data(wim,fp);
if (ret != 0) // Always should check the error codes.
{
if(fp!=NULL)
fclose(fp);
goto out;
}
if(fp!=NULL)
fclose(fp);
*/
在做测试的时候,我FILE结构的所有打开方式都试了一遍,都愣是异常提示无法写入文件,最后找到唯一的解释就是:传递FILE*指针到dll里面之后引起异常
于是换了种方式改用
wimlib_get_wim_info 方法获取WIM信息:
wimlib_get_image_property 方法获取XML节点信息;
cpp
/**
* @ingroup G_wim_information
*
* Get basic information about a WIM file.
*
* @param wim
* Pointer to the ::WIMStruct to query. This need not represent a
* standalone WIM (e.g. it could represent part of a split WIM).
* @param info
* A ::wimlib_wim_info structure that will be filled in with information
* about the WIM file.
*
* @return 0
*/
WIMLIBAPI int
wimlib_get_wim_info(WIMStruct *wim, struct wimlib_wim_info *info);
/**
* @ingroup G_wim_information
*
* Since wimlib v1.8.3: get a per-image property from the WIM's XML document.
* This is an alternative to wimlib_get_image_name() and
* wimlib_get_image_description() which allows getting any simple string
* property.
*
* @param wim
* Pointer to the ::WIMStruct for the WIM.
* @param image
* The 1-based index of the image for which to get the property.
* @param property_name
* The name of the image property, for example "NAME", "DESCRIPTION", or
* "TOTALBYTES". The name can contain forward slashes to indicate a nested
* XML element; for example, "WINDOWS/VERSION/BUILD" indicates the BUILD
* element nested within the VERSION element nested within the WINDOWS
* element. Since wimlib v1.9.0, a bracketed number can be used to
* indicate one of several identically-named elements; for example,
* "WINDOWS/LANGUAGES/LANGUAGE[2]" indicates the second "LANGUAGE" element
* nested within the "WINDOWS/LANGUAGES" element. Note that element names
* are case sensitive.
*
* @return
* The property's value as a ::wimlib_tchar string, or @c NULL if there is
* no such property. The string may not remain valid after later library
* calls, so the caller should duplicate it if needed.
*/
WIMLIBAPI const wimlib_tchar *
wimlib_get_image_property(const WIMStruct *wim, int image,
const wimlib_tchar *property_name);
完整调用:
cpp
int ret=0;
WIMStruct *wim = NULL;
wimlib_wim_info *info=new wimlib_wim_info;
//QString Image_path; wim镜像路径
wchar_t* wimage=_utf8_to_wchar(Image_path.toStdString().c_str());
/* Open the WIM file as a WIMStruct. */
ret = wimlib_open_wim(wimage, /* Path of WIM file to open */
0, /* WIMLIB_OPEN_FLAG_* flags (0 means all defaults) */
&wim); /* Return the WIMStruct pointer in this location */
if (ret != 0) /* Always should check the error codes. */
goto out;
//通过wimlib_wim_info结构获取信息
//Get basic information about a WIM file.
ret =wimlib_get_wim_info(wim, info);
if (ret != 0) /* Always should check the error codes. */
goto out;
qDebug()<<"[image_count] "<<info->image_count;
qDebug()<<"[boot_index] "<<info->boot_index;
qDebug()<<"[wim_version] "<<info->wim_version;
//!读取镜像属性 实际上就是读取xml文件结构数据
/*
for(int i=1;i<=info->image_count;i++)
{
XML_Wim_Version item_version;
item_version.Index=i;
item_version.DISPLAYNAME=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"DISPLAYNAME"));
QString image_size=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"TOTALBYTES"));
item_version.ISOSIZE=image_size.toDouble()!=0?(QString::number(image_size.toDouble()/MB,'f',1)+"MB"):"???";
item_version.MAJOR=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/MAJOR"));
item_version.MINOR=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/MINOR"));
item_version.BUILD=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/BUILD"));
item_version.SPBUILD=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/VERSION/SPBUILD"));
item_version.PRODUCTTYPE=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"WINDOWS/PRODUCTTYPE"));
item_version.VERSION=WINVERSION(item_version.PRODUCTTYPE,QString("%1.%2.%3.%4").arg(item_version.MAJOR).arg(item_version.MINOR).arg(item_version.BUILD).arg(item_version.SPBUILD));
item_version.FILECOUNT=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"FILECOUNT"));
item_version.DIRCOUNT=QString::fromWCharArray(wimlib_get_image_property(wim,i,L"DIRCOUNT"));
Versions.append(item_version);
}
*/
//系统版本数量
//int Image_Count=Versions.count();
out:
/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */
wimlib_free(wim);
/* Check for error status. */
if (ret != 0) {
qDebug()<<"wimlib error : "<<QString::fromWCharArray(wimlib_get_error_string((enum wimlib_error_code)ret));
}
/* Free global memory (optional). */
wimlib_global_cleanup();
free(wimage);
Wimlib库自带异常捕获,能通过wimlib_get_error_string 完整获取错误信息。
在测试的时候,部分信息不完整的WIM文件无法通过wimlib_open_wim方法打开,暂时无解。
导出指定系统中的文件
可通过wimlib_extract_paths 导出指定系统版本中的文件,
wimlib_extract_paths 函数说明:
cpp
/**
* @ingroup G_extracting_wims
*
* Extract zero or more paths (files or directory trees) from the specified WIM
* image.
*
* By default, each path will be extracted to a corresponding subdirectory of
* the target based on its location in the image. For example, if one of the
* paths to extract is <c>/Windows/explorer.exe</c> and the target is
* <c>outdir</c>, the file will be extracted to
* <c>outdir/Windows/explorer.exe</c>. This behavior can be changed by
* providing the flag ::WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE, which
* will cause each file or directory tree to be placed directly in the target
* directory --- so the same example would extract <c>/Windows/explorer.exe</c>
* to <c>outdir/explorer.exe</c>.
*
* With globbing turned off (the default), paths are always checked for
* existence strictly; that is, if any path to extract does not exist in the
* image, then nothing is extracted and the function fails with
* ::WIMLIB_ERR_PATH_DOES_NOT_EXIST. But with globbing turned on
* (::WIMLIB_EXTRACT_FLAG_GLOB_PATHS specified), globs are by default permitted
* to match no files, and there is a flag (::WIMLIB_EXTRACT_FLAG_STRICT_GLOB) to
* enable the strict behavior if desired.
*
* Symbolic links are not dereferenced when paths in the image are interpreted.
*
* @param wim
* WIM from which to extract the paths, specified as a pointer to the
* ::WIMStruct for a standalone WIM file, a delta WIM file, or part 1 of a
* split WIM. In the case of a WIM file that is not standalone, this
* ::WIMStruct must have had any needed external resources previously
* referenced using wimlib_reference_resources() or
* wimlib_reference_resource_files().
* @param image
* The 1-based index of the WIM image from which to extract the paths.
* @param paths
* Array of paths to extract. Each element must be the absolute path to a
* file or directory within the image. Path separators may be either
* forwards or backwards slashes, and leading path separators are optional.
* The paths will be interpreted either case-sensitively (UNIX default) or
* case-insensitively (Windows default); however, the case sensitivity can
* be configured explicitly at library initialization time by passing an
* appropriate flag to wimlib_global_init().
* <br/>
* By default, "globbing" is disabled, so the characters @c * and @c ? are
* interpreted literally. This can be changed by specifying
* ::WIMLIB_EXTRACT_FLAG_GLOB_PATHS in @p extract_flags.
* @param num_paths
* Number of paths specified in @p paths.
* @param target
* Directory to which to extract the paths.
* @param extract_flags
* Bitwise OR of flags prefixed with WIMLIB_EXTRACT_FLAG.
*
* @return 0 on success; a ::wimlib_error_code value on failure. Most of the
* error codes are the same as those returned by wimlib_extract_image(). Below,
* some of the error codes returned in situations specific to path-mode
* extraction are documented:
*
* @retval ::WIMLIB_ERR_NOT_A_REGULAR_FILE
* ::WIMLIB_EXTRACT_FLAG_TO_STDOUT was specified in @p extract_flags, but
* one of the paths to extract did not name a regular file.
* @retval ::WIMLIB_ERR_PATH_DOES_NOT_EXIST
* One of the paths to extract does not exist in the image; see discussion
* above about strict vs. non-strict behavior.
*
* If a progress function is registered with @p wim, then it will receive
* ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS.
*/
WIMLIBAPI int
wimlib_extract_paths(WIMStruct *wim,
int image,
const wimlib_tchar *target,
const wimlib_tchar * const *paths,
size_t num_paths,
int extract_flags);
获取镜像目录结构(装载/卸载镜像)
挂载WIM映像(仅限Linux);
这是在我测试的时候,把装载/卸载方法写完,调用失败查找官方文档才发现的问题...
wimlib_mount_image 装载函数:
wimlib_unmount_image 卸载函数:
cpp
/**
* @ingroup G_mounting_wim_images
*
* Mount an image from a WIM file on a directory read-only or read-write.
*
* @param wim
* Pointer to the ::WIMStruct containing the image to be mounted. This
* ::WIMStruct must have a backing file.
* @param image
* The 1-based index of the image to mount. This image cannot have been
* previously modified in memory.
* @param dir
* The path to an existing empty directory on which to mount the image.
* @param mount_flags
* Bitwise OR of flags prefixed with WIMLIB_MOUNT_FLAG. Use
* ::WIMLIB_MOUNT_FLAG_READWRITE to request a read-write mount instead of a
* read-only mount.
* @param staging_dir
* If non-NULL, the name of a directory in which a temporary directory for
* storing modified or added files will be created. Ignored if
* ::WIMLIB_MOUNT_FLAG_READWRITE is not specified in @p mount_flags. If
* left @c NULL, the staging directory is created in the same directory as
* the backing WIM file. The staging directory is automatically deleted
* when the image is unmounted.
*
* @return 0 on success; a ::wimlib_error_code value on failure.
*
* @retval ::WIMLIB_ERR_ALREADY_LOCKED
* Another process is currently modifying the WIM file.
* @retval ::WIMLIB_ERR_FUSE
* A non-zero status code was returned by @c fuse_main().
* @retval ::WIMLIB_ERR_IMAGE_HAS_MULTIPLE_REFERENCES
* There are currently multiple references to the image as a result of a
* call to wimlib_export_image(). Free one before attempting the
* read-write mount.
* @retval ::WIMLIB_ERR_INVALID_IMAGE
* @p image does not exist in @p wim.
* @retval ::WIMLIB_ERR_INVALID_PARAM
* @p wim was @c NULL; or @p dir was NULL or an empty string; or an
* unrecognized flag was specified in @p mount_flags; or the image has
* already been modified in memory (e.g. by wimlib_update_image()).
* @retval ::WIMLIB_ERR_MKDIR
* ::WIMLIB_MOUNT_FLAG_READWRITE was specified in @p mount_flags, but the
* staging directory could not be created.
* @retval ::WIMLIB_ERR_WIM_IS_READONLY
* ::WIMLIB_MOUNT_FLAG_READWRITE was specified in @p mount_flags, but the
* WIM file is considered read-only because of any of the reasons mentioned
* in the documentation for the ::WIMLIB_OPEN_FLAG_WRITE_ACCESS flag.
* @retval ::WIMLIB_ERR_UNSUPPORTED
* Mounting is not supported in this build of the library.
*
* This function can additionally return ::WIMLIB_ERR_DECOMPRESSION,
* ::WIMLIB_ERR_INVALID_METADATA_RESOURCE, ::WIMLIB_ERR_METADATA_NOT_FOUND,
* ::WIMLIB_ERR_READ, or ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE, all of which
* indicate failure (for different reasons) to read the metadata resource for
* the image to mount.
*
* The ability to mount WIM images is implemented using FUSE (Filesystem in
* UserSpacE). Depending on how FUSE is set up on your system, this function
* may work as normal users in addition to the root user.
*
* Mounting WIM images is not supported if wimlib was configured
* <c>--without-fuse</c>. This includes Windows builds of wimlib;
* ::WIMLIB_ERR_UNSUPPORTED will be returned in such cases.
*
* Calling this function daemonizes the process, unless
* ::WIMLIB_MOUNT_FLAG_DEBUG was specified or an early error occurs.
*
* It is safe to mount multiple images from the same WIM file read-only at the
* same time, but only if different ::WIMStruct's are used. It is @b not safe
* to mount multiple images from the same WIM file read-write at the same time.
*
* To unmount the image, call wimlib_unmount_image(). This may be done in a
* different process.
*/
WIMLIBAPI int
wimlib_mount_image(WIMStruct *wim,
int image,
const wimlib_tchar *dir,
int mount_flags,
const wimlib_tchar *staging_dir);
/**
* @ingroup G_mounting_wim_images
*
* Unmount a WIM image that was mounted using wimlib_mount_image().
*
* When unmounting a read-write mounted image, the default behavior is to
* discard changes to the image. Use ::WIMLIB_UNMOUNT_FLAG_COMMIT to cause the
* image to be committed.
*
* @param dir
* The directory on which the WIM image is mounted.
* @param unmount_flags
* Bitwise OR of flags prefixed with @p WIMLIB_UNMOUNT_FLAG.
*
* @return 0 on success; a ::wimlib_error_code value on failure.
*
* @retval ::WIMLIB_ERR_NOT_A_MOUNTPOINT
* There is no WIM image mounted on the specified directory.
* @retval ::WIMLIB_ERR_MOUNTED_IMAGE_IS_BUSY
* The read-write mounted image cannot be committed because there are file
* descriptors open to it, and ::WIMLIB_UNMOUNT_FLAG_FORCE was not
* specified.
* @retval ::WIMLIB_ERR_MQUEUE
* Could not create a POSIX message queue.
* @retval ::WIMLIB_ERR_NOT_PERMITTED_TO_UNMOUNT
* The image was mounted by a different user.
* @retval ::WIMLIB_ERR_UNSUPPORTED
* Mounting is not supported in this build of the library.
*
* Note: you can also unmount the image by using the @c umount() system call, or
* by using the @c umount or @c fusermount programs. However, you need to call
* this function if you want changes to be committed.
*/
WIMLIBAPI int
wimlib_unmount_image(const wimlib_tchar *dir, int unmount_flags);
调用示例,建议Linux环境下测试,Windows环境下不支持:
cpp
int WIM_INDEX=qMin(qMax(1,index.toInt()),Image_Count);
wchar_t* wimage;
int ret=0;
WIMStruct *wim = NULL;
// wchar_t* wtemp=tempObj.GetTempDirU();
wchar_t* wtemp=_utf8_to_wchar(QString("C:\\Users\\admin\\Desktop\\textxml\\text").toStdString().c_str());
QDir tempMountDir(QString::fromWCharArray(wtemp)+"\\TempMount_WIMLIB");
if(!tempMountDir.exists())
tempMountDir.mkpath(QString::fromWCharArray(wtemp)+"\\TempMount_WIMLIB");
wchar_t* wdst=_utf8_to_wchar(QString(QString::fromWCharArray(wtemp)+"\\TempMount_WIMLIB").toStdString().c_str());
//TempFile 挂载路径
QString TempFile=QString::fromWCharArray(wdst);
qDebug()<<"[TempFile] "<<TempFile;
//Image_path 镜像路径
wimage=_utf8_to_wchar(Image_path.toStdString().c_str());
/* Open the WIM file as a WIMStruct. */
ret = wimlib_open_wim(wimage, /* Path of WIM file to open */
0, /* WIMLIB_OPEN_FLAG_* flags (0 means all defaults) */
&wim); /* Return the WIMStruct pointer in this location */
if (ret != 0) /* Always should check the error codes. */
goto out;
//WIMLIB_MOUNT_FLAG_READWRITE
//WIMLIB_MOUNT_FLAG_DEBUG
//WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_NONE
//WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR
//WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS
//WIMLIB_MOUNT_FLAG_UNIX_DATA
//WIMLIB_MOUNT_FLAG_ALLOW_OTHER
ret=wimlib_mount_image(wim,WIM_INDEX,wdst,0,L"");
if (ret != 0) /* Always should check the error codes. */
{
goto out;
}
//遍历目录结构
//Lib_Deploy_Environment::getInstance().EnumerateFiles(TempFile,Fetch_Files);
//! 如果需要对镜像镜像修改 可以在此处操作文件目录/文件 然后提交保存
//!WIMLIB_UNMOUNT_FLAG_COMMIT 保存装载后的更改!
//WIMLIB_UNMOUNT_FLAG_CHECK_INTEGRITY
//WIMLIB_UNMOUNT_FLAG_COMMIT
//WIMLIB_UNMOUNT_FLAG_REBUILD
//WIMLIB_UNMOUNT_FLAG_RECOMPRESS
//WIMLIB_UNMOUNT_FLAG_FORCE
//WIMLIB_UNMOUNT_FLAG_NEW_IMAGE
//不提交修改
ret=wimlib_unmount_image(wdst, 0);
if (ret != 0) /* Always should check the error codes. */
{
goto out;
}
out:
/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */
wimlib_free(wim);
/* Check for error status. */
if (ret != 0) {
qDebug()<<"wimlib error : "<<QString::fromWCharArray(wimlib_get_error_string((enum wimlib_error_code)ret));
}
/* Free global memory (optional). */
wimlib_global_cleanup();
提取镜像到指定目录
WIMLIB 通过wimlib_extract_image 函数提取镜像。
也可通过wimlib_register_progress_function设置回调函数直接获取进度。
cpp
/**
* @ingroup G_general
*
* Register a progress function with a ::WIMStruct.
*
* @param wim
* The ::WIMStruct for which to register the progress function.
* @param progfunc
* Pointer to the progress function to register. If the WIM already has a
* progress function registered, it will be replaced with this one. If @p
* NULL, the current progress function (if any) will be unregistered.
* @param progctx
* The value which will be passed as the third argument to calls to @p
* progfunc.
*/
WIMLIBAPI void
wimlib_register_progress_function(WIMStruct *wim,
wimlib_progress_func_t progfunc,
void *progctx);
/**
* @ingroup G_extracting_wims
*
* Extract an image, or all images, from a ::WIMStruct.
*
* The exact behavior of how wimlib extracts files from a WIM image is
* controllable by the @p extract_flags parameter, but there also are
* differences depending on the platform (UNIX-like vs Windows). See the
* documentation for <b>wimapply</b> for more information, including about the
* NTFS-3G extraction mode.
*
* @param wim
* The WIM from which to extract the image(s), specified as a pointer to the
* ::WIMStruct for a standalone WIM file, a delta WIM file, or part 1 of a
* split WIM. In the case of a WIM file that is not standalone, this
* ::WIMStruct must have had any needed external resources previously
* referenced using wimlib_reference_resources() or
* wimlib_reference_resource_files().
* @param image
* The 1-based index of the image to extract, or ::WIMLIB_ALL_IMAGES to
* extract all images. Note: ::WIMLIB_ALL_IMAGES is unsupported in NTFS-3G
* extraction mode.
* @param target
* A null-terminated string which names the location to which the image(s)
* will be extracted. By default, this is interpreted as a path to a
* directory. Alternatively, if ::WIMLIB_EXTRACT_FLAG_NTFS is specified in
* @p extract_flags, then this is interpreted as a path to an unmounted
* NTFS volume.
* @param extract_flags
* Bitwise OR of flags prefixed with WIMLIB_EXTRACT_FLAG.
*
* @return 0 on success; a ::wimlib_error_code value on failure.
*
* @retval ::WIMLIB_ERR_DECOMPRESSION
* The WIM file contains invalid compressed data.
* @retval ::WIMLIB_ERR_INVALID_IMAGE
* @p image does not exist in @p wim.
* @retval ::WIMLIB_ERR_INVALID_METADATA_RESOURCE
* The metadata for an image to extract was invalid.
* @retval ::WIMLIB_ERR_INVALID_PARAM
* The extraction flags were invalid; more details may be found in the
* documentation for the specific extraction flags that were specified. Or
* @p target was @c NULL or an empty string, or @p wim was @c NULL.
* @retval ::WIMLIB_ERR_INVALID_RESOURCE_HASH
* The data of a file that needed to be extracted was corrupt.
* @retval ::WIMLIB_ERR_LINK
* Failed to create a symbolic link or a hard link.
* @retval ::WIMLIB_ERR_METADATA_NOT_FOUND
* @p wim does not contain image metadata; for example, it represents a
* non-first part of a split WIM.
* @retval ::WIMLIB_ERR_MKDIR
* Failed create a directory.
* @retval ::WIMLIB_ERR_NTFS_3G
* libntfs-3g reported that a problem occurred while writing to the NTFS
* volume.
* @retval ::WIMLIB_ERR_OPEN
* Could not create a file, or failed to open an already-extracted file.
* @retval ::WIMLIB_ERR_READ
* Failed to read data from the WIM.
* @retval ::WIMLIB_ERR_READLINK
* Failed to determine the target of a symbolic link in the WIM.
* @retval ::WIMLIB_ERR_REPARSE_POINT_FIXUP_FAILED
* Failed to fix the target of an absolute symbolic link (e.g. if the
* target would have exceeded the maximum allowed length). (Only if
* reparse data was supported by the extraction mode and
* ::WIMLIB_EXTRACT_FLAG_STRICT_SYMLINKS was specified in @p
* extract_flags.)
* @retval ::WIMLIB_ERR_RESOURCE_NOT_FOUND
* A file data blob that needed to be extracted could not be found in the
* blob lookup table of @p wim. See @ref G_nonstandalone_wims.
* @retval ::WIMLIB_ERR_SET_ATTRIBUTES
* Failed to set attributes on a file.
* @retval ::WIMLIB_ERR_SET_REPARSE_DATA
* Failed to set reparse data on a file (only if reparse data was supported
* by the extraction mode).
* @retval ::WIMLIB_ERR_SET_SECURITY
* Failed to set security descriptor on a file.
* @retval ::WIMLIB_ERR_SET_SHORT_NAME
* Failed to set the short name of a file.
* @retval ::WIMLIB_ERR_SET_TIMESTAMPS
* Failed to set timestamps on a file.
* @retval ::WIMLIB_ERR_UNEXPECTED_END_OF_FILE
* Unexpected end-of-file occurred when reading data from the WIM.
* @retval ::WIMLIB_ERR_UNSUPPORTED
* A requested extraction flag, or the data or metadata that must be
* extracted to support it, is unsupported in the build and configuration
* of wimlib, or on the current platform or extraction mode or target
* volume. Flags affected by this include ::WIMLIB_EXTRACT_FLAG_NTFS,
* ::WIMLIB_EXTRACT_FLAG_UNIX_DATA, ::WIMLIB_EXTRACT_FLAG_STRICT_ACLS,
* ::WIMLIB_EXTRACT_FLAG_STRICT_SHORT_NAMES,
* ::WIMLIB_EXTRACT_FLAG_STRICT_TIMESTAMPS, and
* ::WIMLIB_EXTRACT_FLAG_STRICT_SYMLINKS. For example, if
* ::WIMLIB_EXTRACT_FLAG_STRICT_SHORT_NAMES is specified in @p
* extract_flags, ::WIMLIB_ERR_UNSUPPORTED will be returned if the WIM
* image contains one or more files with short names, but extracting short
* names is not supported --- on Windows, this occurs if the target volume
* does not support short names, while on non-Windows, this occurs if
* ::WIMLIB_EXTRACT_FLAG_NTFS was not specified in @p extract_flags.
* @retval ::WIMLIB_ERR_WIMBOOT
* ::WIMLIB_EXTRACT_FLAG_WIMBOOT was specified in @p extract_flags, but
* there was a problem creating WIMBoot pointer files or registering a
* source WIM file with the Windows Overlay Filesystem (WOF) driver.
* @retval ::WIMLIB_ERR_WRITE
* Failed to write data to a file being extracted.
*
* If a progress function is registered with @p wim, then as each image is
* extracted it will receive ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_BEGIN, then
* zero or more ::WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE messages, then zero
* or more ::WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS messages, then zero or more
* ::WIMLIB_PROGRESS_MSG_EXTRACT_METADATA messages, then
* ::WIMLIB_PROGRESS_MSG_EXTRACT_IMAGE_END.
*/
WIMLIBAPI int
wimlib_extract_image(WIMStruct *wim, int image,
const wimlib_tchar *target, int extract_flags);
调用示例:
cpp
enum wimlib_progress_status extract_progress(enum wimlib_progress_msg msg,
union wimlib_progress_info *info, void *progctx)
{
switch (msg) {
case WIMLIB_PROGRESS_MSG_EXTRACT_STREAMS:
qDebug("Extracting files: %.2f%% complete\n",
TO_PERCENT(info->extract.completed_bytes,
info->extract.total_bytes));
break;
default:
break;
}
return WIMLIB_PROGRESS_STATUS_CONTINUE;
}
void Export_WIM(QString Imagepath,int index,QString descpath)
{
//QString Imagepath; 镜像路径
wchar_t* wimage=_utf8_to_wchar(Imagepath.toStdString().c_str());
//QString descpath;输出目录
wchar_t* wdst=_utf8_to_wchar(descpath.toStdString().c_str());
int ret=0;
WIMStruct *wim = NULL;
/* Open the WIM file as a WIMStruct. */
ret = wimlib_open_wim(wimage, /* Path of WIM file to open */
0, /* WIMLIB_OPEN_FLAG_* flags (0 means all defaults) */
&wim); /* Return the WIMStruct pointer in this location */
if (ret != 0) /* Always should check the error codes. */
goto out;
/* Register our progress function. */
wimlib_register_progress_function(wim, extract_progress, NULL);
/* Extract the first image. */
ret = wimlib_extract_image(wim, /* WIMStruct from which to extract the image */
index, /* Image to extract */
wdst, /* Directory to extract the image to */
0); /* WIMLIB_EXTRACT_FLAG_* flags (0 means all defaults) */
if (ret != 0) /* Always should check the error codes. */
goto out;
out:
/* Free the WIMStruct. Has no effect if the pointer to it is NULL. */
wimlib_free(wim);
/* Check for error status. */
if (ret != 0) {
QString Error=QString::fromWCharArray(wimlib_get_error_string((enum wimlib_error_code)ret));
qDebug()<<"wimlib error : "<<Error;
}
/* Free global memory (optional). */
wimlib_global_cleanup();
free(wimage);
free(wdst);
}
注意
- Wimlib库在Window环境下不如WIMGAPI库好用(个人感觉);Windows环境建议使用WIMGAPI开发,Linux环境建议使用Wimlib,实在不想这么麻烦,通过QProcess 调用cmd执行wimlib-imagex.exe命令行的方式也很不错。
- Wimlib库函数的调用可以参考
https://github-wiki-see.page/m/openthos/openthos/wiki/wimlib-analysis
中的说明(中文版),包括一些函数的使用规范,宏定义都有说明。 - 在Gitbit上有一个wimlib-master 项目,具体链接丢了,
可以查看examples文件夹中的各种示例文件:
applywim.c
capturewim.c
compressfile.c
decompressfile.c
updatewim.c