diff options
author | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-01-04 01:36:59 -0500 |
---|---|---|
committer | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2012-01-04 01:36:59 -0500 |
commit | fea88e48795d33d4e724c77e88dc887c2ff33ca2 (patch) | |
tree | e18ce9db3eadf4b7126a9be50396c5cb3e0f7b7b /libarchive/archive_write_disk_windows.c | |
parent | 3333fe8049cee4126a563990e2da9ff1f3700847 (diff) | |
download | libarchive-fea88e48795d33d4e724c77e88dc887c2ff33ca2.tar.gz |
Use OVERLAOPED data with WriteFile API instead of SetFilePointer API to set the file offset.
SVN-Revision: 4084
Diffstat (limited to 'libarchive/archive_write_disk_windows.c')
-rw-r--r-- | libarchive/archive_write_disk_windows.c | 41 |
1 files changed, 11 insertions, 30 deletions
diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c index 2dc2d92e..07dffb73 100644 --- a/libarchive/archive_write_disk_windows.c +++ b/libarchive/archive_write_disk_windows.c @@ -917,6 +917,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; @@ -970,24 +971,11 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size) if (a->offset + bytes_to_write > block_end) bytes_to_write = 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(); @@ -1079,20 +1067,13 @@ _archive_write_disk_finish_entry(struct archive *_a) /* We can use lseek()/write() to extend the file if * ftruncate didn't work or isn't available. */ if (bhfi_size(&(a->st)) < a->filesize) { + OVERLAPPED ol; const char nul = '\0'; - LARGE_INTEGER distance; - distance.QuadPart = a->filesize - 1; - if (!SetFilePointerEx_perso(a->fh, distance, NULL, FILE_BEGIN)) { - 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); - } - if (!WriteFile(a->fh, &nul, 1, NULL, NULL)) { + + memset(&ol, 0, sizeof(ol)); + ol.Offset = (DWORD)((a->filesize -1) & 0xFFFFFFFF); + ol.OffsetHigh = (DWORD)((a->filesize -1) >> 32); + if (!WriteFile(a->fh, &nul, 1, NULL, &ol)) { DWORD lasterr = GetLastError(); if (lasterr == ERROR_ACCESS_DENIED) errno = EBADF; |