[vhd] add libcdio integration to wimlib

* Allows working with WIMs without mounting the ISO by referencing something like "C:\Downloads\Windows.iso|sources/install.wim".
This commit is contained in:
Pete Batard 2025-04-25 18:11:46 +01:00
parent c288f2fe57
commit 96996ae1ee
No known key found for this signature in database
GPG key ID: 38E0CF5E69EDD671
8 changed files with 312 additions and 25 deletions

View file

@ -264,7 +264,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4018;4146;4267;4244;4334;4789;4996;6201;6239;6246;6255;6262;6297;6326;28252;28253</DisableSpecificWarnings>
@ -286,7 +286,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/std:clatest</AdditionalOptions>
@ -305,7 +305,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/std:clatest</AdditionalOptions>
@ -321,7 +321,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4018;4146;4267;4244;4334;4789;4996;6201;6239;6246;6255;6262;6297;6326;28252;28253</DisableSpecificWarnings>
@ -341,7 +341,7 @@
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/std:clatest</AdditionalOptions>
@ -358,7 +358,7 @@
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/std:clatest</AdditionalOptions>
@ -372,7 +372,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4018;4146;4267;4244;4334;4789;4996;6201;6239;6246;6255;6262;6297;6326;28252;28253</DisableSpecificWarnings>
@ -391,7 +391,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>..\src;..\src\wimlib;..\src\msvc-missing;..\src\libcdio;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4018;4146;4267;4244;4334;4789;4996;6201;6239;6246;6255;6262;6297;6326;28252;28253</DisableSpecificWarnings>

View file

