*/
#define MAX_OVERLAPPED 8
-#define BUFFER_SIZE (1024 * 8)
+#define READ_BUFFER_SIZE (1024 * 64) /* Default to 64KB per https://technet.microsoft.com/en-us/library/cc938632.aspx */
#define DIRECT_IO 0/* Disabled */
#define ASYNC_IO 1/* Enabled */
/* Allocate read buffer. */
if (olp->buff == NULL) {
void *p;
- size_t s = (size_t)align_num_per_sector(t, BUFFER_SIZE);
+ size_t s = (size_t)align_num_per_sector(t, READ_BUFFER_SIZE);
p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE);
if (p == NULL) {
archive_set_error(&a->archive, ENOMEM,
break;
} while (r == ARCHIVE_OK && t->ol_num_doing < MAX_OVERLAPPED);
} else {
- if (start_next_async_read(a, t) == ARCHIVE_FATAL)
+ if ((r = start_next_async_read(a, t)) == ARCHIVE_FATAL)
goto abort_read_data;
}
if (range.Length.QuadPart > 0)
continue;
} else {
- /* The remaining data is hole. */
+ /* The entire file is a hole. Add one data block of size 0 at the end. */
archive_entry_sparse_add_entry(entry,
- range.FileOffset.QuadPart,
- range.Length.QuadPart);
+ entry_size,
+ 0);
}
break;
} else {
assert(handle != INVALID_HANDLE_VALUE);
assert(DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0,
NULL, 0, &dmy, NULL) != 0);
+
+ unsigned int offsetSoFar = 0;
+
while (s->type != END) {
if (s->type == HOLE) {
- LARGE_INTEGER distance;
-
- distance.QuadPart = s->size;
- assert(SetFilePointerEx(handle, distance,
- NULL, FILE_CURRENT) != 0);
+ LARGE_INTEGER fileOffset, beyondOffset, distanceToMove;
+ fileOffset.QuadPart = offsetSoFar;
+ beyondOffset.QuadPart = offsetSoFar + s->size;
+ distanceToMove.QuadPart = s->size;
+
+ FILE_ZERO_DATA_INFORMATION zeroInformation;
+ zeroInformation.FileOffset = fileOffset;
+ zeroInformation.BeyondFinalZero = beyondOffset;
+
+ DWORD bytesReturned;
+ assert(SetFilePointerEx(handle, distanceToMove,
+ NULL, FILE_CURRENT) != 0);
+ assert(SetEndOfFile(handle) != 0);
+ assert(DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, &zeroInformation,
+ sizeof(FILE_ZERO_DATA_INFORMATION), NULL, 0, &bytesReturned, NULL) != 0);
} else {
DWORD w, wr;
size_t size;
size -= wr;
}
}
+ offsetSoFar += s->size;
s++;
}
assertEqualInt(CloseHandle(handle), 1);
* on all platform.
*/
const struct sparse sparse_file0[] = {
+ // 0 // 1024
{ DATA, 1024 }, { HOLE, 2048000 },
+ // 2049024 // 2051072
{ DATA, 2048 }, { HOLE, 2048000 },
+ // 4099072 // 4103168
{ DATA, 4096 }, { HOLE, 20480000 },
+ // 24583168 // 24591360
{ DATA, 8192 }, { HOLE, 204800000 },
+ // 229391360 // 229391361
{ DATA, 1 }, { END, 0 }
};
const struct sparse sparse_file1[] = {