From a2984b07d10ef6b49a509cf0289bd9dc824e42e7 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 10 Mar 2013 01:38:55 -0600 Subject: [PATCH] Win32 apply --- src/add_image.c | 107 +++----------- src/extract_image.c | 315 ++++++++++++++++++++++++++++++++++++++++++ src/resource.c | 1 - src/wimlib_internal.h | 26 ++-- src/win32.c | 68 +++++++++ src/write.c | 6 +- 6 files changed, 420 insertions(+), 103 deletions(-) create mode 100644 src/win32.c diff --git a/src/add_image.c b/src/add_image.c index fa3e77b0..7adc5252 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -21,6 +21,7 @@ * along with wimlib; if not, see http://www.gnu.org/licenses/. */ +#include "config.h" #if defined(__CYGWIN__) || defined(__WIN32__) # include @@ -48,19 +49,10 @@ #include #include -#if defined(__CYGWIN__) || defined(__WIN32__) -/*#define ERROR_WIN32_SAFE(format, ...) \*/ -/*{( \*/ - /*DWORD err = GetLastError(); \*/ - /*ERROR(format, ##__VA_ARGS__); \*/ - /*SetLastError(err); \*/ -/*)}*/ -#define DEBUG_WIN32_SAFE(format, ...) \ -({ \ - DWORD err = GetLastError(); \ - DEBUG(format, ##__VA_ARGS__); \ - SetLastError(err); \ -}) +#ifdef HAVE_ALLOCA_H +#include +#else +#include #endif #define WIMLIB_ADD_IMAGE_FLAG_ROOT 0x80000000 @@ -118,71 +110,12 @@ err: } #if defined(__CYGWIN__) || defined(__WIN32__) + static u64 FILETIME_to_u64(const FILETIME *ft) { return ((u64)ft->dwHighDateTime << 32) | (u64)ft->dwLowDateTime; } -#ifdef ENABLE_ERROR_MESSAGES -static void win32_error(DWORD err_code) -{ - char *buffer; - DWORD nchars; - nchars = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, err_code, 0, - (char*)&buffer, 0, NULL); - if (nchars == 0) { - ERROR("Error printing error message! " - "Computer will self-destruct in 3 seconds."); - } else { - ERROR("Win32 error: %s", buffer); - LocalFree(buffer); - } -} -#else -#define win32_error(err_code) -#endif - -static HANDLE win32_open_file(const wchar_t *path) -{ - return CreateFileW(path, - GENERIC_READ | READ_CONTROL, - FILE_SHARE_READ, - NULL, /* lpSecurityAttributes */ - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT, - NULL /* hTemplateFile */); -} - -int win32_read_file(const char *filename, - void *handle, u64 offset, size_t size, u8 *buf) -{ - HANDLE h = handle; - DWORD err; - DWORD bytesRead; - LARGE_INTEGER liOffset = {.QuadPart = offset}; - - wimlib_assert(size <= 0xffffffff); - - if (SetFilePointerEx(h, liOffset, NULL, FILE_BEGIN)) - if (ReadFile(h, buf, size, &bytesRead, NULL) && bytesRead == size) - return 0; - err = GetLastError(); - ERROR("Error reading \"%s\"", filename); - win32_error(err); - return WIMLIB_ERR_READ; -} - -void win32_close_handle(void *handle) -{ - CloseHandle((HANDLE)handle); -} - -void *win32_open_handle(const char *path_utf16) -{ - return (void*)win32_open_file((const wchar_t*)path_utf16); -} static int build_dentry_tree(struct wim_dentry **root_ret, const char *root_disk_path, @@ -221,14 +154,10 @@ static int win32_get_security_descriptor(struct wim_dentry *dentry, BOOL status; DWORD err; -#ifdef BACKUP_SECURITY_INFORMATION - requestedInformation = BACKUP_SECURITY_INFORMATION; -#else requestedInformation = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION; -#endif /* Request length of security descriptor */ status = GetFileSecurityW(path_utf16, requestedInformation, NULL, 0, &lenNeeded); @@ -369,7 +298,7 @@ static int win32_sha1sum(const wchar_t *path, u8 hash[SHA1_HASH_SIZE]) DWORD bytesRead; int ret; - hFile = win32_open_file(path); + hFile = win32_open_file(path); if (hFile == INVALID_HANDLE_VALUE) return WIMLIB_ERR_OPEN; @@ -425,12 +354,11 @@ static int win32_capture_stream(const char *path, char *utf8_stream_name; size_t utf8_stream_name_len; ret = utf16_to_utf8((const char *)p, - colon - p, + (colon - p) * sizeof(wchar_t), &utf8_stream_name, &utf8_stream_name_len); if (ret) goto out; - DEBUG_WIN32_SAFE("Add alternate data stream %s:%s", path, utf8_stream_name); ads_entry = inode_add_ads(inode, utf8_stream_name); FREE(utf8_stream_name); if (!ads_entry) { @@ -450,7 +378,7 @@ static int win32_capture_stream(const char *path, spath[path_utf16_nchars] = L':'; memcpy(&spath[path_utf16_nchars + 1], p, (colon - p) * sizeof(wchar_t)); } - spath[spath_nchars] = L'\0'; + spath[spath_nchars] = L'\0'; ret = win32_sha1sum(spath, hash); if (ret) { @@ -497,7 +425,7 @@ static int win32_capture_streams(const char *path, int ret; HANDLE hFind; DWORD err; - + hFind = FindFirstStreamW(path_utf16, FindStreamInfoStandard, &dat, 0); if (hFind == INVALID_HANDLE_VALUE) { ERROR("Win32 API: Failed to look up data streams of \"%s\"", @@ -829,14 +757,12 @@ static int build_dentry_tree(struct wim_dentry **root_ret, sd_set = extra_arg; } - DEBUG_WIN32_SAFE("root_disk_path=\"%s\"", root_disk_path); ret = utf8_to_utf16(root_disk_path, strlen(root_disk_path), (char**)&path_utf16, &path_utf16_nchars); if (ret) goto out_destroy_sd_set; path_utf16_nchars /= sizeof(wchar_t); - DEBUG_WIN32_SAFE("Win32: Opening file `%s'", root_disk_path); HANDLE hFile = win32_open_file(path_utf16); if (hFile == INVALID_HANDLE_VALUE) { err = GetLastError(); @@ -892,7 +818,16 @@ static int build_dentry_tree(struct wim_dentry **root_ret, if (inode_is_directory(inode)) { /* Directory (not a reparse point) --- recurse to children */ - DEBUG_WIN32_SAFE("Recursing to directory \"%s\"", root_disk_path); + + /* But first... directories may have alternate data streams that + * need to be captured */ + ret = win32_capture_streams(root_disk_path, + path_utf16, + path_utf16_nchars, + inode, + lookup_table); + if (ret) + goto out_close_handle; ret = win32_recurse_directory(root, root_disk_path, lookup_table, @@ -906,14 +841,12 @@ static int build_dentry_tree(struct wim_dentry **root_ret, } else if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) { /* Reparse point: save the reparse tag and data */ - DEBUG_WIN32_SAFE("Capturing reparse point `%s'", root_disk_path); ret = win32_capture_reparse_point(root_disk_path, hFile, inode, lookup_table); } else { - DEBUG_WIN32_SAFE("Capturing streams of \"%s\"", root_disk_path); /* Not a directory, not a reparse point */ ret = win32_capture_streams(root_disk_path, path_utf16, diff --git a/src/extract_image.c b/src/extract_image.c index c0d951cb..d91f7262 100644 --- a/src/extract_image.c +++ b/src/extract_image.c @@ -30,6 +30,14 @@ #include "config.h" +#if defined(__CYGWIN__) || defined(__WIN32__) +#include +# ifdef ERROR +# undef ERROR +# endif +#include +#endif + #include #include #include @@ -54,6 +62,201 @@ #include #endif +#ifdef HAVE_ALLOCA_H +#include +#else +#include +#endif + +#if defined(__CYGWIN__) || defined(__WIN32__) + +static int win32_set_reparse_data(HANDLE h, + u32 reparse_tag, + const struct wim_lookup_table_entry *lte, + const wchar_t *path, + const char *path_utf8) +{ + int ret; + u8 *buf; + size_t len; + + if (!lte) { + WARNING("\"%s\" is marked as a reparse point but had no reparse data", + path_utf8); + return 0; + } + len = wim_resource_size(lte); + if (len > 16 * 1024 - 8) { + WARNING("\"%s\": reparse data too long!", path_utf8); + return 0; + } + buf = alloca(len + 8); + ret = read_full_wim_resource(lte, buf + 8, 0); + if (ret) + return ret; + *(u32*)(buf + 0) = reparse_tag; + *(u16*)(buf + 4) = len; + if (!DeviceIoControl(h, FSCTL_SET_REPARSE_POINT, buf, len + 8, + NULL, 0, NULL, NULL)) + { + DWORD err = GetLastError(); + ERROR("Failed to set reparse data on \"%s\"", + path_utf8); + win32_error(err); + ret = WIMLIB_ERR_WRITE; + } else + ret = 0; + return ret; +} + + +static int win32_extract_chunk(const u8 *buf, size_t len, u64 offset, void *arg) +{ + HANDLE hStream = arg; + + DWORD nbytes_written; + wimlib_assert(len <= 0xffffffff); + + if (!WriteFile(hStream, buf, len, &nbytes_written, NULL) || + nbytes_written != len) + { + DWORD err = GetLastError(); + ERROR("WriteFile(): write error"); + win32_error(err); + return WIMLIB_ERR_WRITE; + } + return 0; +} + +static int do_win32_extract_stream(HANDLE hStream, struct wim_lookup_table_entry *lte) +{ + return extract_wim_resource(lte, wim_resource_size(lte), + win32_extract_chunk, hStream); +} + +static int win32_extract_stream(const struct wim_inode *inode, + const wchar_t *path, + const wchar_t *stream_name_utf16, + struct wim_lookup_table_entry *lte, + const char *path_utf8) +{ + wchar_t *stream_path; + HANDLE h; + int ret; + + if (stream_name_utf16) { + size_t stream_path_nchars; + size_t path_nchars = wcslen(path); + size_t stream_name_nchars = wcslen(stream_name_utf16); + + stream_path_nchars = path_nchars + 1 + stream_name_nchars; + + stream_path = alloca((stream_path_nchars + 1) * sizeof(wchar_t)); + + memcpy(stream_path, path, path_nchars * sizeof(wchar_t)); + stream_path[path_nchars] = L':'; + memcpy(&stream_path[path_nchars + 1], stream_name_utf16, + stream_name_nchars * sizeof(wchar_t)); + stream_path[stream_path_nchars] = L'\0'; + + /*wsprintf(stream_path, stream_path_nchars, L"%ls:%ls",*/ + /*path, stream_name_utf16);*/ + } else { + stream_path = (wchar_t*)path; + } + + h = CreateFileW(stream_path, + GENERIC_WRITE | WRITE_OWNER | WRITE_DAC, + 0, + NULL, + CREATE_ALWAYS, + FILE_FLAG_OPEN_REPARSE_POINT | + FILE_FLAG_BACKUP_SEMANTICS | + inode->i_attributes, + NULL); + if (!h) { + win32_error(GetLastError()); + ret = WIMLIB_ERR_OPEN; + goto fail; + } + + if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) { + ret = win32_set_reparse_data(h, inode->i_reparse_tag, + lte, path, path_utf8); + if (ret) + goto fail_close_handle; + } else { + if (lte) { + ret = do_win32_extract_stream(h, lte); + if (ret) + goto fail_close_handle; + } + } + + if (!CloseHandle(h)) { + win32_error(GetLastError()); + ret = WIMLIB_ERR_WRITE; + goto fail; + } + ret = 0; + goto out; +fail_close_handle: + CloseHandle(h); +fail: + ERROR("Error extracting %s", path_utf8); +out: + return ret; +} + +static int win32_extract_streams(struct wim_inode *inode, + const wchar_t *path, + const char *path_utf8) +{ + struct wim_lookup_table_entry *unnamed_lte; + int ret; + + ret = win32_extract_stream(inode, path, NULL, unnamed_lte, path_utf8); + if (ret) + goto out; + + for (u16 i = 0; i < inode->i_num_ads; i++) { + const struct wim_ads_entry *ads_entry = &inode->i_ads_entries[i]; + if (ads_entry->stream_name_len != 0) { + ret = win32_extract_stream(inode, + path, + (const wchar_t*)ads_entry->stream_name, + ads_entry->lte, + path_utf8); + if (ret) + goto out; + } + } + ret = 0; +out: + return ret; +} + +static int win32_set_security_data(const struct wim_inode *inode, + const wchar_t *path, + const struct wim_security_data *sd, + const char *path_utf8) +{ + SECURITY_INFORMATION securityInformation = DACL_SECURITY_INFORMATION | + SACL_SECURITY_INFORMATION | + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION; + if (!SetFileSecurityW(path, securityInformation, + (PSECURITY_DESCRIPTOR)sd->descriptors[inode->i_security_id])) + { + DWORD err = GetLastError(); + ERROR("Can't set security descriptor on \"%s\"", path_utf8); + win32_error(err); + return WIMLIB_ERR_WRITE; + } + return 0; +} + +#else static int extract_regular_file_linked(struct wim_dentry *dentry, const char *output_path, struct apply_args *args, @@ -322,6 +525,8 @@ static int extract_symlink(struct wim_dentry *dentry, return 0; } +#endif /* !__CYGWIN__ && !__WIN32__ */ + static int extract_directory(struct wim_dentry *dentry, const char *output_path, bool is_root) { @@ -379,6 +584,60 @@ static int apply_dentry_normal(struct wim_dentry *dentry, void *arg) memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len); output_path[len + dentry->full_path_utf8_len] = '\0'; +#if defined(__CYGWIN__) || defined(__WIN32__) + char *utf16_path; + size_t utf16_path_len; + DWORD err; + int ret; + ret = utf8_to_utf16(output_path, len + dentry->full_path_utf8_len, + &utf16_path, &utf16_path_len); + if (ret) + return ret; + + if (inode->i_nlink > 1 && inode->i_extracted_file != NULL) { + /* Linked file, with another name already extracted */ + if (!CreateHardLinkW((const wchar_t*)inode->i_extracted_file, + (const wchar_t*)utf16_path, + NULL)) + { + err = GetLastError(); + ERROR("Can't create hard link \"%s\"", output_path); + ret = WIMLIB_ERR_LINK; + win32_error(err); + goto out_free_utf16_path; + } + ret = 0; + goto out_free_utf16_path; + } + ret = win32_extract_streams(inode, (const wchar_t*)utf16_path, + output_path); + if (ret) + goto out_free_utf16_path; + + if (inode->i_security_id != -1) { + ret = win32_set_security_data(inode, + (const wchar_t*)utf16_path, + wim_const_security_data(args->w), + output_path); + if (ret) + goto out_free_utf16_path; + } + + /*if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) {*/ + /*ret = win32_set_reparse_data(inode, path, output_path);*/ + /*if (ret)*/ + /*goto out_free_utf16_path;*/ + /*}*/ + + if (inode->i_nlink > 1) { + inode->i_extracted_file = utf16_path; + utf16_path = NULL; + } + ret = 0; +out_free_utf16_path: + FREE(utf16_path); + return ret; +#else if (inode_is_symlink(inode)) return extract_symlink(dentry, args, output_path); else if (inode_is_directory(inode)) @@ -387,6 +646,7 @@ static int apply_dentry_normal(struct wim_dentry *dentry, void *arg) output_path, false); else return extract_regular_file(dentry, args, output_path); +#endif } /* Apply timestamps to an extracted file or directory */ @@ -402,6 +662,53 @@ static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg) memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len); output_path[len + dentry->full_path_utf8_len] = '\0'; +#if defined(__CYGWIN__) || defined(__WIN32__) + /* Win32 */ + char *utf16_path; + size_t utf16_path_len; + DWORD err; + HANDLE h; + BOOL bret1, bret2; + + ret = utf8_to_utf16(output_path, len + dentry->full_path_utf8_len, + &utf16_path, &utf16_path_len); + if (ret) + return ret; + h = CreateFile(utf16_path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, + NULL); + + if (!h) + err = GetLastError(); + FREE(utf16_path); + if (!h) + goto fail; + + FILETIME creationTime = {.dwLowDateTime = dentry->d_inode->i_creation_time & 0xffffffff, + .dwHighDateTime = dentry->d_inode->i_creation_time >> 32}; + FILETIME lastAccessTime = {.dwLowDateTime = dentry->d_inode->i_last_access_time & 0xffffffff, + .dwHighDateTime = dentry->d_inode->i_last_access_time >> 32}; + FILETIME lastWriteTime = {.dwLowDateTime = dentry->d_inode->i_last_write_time & 0xffffffff, + .dwHighDateTime = dentry->d_inode->i_last_write_time >> 32}; + + if (!SetFileTime(h, &creationTime, &lastAccessTime, &lastWriteTime)) { + err = GetLastError(); + CloseHandle(h); + goto fail; + } + if (!CloseHandle(h)) { + err = GetLastError(); + goto fail; + } + return 0; +fail: + err = GetLastError(); + ERROR("Can't set timestamps on \"%s\"", output_path); + win32_error(err); + return WIMLIB_ERR_WRITE; +#else + /* UNIX */ + /* Convert the WIM timestamps, which are accurate to 100 nanoseconds, * into struct timeval's. */ struct timeval tv[2]; @@ -430,6 +737,7 @@ static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg) } } return 0; +#endif } /* Extract a dentry if it hasn't already been extracted, and either the dentry @@ -849,6 +1157,13 @@ WIMLIBAPI int wimlib_extract_image(WIMStruct *w, == (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)) return WIMLIB_ERR_INVALID_PARAM; +#if defined(__CYGWIN__) || defined(__WIN32__) + if (extract_flags & WIMLIB_EXTRACT_FLAG_UNIX_DATA) { + ERROR("Extracting UNIX data is not supported on Windows"); + return WIMLIB_ERR_INVALID_PARAM; + } +#endif + if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) { #ifdef WITH_NTFS_3G if ((extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK))) { diff --git a/src/resource.c b/src/resource.c index 69a531fb..eb79c749 100644 --- a/src/resource.c +++ b/src/resource.c @@ -561,7 +561,6 @@ int read_wim_resource(const struct wim_lookup_table_entry *lte, u8 buf[], #if defined(__CYGWIN__) || defined(__WIN32__) case RESOURCE_WIN32: wimlib_assert(lte->file_on_disk_fp != NULL); - DEBUG("Calling win32_read_file()"); ret = win32_read_file(lte->file_on_disk, lte->file_on_disk_fp, offset, size, buf); break; diff --git a/src/wimlib_internal.h b/src/wimlib_internal.h index 8a99f30d..b1b2ecd7 100644 --- a/src/wimlib_internal.h +++ b/src/wimlib_internal.h @@ -372,10 +372,6 @@ extern bool exclude_path(const char *path, extern int add_new_dentry_tree(WIMStruct *dest_wim, struct wim_dentry *root, struct wim_security_data *sd); -#if defined(__CYGWIN__) || defined(__WIN32__) -extern FILE *win32_open_fp(const char *path_utf16); -#endif - /* extract_image.c */ /* Internal use only */ @@ -435,7 +431,6 @@ struct apply_args { #ifdef WITH_NTFS_3G struct _ntfs_volume *vol; #endif - struct list_head empty_files; wimlib_progress_func_t progress_func; int (*apply_dentry)(struct wim_dentry *, void *); }; @@ -485,13 +480,6 @@ extern int extract_wim_resource(const struct wim_lookup_table_entry *lte, u64 size, extract_chunk_func_t extract_chunk, void *extract_chunk_arg); -#if defined(__CYGWIN__) || defined(__WIN32__) -extern int win32_read_file(const char *filename, void *handle, u64 offset, - size_t size, u8 *buf); -extern void *win32_open_handle(const char *path_utf16); -extern void win32_close_handle(void *handle); -#endif - /* * Extracts the first @size bytes of the WIM resource specified by @lte to the * open file descriptor @fd. @@ -540,6 +528,20 @@ extern int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *)); extern void destroy_image_metadata(struct wim_image_metadata *imd, struct wim_lookup_table *lt); +/* win32.c */ + +#if defined(__CYGWIN__) || defined(__WIN32__) +extern int win32_read_file(const char *filename, void *handle, u64 offset, + size_t size, u8 *buf); +extern void *win32_open_file(const void *path_utf16); +extern void win32_close_file(void *handle); +#ifdef ENABLE_ERROR_MESSAGES +extern void win32_error(u32 err); +#else +#define win32_error(err) +#endif +#endif + /* write.c */ diff --git a/src/win32.c b/src/win32.c new file mode 100644 index 00000000..b3468a9a --- /dev/null +++ b/src/win32.c @@ -0,0 +1,68 @@ +#include "config.h" + +#if defined(__CYGWIN__) || defined(__WIN32__) +#include +# ifdef ERROR +# undef ERROR +# endif + +#include "wimlib_internal.h" + + +#ifdef ENABLE_ERROR_MESSAGES +void win32_error(u32 err_code) +{ + char *buffer; + DWORD nchars; + nchars = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, err_code, 0, + (char*)&buffer, 0, NULL); + if (nchars == 0) { + ERROR("Error printing error message! " + "Computer will self-destruct in 3 seconds."); + } else { + ERROR("Win32 error: %s", buffer); + LocalFree(buffer); + } +} +#else +#define win32_error(err_code) +#endif + +void *win32_open_file(const void *path) +{ + return CreateFileW((const wchar_t*)path, + GENERIC_READ | READ_CONTROL, + FILE_SHARE_READ, + NULL, /* lpSecurityAttributes */ + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | + FILE_FLAG_OPEN_REPARSE_POINT, + NULL /* hTemplateFile */); +} + +int win32_read_file(const char *filename, + void *handle, u64 offset, size_t size, u8 *buf) +{ + HANDLE h = handle; + DWORD err; + DWORD bytesRead; + LARGE_INTEGER liOffset = {.QuadPart = offset}; + + wimlib_assert(size <= 0xffffffff); + + if (SetFilePointerEx(h, liOffset, NULL, FILE_BEGIN)) + if (ReadFile(h, buf, size, &bytesRead, NULL) && bytesRead == size) + return 0; + err = GetLastError(); + ERROR("Error reading \"%s\"", filename); + win32_error(err); + return WIMLIB_ERR_READ; +} + +void win32_close_file(void *handle) +{ + CloseHandle((HANDLE)handle); +} + +#endif /* __CYGWIN__ || __WIN32__ */ diff --git a/src/write.c b/src/write.c index c346e61c..da0ef9c9 100644 --- a/src/write.c +++ b/src/write.c @@ -259,7 +259,7 @@ static int prepare_resource_for_read(struct wim_lookup_table_entry *lte { switch (lte->resource_location) { case RESOURCE_IN_FILE_ON_DISK: - if (!lte->file_on_disk_fp) { + if (!lte->file_on_disk_fp) { lte->file_on_disk_fp = fopen(lte->file_on_disk, "rb"); if (!lte->file_on_disk_fp) { ERROR_WITH_ERRNO("Failed to open the file " @@ -297,7 +297,7 @@ static int prepare_resource_for_read(struct wim_lookup_table_entry *lte #if defined(__CYGWIN__) || defined(__WIN32__) case RESOURCE_WIN32: if (!lte->file_on_disk_fp) { - lte->file_on_disk_fp = win32_open_handle(lte->file_on_disk); + lte->file_on_disk_fp = win32_open_file(lte->file_on_disk); if (!lte->file_on_disk_fp) return WIMLIB_ERR_OPEN; } @@ -337,7 +337,7 @@ static void end_wim_resource_read(struct wim_lookup_table_entry *lte else if (lte->resource_location == RESOURCE_WIN32 && lte->file_on_disk_fp) { - win32_close_handle(lte->file_on_disk_fp); + win32_close_file(lte->file_on_disk_fp); lte->file_on_disk_fp = NULL; } #endif -- 2.27.0