@ -3831,9 +3831,28 @@ extern int TestHashes(void);
&& (msg.wParam == 'T')) {
int r;
WIMStruct* wim;
r = wimlib_open_wim(L"C:\\tmp\\boot.wim", WIMLIB_OPEN_FLAG_CHECK_INTEGRITY, &wim);
r = wimlib_open_wim(L"D:\\Incoming\\Win11_24H2_EnglishInternational_x64.iso|sources/boot.wim", WIMLIB_OPEN_FLAG_CHECK_INTEGRITY, &wim);
// r = wimlib_open_wim(L"C:\\tmp\\test.iso|sources/boot.wim", WIMLIB_OPEN_FLAG_CHECK_INTEGRITY, &wim);
// r = wimlib_open_wim(L"C:\\tmp\\boot.wim", WIMLIB_OPEN_FLAG_CHECK_INTEGRITY, &wim);
if (r == 0) {
int image;
wchar_t* xml;
size_t xml_size;
wimlib_print_header(wim);
if (wimlib_get_xml_data(wim, (void**) & xml, &xml_size) == 0) {
xml[(xml_size / sizeof(wchar_t)) - 1] = L'\0';
wuprintf(L"%s", xml);
free(xml);
}
image = wimlib_resolve_image(wim, L"1");
uprintf("image = %d", image);
const wchar_t* fn = L"Windows/win.ini";
r = wimlib_extract_paths(wim, image, L"C:\\tmp\\wim", &fn, 1, WIMLIB_EXTRACT_FLAG_NORPFIX |
WIMLIB_EXTRACT_FLAG_GLOB_PATHS | WIMLIB_EXTRACT_FLAG_STRICT_GLOB | WIMLIB_EXTRACT_FLAG_NO_PRESERVE_DIR_STRUCTURE);
if (r == 0)
uprintf("Successfully extracted '%S'", fn);
else
uprintf("Failed to extract '%S': %d", fn, r);
wimlib_free(wim);
} else {
uprintf("Failed to open WIM: %d", r);

View file

@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 4.8.2237"
CAPTION "Rufus 4.8.2238"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@ -407,8 +407,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,8,2237,0
PRODUCTVERSION 4,8,2237,0
FILEVERSION 4,8,2238,0
PRODUCTVERSION 4,8,2238,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -426,13 +426,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "4.8.2237"
VALUE "FileVersion", "4.8.2238"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2025 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.8.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "4.8.2237"
VALUE "ProductVersion", "4.8.2238"
END
END
BLOCK "VarFileInfo"

View file

@ -8,4 +8,4 @@ libwim_a_SOURCES = avl_tree.c blob_table.c compress.c compress_common.c compress
sha1.c solid.c split.c tagged_items.c textfile.c threads.c timestamp.c update_image.c \
util.c wim.c wimboot.c win32_apply.c win32_capture.c win32_common.c win32_replacements.c \
win32_vss.c write.c xml.c xmlproc.c xml_windows.c xpress_compress.c xpress_decompress.c
libwim_a_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/.. -DHAVE_CONFIG_H -D_RUFUS -D__SSE2__ -D_POSIX -D_POSIX_THREAD_SAFE_FUNCTIONS -DUNICODE -D_UNICODE -D__MINGW_USE_VC2005_COMPAT -Wno-undef -Wno-strict-aliasing -Wno-shadow -Wno-incompatible-pointer-types -Wno-sequence-point
libwim_a_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/.. -I$(srcdir)/../libcdio -DHAVE_CONFIG_H -D_RUFUS -D__SSE2__ -D_POSIX -D_POSIX_THREAD_SAFE_FUNCTIONS -DUNICODE -D_UNICODE -D__MINGW_USE_VC2005_COMPAT -Wno-undef -Wno-strict-aliasing -Wno-shadow -Wno-incompatible-pointer-types -Wno-sequence-point

View file

@ -291,7 +291,7 @@ libwim_a_SOURCES = avl_tree.c blob_table.c compress.c compress_common.c compress
util.c wim.c wimboot.c win32_apply.c win32_capture.c win32_common.c win32_replacements.c \
win32_vss.c write.c xml.c xmlproc.c xml_windows.c xpress_compress.c xpress_decompress.c
libwim_a_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/.. -DHAVE_CONFIG_H -D_RUFUS -D__SSE2__ -D_POSIX -D_POSIX_THREAD_SAFE_FUNCTIONS -DUNICODE -D_UNICODE -D__MINGW_USE_VC2005_COMPAT -Wno-undef -Wno-strict-aliasing -Wno-shadow -Wno-incompatible-pointer-types -Wno-sequence-point
libwim_a_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/.. -I$(srcdir)/../libcdio -DHAVE_CONFIG_H -D_RUFUS -D__SSE2__ -D_POSIX -D_POSIX_THREAD_SAFE_FUNCTIONS -DUNICODE -D_UNICODE -D__MINGW_USE_VC2005_COMPAT -Wno-undef -Wno-strict-aliasing -Wno-shadow -Wno-incompatible-pointer-types -Wno-sequence-point
all: all-am
.SUFFIXES:

View file

@ -4,6 +4,7 @@
/*
* Copyright (C) 2013 Eric Biggers
* Copyright (C) 2025 Pete Batard <pete@akeo.ie>
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
@ -38,6 +39,130 @@
# define pwrite win32_pwrite
#endif
#ifdef WITH_LIBCDIO
static int
udf_pread(struct filedes* fd, void* buf, size_t count, off_t offset)
{
ssize_t ret;
size_t partial_size;
uint64_t file_length;
char _buf[UDF_BLOCKSIZE];
if (count == 0)
return 0;
if (!udf_setpos(fd->p_udf_file, (offset / UDF_BLOCKSIZE) * UDF_BLOCKSIZE)) {
errno = ERANGE;
return WIMLIB_ERR_READ;
}
fd->offset = (offset / UDF_BLOCKSIZE) * UDF_BLOCKSIZE;
file_length = udf_get_file_length(fd->p_udf_file);
if (offset + count > file_length)
count = file_length - offset;
if (offset % UDF_BLOCKSIZE) {
partial_size = min(UDF_BLOCKSIZE - offset % UDF_BLOCKSIZE, count);
ret = udf_read_block(fd->p_udf_file, _buf, 1);
if (unlikely(ret <= 0)) {
errno = EINVAL;
return WIMLIB_ERR_READ;
}
memcpy(buf, &_buf[offset % UDF_BLOCKSIZE], partial_size);
buf = _PTR(buf + partial_size);
fd->offset += partial_size;
count -= partial_size;
}
while (count >= UDF_BLOCKSIZE) {
ret = udf_read_block(fd->p_udf_file, buf, count / UDF_BLOCKSIZE);
if (unlikely(ret <= 0)) {
errno = EINVAL;
return WIMLIB_ERR_READ;
}
buf = _PTR(buf + ret);
fd->offset += ret;
count -= ret;
}
partial_size = count % UDF_BLOCKSIZE;
if (partial_size) {
ret = udf_read_block(fd->p_udf_file, _buf, 1);
if (unlikely(ret <= 0)) {
errno = EINVAL;
return WIMLIB_ERR_READ;
}
memcpy(buf, _buf, partial_size);
buf = _PTR(buf + partial_size);
fd->offset += partial_size;
}
return 0;
}
static int
iso_pread(struct filedes* fd, void* buf, size_t count, off_t offset)
{
ssize_t ret;
size_t partial_size;
char _buf[ISO_BLOCKSIZE];
lsn_t lsn_offset = fd->p_iso_file->lsn + offset / ISO_BLOCKSIZE;
if (count == 0)
return 0;
if (offset >= fd->p_iso_file->total_size) {
errno = ERANGE;
return WIMLIB_ERR_READ;
}
if (offset + count > fd->p_iso_file->total_size)
count = fd->p_iso_file->total_size - offset;
if (offset % ISO_BLOCKSIZE) {
partial_size = min(ISO_BLOCKSIZE - offset % ISO_BLOCKSIZE, count);
ret = iso9660_iso_seek_read(fd->p_iso, _buf, lsn_offset, 1);
if (unlikely(ret <= 0)) {
errno = EINVAL;
return WIMLIB_ERR_READ;
}
lsn_offset += 1;
memcpy(buf, &_buf[offset % ISO_BLOCKSIZE], partial_size);
buf = _PTR(buf + partial_size);
fd->offset += partial_size;
count -= partial_size;
}
while (count >= ISO_BLOCKSIZE) {
ret = iso9660_iso_seek_read(fd->p_iso, _buf,
lsn_offset % ISO_BLOCKSIZE, 1);
ret = iso9660_iso_seek_read(fd->p_iso, buf, lsn_offset, count / ISO_BLOCKSIZE);
if (unlikely(ret <= 0)) {
errno = EINVAL;
return WIMLIB_ERR_READ;
}
lsn_offset += ret / ISO_BLOCKSIZE;
buf = _PTR(buf + ret);
fd->offset += ret;
count -= ret;
}
partial_size = count % ISO_BLOCKSIZE;
if (partial_size) {
ret = iso9660_iso_seek_read(fd->p_iso, _buf, lsn_offset, 1);
if (unlikely(ret <= 0)) {
errno = EINVAL;
return WIMLIB_ERR_READ;
}
memcpy(buf, _buf, partial_size);
buf = _PTR(buf + partial_size);
fd->offset += partial_size;
}
return 0;
}
#endif
/*
* Wrapper around read() that checks for errors and keeps retrying until all
* requested bytes have been read or until end-of file has occurred.
@ -50,6 +175,13 @@
int
full_read(struct filedes *fd, void *buf, size_t count)
{
#ifdef WITH_LIBCDIO
if (fd->is_udf)
return udf_pread(fd, buf, count, 0);
else if (fd->is_iso)
return iso_pread(fd, buf, count, 0);
#endif
while (count) {
ssize_t ret = read(fd->fd, buf, count);
if (unlikely(ret <= 0)) {
@ -117,6 +249,13 @@ full_pread(struct filedes *fd, void *buf, size_t count, off_t offset)
if (fd->is_pipe)
goto is_pipe;
#ifdef WITH_LIBCDIO
if (fd->is_udf)
return udf_pread(fd, buf, count, offset);
else if (fd->is_iso)
return iso_pread(fd, buf, count, offset);
#endif
while (count) {
ssize_t ret = pread(fd->fd, buf, count, offset);
if (unlikely(ret <= 0)) {
@ -195,6 +334,13 @@ full_pwrite(struct filedes *fd, const void *buf, size_t count, off_t offset)
off_t filedes_seek(struct filedes *fd, off_t offset)
{
#ifdef WITH_LIBCDIO
/* No arbitrary seek for ISO files */
if (fd->is_udf || fd->is_iso) {
errno = ENFILE;
return -1;
}
#endif
if (fd->is_pipe) {
errno = ESPIPE;
return -1;
@ -209,5 +355,10 @@ off_t filedes_seek(struct filedes *fd, off_t offset)
bool filedes_is_seekable(struct filedes *fd)
{
#ifdef WITH_LIBCDIO
/* No arbitrary seek for ISO files */
if (fd->is_udf || fd->is_iso)
return false;
#endif
return !fd->is_pipe && lseek(fd->fd, 0, SEEK_CUR) != -1;
}

View file

@ -4,6 +4,7 @@
/*
* Copyright 2012-2023 Eric Biggers
* Copyright 2025 Pete Batard <pete@akeo.ie>
*
* This file is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
@ -616,11 +617,77 @@ wimlib_register_progress_function(WIMStruct *wim,
wim->progctx = progctx;
}
#ifdef WITH_LIBCDIO
static int
open_iso_wim_file(const tchar* filename, struct filedes* fd_ret)
{
int ret = 0;
size_t n;
char *iso_filename, *iso_path = NULL;
udf_dirent_t *p_udf_root;
/* If the wim path contains a pipe separator, look it up inside an ISO */
if (tstr_to_utf8(filename, (tstrlen(filename) + 1) * sizeof(tchar), &iso_path, &n))
return WIMLIB_ERR_NOMEM;
iso_filename = strchr(iso_path, '|');
if (iso_filename == NULL) {
ret = WIMLIB_ERR_NO_FILENAME;
goto out;
}
*iso_filename++ = '\0';
filedes_init(fd_ret, 0);
/* Try to open as UDF image */
fd_ret->p_udf = udf_open(iso_path);
if (!fd_ret->p_udf)
goto try_iso;
p_udf_root = udf_get_root(fd_ret->p_udf, true, 0);
if (!p_udf_root) {
ret = WIMLIB_ERR_OPEN;
goto out;
}
fd_ret->p_udf_file = udf_fopen(p_udf_root, iso_filename);
udf_dirent_free(p_udf_root);
if (!fd_ret->p_udf_file) {
ret = WIMLIB_ERR_OPEN;
goto out;
}
fd_ret->is_udf = 1;
goto out;
try_iso:
/* Try to open as ISO9660 image */
fd_ret->p_iso = iso9660_open_ext(iso_path, ISO_EXTENSION_ALL);
if (!fd_ret->p_iso) {
ret = WIMLIB_ERR_OPEN;
goto out;
}
fd_ret->p_iso_file = iso9660_ifs_stat_translate(fd_ret->p_iso, iso_filename);
if (!fd_ret->p_iso_file) {
ret = WIMLIB_ERR_OPEN;
goto out;
}
fd_ret->is_iso = 1;
out:
FREE(iso_path);
/* Because we use an union, make sure fd is cleared on error */
if (ret)
fd_ret->fd = 0;
return ret;
}
#endif
static int
open_wim_file(const tchar *filename, struct filedes *fd_ret)
{
int raw_fd;
#ifdef WITH_LIBCDIO
if (open_iso_wim_file(filename, fd_ret) == 0)
return 0;
#endif
raw_fd = topen(filename, O_RDONLY | O_BINARY);
if (raw_fd < 0) {
ERROR_WITH_ERRNO("Can't open \"%"TS"\" read-only", filename);
@ -653,6 +720,16 @@ begin_read(WIMStruct *wim, const void *wim_filename_or_fd, int open_flags)
return ret;
/* The file size is needed for enforcing some limits later. */
#ifdef WITH_LIBCDIO
if ((wim->in_fd.is_udf | wim->in_fd.is_iso) &&
(open_flags & WIMLIB_OPEN_FLAG_WRITE_ACCESS))
return WIMLIB_ERR_WIM_IS_READONLY;
if (wim->in_fd.is_udf)
wim->file_size = udf_get_file_length(wim->in_fd.p_udf_file);
else if (wim->in_fd.is_iso)
wim->file_size = wim->in_fd.p_iso_file->total_size;
else
#endif
if (fstat(wim->in_fd.fd, &stbuf) == 0)
wim->file_size = stbuf.st_size;
@ -668,6 +745,12 @@ begin_read(WIMStruct *wim, const void *wim_filename_or_fd, int open_flags)
* Warning: in Windows native builds, realpath() calls the
* replacement function in win32_replacements.c.
*/
#ifdef WITH_LIBCDIO
/* No overwriting for libcdio, so simply duplicate */
if (tstrchr(wimfile, T('|')))
wim->filename = tstrdup(wimfile);
else
#endif
wim->filename = realpath(wimfile, NULL);
if (!wim->filename) {
ERROR_WITH_ERRNO("Failed to get full path to file "
@ -900,10 +983,22 @@ wim_decrement_refcnt(WIMStruct *wim)
wimlib_assert(wim->refcnt > 0);
if (--wim->refcnt != 0)
return;
if (filedes_valid(&wim->in_fd))
filedes_close(&wim->in_fd);
if (filedes_valid(&wim->out_fd))
filedes_close(&wim->out_fd);
#ifdef WITH_LIBCDIO
if (wim->in_fd.is_udf) {
udf_dirent_free(wim->in_fd.p_udf_file);
udf_close(wim->in_fd.p_udf);
} else if (wim->in_fd.is_iso) {
iso9660_stat_free(wim->in_fd.p_iso_file);
iso9660_close(wim->in_fd.p_iso);
} else {
#endif
if (filedes_valid(&wim->in_fd))
filedes_close(&wim->in_fd);
if (filedes_valid(&wim->out_fd))
filedes_close(&wim->out_fd);
#ifdef WITH_LIBCDIO
}
#endif
wimlib_free_decompressor(wim->decompressor);
xml_free_info_struct(wim->xml_info);
FREE(wim->filename);

View file

@ -6,12 +6,35 @@
#include <sys/types.h>
#include <unistd.h>
#ifdef WITH_LIBCDIO
# define DO_NOT_WANT_COMPATIBILITY
# undef PRAGMA_BEGIN_PACKED
# undef PRAGMA_END_PACKED
# include <cdio/udf.h>
# include <cdio/iso9660.h>
#endif
/* Wrapper around a file descriptor that keeps track of offset (including in
* pipes, which don't support lseek()) and a cached flag that tells whether the
* file descriptor is a pipe or not. */
* pipes, which don't support lseek()), allows the handling of files that are
* contained within ISO images, and a cached flag that tells whether the file
* descriptor is a pipe or not. */
struct filedes {
int fd;
union {
int fd;
#ifdef WITH_LIBCDIO
iso9660_t* p_iso;
udf_t* p_udf;
#endif
};
unsigned int is_pipe : 1;
#ifdef WITH_LIBCDIO
unsigned int is_iso : 1;
unsigned int is_udf : 1;
union {
udf_dirent_t* p_udf_file;
iso9660_stat_t* p_iso_file;
};
#endif
off_t offset;
};
@ -39,9 +62,8 @@ filedes_is_seekable(struct filedes *fd);
static inline void filedes_init(struct filedes *fd, int raw_fd)
{
memset(fd, 0, sizeof(*fd));
fd->fd = raw_fd;
fd->offset = 0;
fd->is_pipe = 0;
}
static inline void filedes_invalidate(struct filedes *fd)