diff options
Diffstat (limited to 'libarchive/archive_write_disk_windows.c')
-rw-r--r-- | libarchive/archive_write_disk_windows.c | 107 |
1 files changed, 47 insertions, 60 deletions
diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c index 57000aaa131d5..39fd65fa0b8f2 100644 --- a/libarchive/archive_write_disk_windows.c +++ b/libarchive/archive_write_disk_windows.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2003-2010 Tim Kientzle - * Copyright (c) 2011 Michihiro NAKAJIMA + * Copyright (c) 2011-2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,9 +33,6 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif #ifdef HAVE_SYS_UTIME_H #include <sys/utime.h> #endif @@ -48,13 +45,9 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_LIMITS_H #include <limits.h> #endif -#include <stdio.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif #include <winioctl.h> /* TODO: Support Mac OS 'quarantine' feature. This is really just a @@ -89,7 +82,7 @@ static BOOL SetFilePointerEx_perso(HANDLE hFile, if(lpNewFilePointer) { lpNewFilePointer->QuadPart = li.QuadPart; } - return li.LowPart != -1 || GetLastError() == NO_ERROR; + return li.LowPart != (DWORD)-1 || GetLastError() == NO_ERROR; } struct fixup_entry { @@ -144,8 +137,8 @@ struct archive_write_disk { struct fixup_entry *current_fixup; int64_t user_uid; int skip_file_set; - dev_t skip_file_dev; - ino_t skip_file_ino; + int64_t skip_file_dev; + int64_t skip_file_ino; time_t start_time; int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid); @@ -214,26 +207,24 @@ struct archive_write_disk { static int check_symlinks(struct archive_write_disk *); static int create_filesystem_object(struct archive_write_disk *); -static struct fixup_entry *current_fixup(struct archive_write_disk *, const wchar_t *pathname); -#if defined(HAVE_FCHDIR) && defined(PATH_MAX) -static void edit_deep_directories(struct archive_write_disk *ad); -#endif +static struct fixup_entry *current_fixup(struct archive_write_disk *, + const wchar_t *pathname); static int cleanup_pathname(struct archive_write_disk *); static int create_dir(struct archive_write_disk *, wchar_t *); static int create_parent_dir(struct archive_write_disk *, wchar_t *); +static int la_chmod(const wchar_t *, mode_t); static int older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *); +static int permissive_name_w(struct archive_write_disk *); static int restore_entry(struct archive_write_disk *); -#ifdef HAVE_POSIX_ACL -static int set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *, - acl_type_t, int archive_entry_acl_type, const char *tn); -#endif -static int set_acls(struct archive_write_disk *, HANDLE h, const wchar_t *, struct archive_acl *); +static int set_acls(struct archive_write_disk *, HANDLE h, + const wchar_t *, struct archive_acl *); static int set_xattrs(struct archive_write_disk *); static int set_fflags(struct archive_write_disk *); static int set_ownership(struct archive_write_disk *); static int set_mode(struct archive_write_disk *, int mode); -static int set_times(struct archive_write_disk *, HANDLE, int, const wchar_t *, - time_t, long, time_t, long, time_t, long, time_t, long); +static int set_times(struct archive_write_disk *, HANDLE, int, + const wchar_t *, time_t, long, time_t, long, time_t, + long, time_t, long); static int set_times_from_entry(struct archive_write_disk *); static struct fixup_entry *sort_dir_list(struct fixup_entry *p); static ssize_t write_data_block(struct archive_write_disk *, @@ -243,11 +234,14 @@ static struct archive_vtable *archive_write_disk_vtable(void); static int _archive_write_disk_close(struct archive *); static int _archive_write_disk_free(struct archive *); -static int _archive_write_disk_header(struct archive *, struct archive_entry *); +static int _archive_write_disk_header(struct archive *, + struct archive_entry *); static int64_t _archive_write_disk_filter_bytes(struct archive *, int); static int _archive_write_disk_finish_entry(struct archive *); -static ssize_t _archive_write_disk_data(struct archive *, const void *, size_t); -static ssize_t _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t); +static ssize_t _archive_write_disk_data(struct archive *, const void *, + size_t); +static ssize_t _archive_write_disk_data_block(struct archive *, const void *, + size_t, int64_t); #define bhfi_dev(bhfi) ((bhfi)->dwVolumeSerialNumber) /* Treat FileIndex as i-node. We should remove a sequence number @@ -361,7 +355,7 @@ file_information(struct archive_write_disk *a, wchar_t *path, * So we have to make the full-pathname in another way, which does not * break "../" path string. */ -int +static int permissive_name_w(struct archive_write_disk *a) { wchar_t *wn, *wnp; @@ -424,10 +418,12 @@ permissive_name_w(struct archive_write_disk *a) wn = _wcsdup(wnp); if (wn == NULL) return (-1); - archive_wstring_ensure(&(a->_name_data), 8 + wcslen(wn) + 1); + archive_wstring_ensure(&(a->_name_data), + 8 + wcslen(wn) + 1); a->name = a->_name_data.s; /* Prepend "\\?\UNC\" */ - archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8); + archive_wstrncpy(&(a->_name_data), + L"\\\\?\\UNC\\", 8); archive_wstrcat(&(a->_name_data), wn+2); free(wn); return (0); @@ -457,7 +453,8 @@ permissive_name_w(struct archive_write_disk *a) wn = _wcsdup(wnp); if (wn == NULL) return (-1); - archive_wstring_ensure(&(a->_name_data), 4 + 2 + wcslen(wn) + 1); + archive_wstring_ensure(&(a->_name_data), + 4 + 2 + wcslen(wn) + 1); a->name = a->_name_data.s; /* Prepend "\\?\" and drive name. */ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); @@ -484,7 +481,7 @@ permissive_name_w(struct archive_write_disk *a) return (0); } -int +static int la_chmod(const wchar_t *path, mode_t mode) { DWORD attr; @@ -917,6 +914,7 @@ archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i) static ssize_t write_data_block(struct archive_write_disk *a, const char *buff, size_t size) { + OVERLAPPED ol; uint64_t start_size = size; DWORD bytes_written = 0; ssize_t block_size = 0, bytes_to_write; @@ -968,26 +966,13 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size) * truncate it to the block boundary. */ bytes_to_write = size; if (a->offset + bytes_to_write > block_end) - bytes_to_write = block_end - a->offset; + bytes_to_write = (DWORD)(block_end - a->offset); } - /* Seek if necessary to the specified offset. */ - if (a->offset != a->fd_offset) { - LARGE_INTEGER distance; - distance.QuadPart = a->offset; - if (SetFilePointerEx_perso(a->fh, distance, NULL, FILE_BEGIN) == 0) { - DWORD lasterr = GetLastError(); - if (lasterr == ERROR_ACCESS_DENIED) - errno = EBADF; - else - la_dosmaperr(lasterr); - archive_set_error(&a->archive, errno, - "Seek failed"); - return (ARCHIVE_FATAL); - } - a->fd_offset = a->offset; - } + memset(&ol, 0, sizeof(ol)); + ol.Offset = (DWORD)(a->offset & 0xFFFFFFFF); + ol.OffsetHigh = (DWORD)(a->offset >> 32); if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write, - &bytes_written, NULL)) { + &bytes_written, &ol)) { DWORD lasterr; lasterr = GetLastError(); @@ -1004,7 +989,7 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size) a->offset += bytes_written; a->fd_offset = a->offset; } - return (start_size - size); + return ((ssize_t)(start_size - size)); } static ssize_t @@ -1393,7 +1378,8 @@ restore_entry(struct archive_write_disk *a) if (a->skip_file_set && bhfi_dev(&a->st) == a->skip_file_dev && bhfi_ino(&a->st) == a->skip_file_ino) { - archive_set_error(&a->archive, 0, "Refusing to overwrite archive"); + archive_set_error(&a->archive, 0, + "Refusing to overwrite archive"); return (ARCHIVE_FAILED); } @@ -2209,7 +2195,8 @@ create_dir(struct archive_write_disk *a, wchar_t *path) * don't add it to the fixup list here, as it's already been * added. */ - if (file_information(a, path, &st, &st_mode, 0) == 0 && S_ISDIR(st_mode)) + if (file_information(a, path, &st, &st_mode, 0) == 0 && + S_ISDIR(st_mode)) return (ARCHIVE_OK); archive_set_error(&a->archive, errno, "Failed to create dir '%ls'", @@ -2252,7 +2239,7 @@ set_times(struct archive_write_disk *a, time_t atime, long atime_nanos, time_t birthtime, long birthtime_nanos, time_t mtime, long mtime_nanos, - time_t ctime, long ctime_nanos) + time_t ctime_sec, long ctime_nanos) { #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) #define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\ @@ -2263,7 +2250,7 @@ set_times(struct archive_write_disk *a, FILETIME *pfbtime; FILETIME fatime, fbtime, fmtime; - (void)ctime; /* UNUSED */ + (void)ctime_sec; /* UNUSED */ (void)ctime_nanos; /* UNUSED */ if (h != INVALID_HANDLE_VALUE) { @@ -2314,11 +2301,11 @@ settimes_failed: static int set_times_from_entry(struct archive_write_disk *a) { - time_t atime, birthtime, mtime, ctime; + time_t atime, birthtime, mtime, ctime_sec; long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec; /* Suitable defaults. */ - atime = birthtime = mtime = ctime = a->start_time; + atime = birthtime = mtime = ctime_sec = a->start_time; atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0; /* If no time was provided, we're done. */ @@ -2340,7 +2327,7 @@ set_times_from_entry(struct archive_write_disk *a) mtime_nsec = archive_entry_mtime_nsec(a->entry); } if (archive_entry_ctime_is_set(a->entry)) { - ctime = archive_entry_ctime(a->entry); + ctime_sec = archive_entry_ctime(a->entry); ctime_nsec = archive_entry_ctime_nsec(a->entry); } @@ -2348,7 +2335,7 @@ set_times_from_entry(struct archive_write_disk *a) atime, atime_nsec, birthtime, birthtime_nsec, mtime, mtime_nsec, - ctime, ctime_nsec); + ctime_sec, ctime_nsec); } static int @@ -2471,7 +2458,7 @@ set_xattrs(struct archive_write_disk *a) } static void -fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns) +fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns) { ULARGE_INTEGER utc; @@ -2480,11 +2467,11 @@ fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns) if (utc.QuadPart >= EPOC_TIME) { utc.QuadPart -= EPOC_TIME; /* milli seconds base */ - *time = (time_t)(utc.QuadPart / 10000000); + *t = (time_t)(utc.QuadPart / 10000000); /* nano seconds base */ *ns = (long)(utc.QuadPart % 10000000) * 100; } else { - *time = 0; + *t = 0; *ns = 0; } } |