X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fwin32_apply.c;h=ffee267c61bfdee2b4e8a9ae4289129e28ce23da;hp=cc466b19826f8630f9368f9ff71d16c175ae2087;hb=d55cda59032e0abe5f71cd6f16ade943d2713fee;hpb=cbd76a9a7f349b42457c290e2970c9f4ecd873c1 diff --git a/src/win32_apply.c b/src/win32_apply.c index cc466b19..ffee267c 100644 --- a/src/win32_apply.c +++ b/src/win32_apply.c @@ -23,13 +23,22 @@ #ifdef __WIN32__ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include /* for SetSecurityInfo() */ -#include "win32_common.h" -#include "wimlib_internal.h" -#include "dentry.h" -#include "lookup_table.h" -#include "endianness.h" +#include "wimlib/win32_common.h" + +#include "wimlib/apply.h" +#include "wimlib/dentry.h" +#include "wimlib/endianness.h" +#include "wimlib/error.h" +#include "wimlib/lookup_table.h" +#include "wimlib/metadata.h" +#include "wimlib/reparse.h" +#include "wimlib/security.h" #define MAX_CREATE_HARD_LINK_WARNINGS 5 #define MAX_CREATE_SOFT_LINK_WARNINGS 5 @@ -48,6 +57,7 @@ L"If you are not running this program as the administrator, you may\n" static int win32_extract_try_rpfix(u8 *rpbuf, + u16 *rpbuflen_p, const wchar_t *extract_root_realpath, unsigned extract_root_realpath_nchars) { @@ -65,8 +75,7 @@ win32_extract_try_rpfix(u8 *rpbuf, size_t new_print_name_nchars; utf16lechar *p; - ret = parse_reparse_data(rpbuf, 8 + le16_to_cpu(*(u16*)(rpbuf + 4)), - &rpdata); + ret = parse_reparse_data(rpbuf, *rpbuflen_p, &rpdata); if (ret) return ret; @@ -88,7 +97,7 @@ win32_extract_try_rpfix(u8 *rpbuf, stripped_nchars = ret; target = rpdata.substitute_name; target_nchars = rpdata.substitute_name_nbytes / sizeof(utf16lechar); - stripped_target = target + 6; + stripped_target = target + stripped_nchars; stripped_target_nchars = target_nchars - stripped_nchars; new_target = alloca((6 + extract_root_realpath_nchars + @@ -97,8 +106,7 @@ win32_extract_try_rpfix(u8 *rpbuf, p = new_target; if (stripped_nchars == 6) { /* Include \??\ prefix if it was present before */ - wmemcpy(p, L"\\??\\", 4); - p += 4; + p = wmempcpy(p, L"\\??\\", 4); } /* Print name excludes the \??\ if present. */ @@ -110,12 +118,10 @@ win32_extract_try_rpfix(u8 *rpbuf, *p++ = extract_root_realpath[1]; } /* Copy the rest of the extract root */ - wmemcpy(p, extract_root_realpath + 2, extract_root_realpath_nchars - 2); - p += extract_root_realpath_nchars - 2; + p = wmempcpy(p, extract_root_realpath + 2, extract_root_realpath_nchars - 2); /* Append the stripped target */ - wmemcpy(p, stripped_target, stripped_target_nchars); - p += stripped_target_nchars; + p = wmempcpy(p, stripped_target, stripped_target_nchars); new_target_nchars = p - new_target; new_print_name_nchars = p - new_print_name; @@ -129,7 +135,7 @@ win32_extract_try_rpfix(u8 *rpbuf, rpdata.substitute_name_nbytes = new_target_nchars * sizeof(utf16lechar); rpdata.print_name = new_print_name; rpdata.print_name_nbytes = new_print_name_nchars * sizeof(utf16lechar); - return make_reparse_buffer(&rpdata, rpbuf); + return make_reparse_buffer(&rpdata, rpbuf, rpbuflen_p); } /* Wrapper around the FSCTL_SET_REPARSE_POINT ioctl to set the reparse data on @@ -142,12 +148,13 @@ win32_set_reparse_data(HANDLE h, struct apply_args *args) { int ret; - u8 rpbuf[REPARSE_POINT_MAX_SIZE]; + u8 rpbuf[REPARSE_POINT_MAX_SIZE] _aligned_attribute(8); DWORD bytesReturned; + u16 rpbuflen; DEBUG("Setting reparse data on \"%ls\"", path); - ret = wim_inode_get_reparse_data(inode, rpbuf); + ret = wim_inode_get_reparse_data(inode, rpbuf, &rpbuflen); if (ret) return ret; @@ -157,6 +164,7 @@ win32_set_reparse_data(HANDLE h, !inode->i_not_rpfixed) { ret = win32_extract_try_rpfix(rpbuf, + &rpbuflen, args->target_realpath, args->target_realpath_len); if (ret) @@ -185,7 +193,7 @@ win32_set_reparse_data(HANDLE h, * "Not used with this operation; set to NULL." */ if (!DeviceIoControl(h, FSCTL_SET_REPARSE_POINT, rpbuf, - 8 + le16_to_cpu(*(u16*)(rpbuf + 4)), + rpbuflen, NULL, 0, &bytesReturned /* lpBytesReturned */, NULL /* lpOverlapped */)) @@ -668,7 +676,6 @@ win32_finish_extract_stream(HANDLE h, const struct wim_dentry *dentry, { int ret = 0; const struct wim_inode *inode = dentry->d_inode; - const wchar_t *short_name; if (stream_name_utf16 == NULL) { /* Unnamed stream. */ @@ -724,7 +731,7 @@ win32_finish_extract_stream(HANDLE h, const struct wim_dentry *dentry, } if (dentry_has_short_name(dentry)) - SetFileShortNameW(h, short_name); + SetFileShortNameW(h, dentry->short_name); else if (running_on_windows_7_or_later()) SetFileShortNameW(h, L""); } else { @@ -1228,6 +1235,7 @@ win32_do_apply_dentry(const wchar_t *output_path, !(args->vol_flags & FILE_SUPPORTS_REPARSE_POINTS)) { WARNING("Not extracting reparse point \"%ls\"", output_path); + dentry->not_extracted = 1; } else { /* Create the file, directory, or reparse point, and extract the * data streams. */ @@ -1270,13 +1278,6 @@ win32_do_apply_dentry_timestamps(const wchar_t *path, HANDLE h; const struct wim_inode *inode = dentry->d_inode; - if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT && - !(args->vol_flags & FILE_SUPPORTS_REPARSE_POINTS)) - { - /* Skip reparse points not extracted */ - return 0; - } - /* Windows doesn't let you change the timestamps of the root directory * (at least on FAT, which is dumb but expected since FAT doesn't store * any metadata about the root directory...) */