summaryrefslogtreecommitdiff
path: root/libarchive/archive_write_disk_windows.c
diff options
context:
space:
mode:
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-01-04 01:36:59 -0500
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-01-04 01:36:59 -0500
commitfea88e48795d33d4e724c77e88dc887c2ff33ca2 (patch)
treee18ce9db3eadf4b7126a9be50396c5cb3e0f7b7b /libarchive/archive_write_disk_windows.c
parent3333fe8049cee4126a563990e2da9ff1f3700847 (diff)
downloadlibarchive-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.c41
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;