]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libarchive/archive_read_disk_windows.c
Update vendor/libarchive/dist to git 31c0a517c91f44eeee717a04db8b075cadda83d8
[FreeBSD/FreeBSD.git] / libarchive / archive_read_disk_windows.c
1 /*-
2  * Copyright (c) 2003-2009 Tim Kientzle
3  * Copyright (c) 2010-2012 Michihiro NAKAJIMA
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer
11  *    in this position and unchanged.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include "archive_platform.h"
28 __FBSDID("$FreeBSD$");
29
30 #if defined(_WIN32) && !defined(__CYGWIN__)
31
32 #ifdef HAVE_ERRNO_H
33 #include <errno.h>
34 #endif
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38 #include <winioctl.h>
39
40 #include "archive.h"
41 #include "archive_string.h"
42 #include "archive_entry.h"
43 #include "archive_private.h"
44 #include "archive_read_disk_private.h"
45
46 #ifndef O_BINARY
47 #define O_BINARY        0
48 #endif
49 #ifndef IO_REPARSE_TAG_SYMLINK
50 /* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
51 #define IO_REPARSE_TAG_SYMLINK 0xA000000CL
52 #endif
53
54 /*-
55  * This is a new directory-walking system that addresses a number
56  * of problems I've had with fts(3).  In particular, it has no
57  * pathname-length limits (other than the size of 'int'), handles
58  * deep logical traversals, uses considerably less memory, and has
59  * an opaque interface (easier to modify in the future).
60  *
61  * Internally, it keeps a single list of "tree_entry" items that
62  * represent filesystem objects that require further attention.
63  * Non-directories are not kept in memory: they are pulled from
64  * readdir(), returned to the client, then freed as soon as possible.
65  * Any directory entry to be traversed gets pushed onto the stack.
66  *
67  * There is surprisingly little information that needs to be kept for
68  * each item on the stack.  Just the name, depth (represented here as the
69  * string length of the parent directory's pathname), and some markers
70  * indicating how to get back to the parent (via chdir("..") for a
71  * regular dir or via fchdir(2) for a symlink).
72  */
73
74 struct restore_time {
75         const wchar_t           *full_path;
76         FILETIME                 lastWriteTime;
77         FILETIME                 lastAccessTime;
78         mode_t                   filetype;
79 };
80
81 struct tree_entry {
82         int                      depth;
83         struct tree_entry       *next;
84         struct tree_entry       *parent;
85         size_t                   full_path_dir_length;
86         struct archive_wstring   name;
87         struct archive_wstring   full_path;
88         size_t                   dirname_length;
89         int64_t                  dev;
90         int64_t                  ino;
91         int                      flags;
92         int                      filesystem_id;
93         /* How to restore time of a directory. */
94         struct restore_time      restore_time;
95 };
96
97 struct filesystem {
98         int64_t         dev;
99         int             synthetic;
100         int             remote;
101         DWORD           bytesPerSector;
102 };
103
104 /* Definitions for tree_entry.flags bitmap. */
105 #define isDir           1  /* This entry is a regular directory. */
106 #define isDirLink       2  /* This entry is a symbolic link to a directory. */
107 #define needsFirstVisit 4  /* This is an initial entry. */
108 #define needsDescent    8  /* This entry needs to be previsited. */
109 #define needsOpen       16 /* This is a directory that needs to be opened. */
110 #define needsAscent     32 /* This entry needs to be postvisited. */
111
112 /*
113  * On Windows, "first visit" is handled as a pattern to be handed to
114  * _findfirst().  This is consistent with Windows conventions that
115  * file patterns are handled within the application.  On Posix,
116  * "first visit" is just returned to the client.
117  */
118
119 #define MAX_OVERLAPPED  8
120 #define READ_BUFFER_SIZE        (1024 * 64) /* Default to 64KB per https://technet.microsoft.com/en-us/library/cc938632.aspx */
121 #define DIRECT_IO       0/* Disabled */
122 #define ASYNC_IO        1/* Enabled */
123
124 /*
125  * Local data for this package.
126  */
127 struct tree {
128         struct tree_entry       *stack;
129         struct tree_entry       *current;
130         HANDLE d;
131         WIN32_FIND_DATAW        _findData;
132         WIN32_FIND_DATAW        *findData;
133         int                      flags;
134         int                      visit_type;
135         /* Error code from last failed operation. */
136         int                      tree_errno;
137
138         /* A full path with "\\?\" prefix. */
139         struct archive_wstring   full_path;
140         size_t                   full_path_dir_length;
141         /* Dynamically-sized buffer for holding path */
142         struct archive_wstring   path;
143
144         /* Last path element */
145         const wchar_t           *basename;
146         /* Leading dir length */
147         size_t                   dirname_length;
148
149         int      depth;
150
151         BY_HANDLE_FILE_INFORMATION      lst;
152         BY_HANDLE_FILE_INFORMATION      st;
153         int                      descend;
154         /* How to restore time of a file. */
155         struct restore_time     restore_time;
156
157         struct entry_sparse {
158                 int64_t          length;
159                 int64_t          offset;
160         }                       *sparse_list, *current_sparse;
161         int                      sparse_count;
162         int                      sparse_list_size;
163
164         char                     initial_symlink_mode;
165         char                     symlink_mode;
166         struct filesystem       *current_filesystem;
167         struct filesystem       *filesystem_table;
168         int                      initial_filesystem_id;
169         int                      current_filesystem_id;
170         int                      max_filesystem_id;
171         int                      allocated_filesystem;
172
173         HANDLE                   entry_fh;
174         int                      entry_eof;
175         int64_t                  entry_remaining_bytes;
176         int64_t                  entry_total;
177
178         int                      ol_idx_doing;
179         int                      ol_idx_done;
180         int                      ol_num_doing;
181         int                      ol_num_done;
182         int64_t                  ol_remaining_bytes;
183         int64_t                  ol_total;
184         struct la_overlapped {
185                 OVERLAPPED       ol;
186                 struct archive * _a;
187                 unsigned char   *buff;
188                 size_t           buff_size;
189                 int64_t          offset;
190                 size_t           bytes_expected;
191                 size_t           bytes_transferred;
192         }                        ol[MAX_OVERLAPPED];
193         int                      direct_io;
194         int                      async_io;
195 };
196
197 #define bhfi_dev(bhfi)  ((bhfi)->dwVolumeSerialNumber)
198 /* Treat FileIndex as i-node. We should remove a sequence number
199  * which is high-16-bits of nFileIndexHigh. */
200 #define bhfi_ino(bhfi)  \
201         ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
202     + (bhfi)->nFileIndexLow)
203
204 /* Definitions for tree.flags bitmap. */
205 #define hasStat         16 /* The st entry is valid. */
206 #define hasLstat        32 /* The lst entry is valid. */
207 #define needsRestoreTimes 128
208
209 static int
210 tree_dir_next_windows(struct tree *t, const wchar_t *pattern);
211
212 /* Initiate/terminate a tree traversal. */
213 static struct tree *tree_open(const wchar_t *, int, int);
214 static struct tree *tree_reopen(struct tree *, const wchar_t *, int);
215 static void tree_close(struct tree *);
216 static void tree_free(struct tree *);
217 static void tree_push(struct tree *, const wchar_t *, const wchar_t *,
218                 int, int64_t, int64_t, struct restore_time *);
219
220 /*
221  * tree_next() returns Zero if there is no next entry, non-zero if
222  * there is.  Note that directories are visited three times.
223  * Directories are always visited first as part of enumerating their
224  * parent; that is a "regular" visit.  If tree_descend() is invoked at
225  * that time, the directory is added to a work list and will
226  * subsequently be visited two more times: once just after descending
227  * into the directory ("postdescent") and again just after ascending
228  * back to the parent ("postascent").
229  *
230  * TREE_ERROR_DIR is returned if the descent failed (because the
231  * directory couldn't be opened, for instance).  This is returned
232  * instead of TREE_POSTDESCENT/TREE_POSTASCENT.  TREE_ERROR_DIR is not a
233  * fatal error, but it does imply that the relevant subtree won't be
234  * visited.  TREE_ERROR_FATAL is returned for an error that left the
235  * traversal completely hosed.  Right now, this is only returned for
236  * chdir() failures during ascent.
237  */
238 #define TREE_REGULAR            1
239 #define TREE_POSTDESCENT        2
240 #define TREE_POSTASCENT         3
241 #define TREE_ERROR_DIR          -1
242 #define TREE_ERROR_FATAL        -2
243
244 static int tree_next(struct tree *);
245
246 /*
247  * Return information about the current entry.
248  */
249
250 /*
251  * The current full pathname, length of the full pathname, and a name
252  * that can be used to access the file.  Because tree does use chdir
253  * extensively, the access path is almost never the same as the full
254  * current path.
255  *
256  */
257 static const wchar_t *tree_current_path(struct tree *);
258 static const wchar_t *tree_current_access_path(struct tree *);
259
260 /*
261  * Request the lstat() or stat() data for the current path.  Since the
262  * tree package needs to do some of this anyway, and caches the
263  * results, you should take advantage of it here if you need it rather
264  * than make a redundant stat() or lstat() call of your own.
265  */
266 static const BY_HANDLE_FILE_INFORMATION *tree_current_stat(struct tree *);
267 static const BY_HANDLE_FILE_INFORMATION *tree_current_lstat(struct tree *);
268
269 /* The following functions use tricks to avoid a certain number of
270  * stat()/lstat() calls. */
271 /* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
272 static int tree_current_is_physical_dir(struct tree *);
273 /* "is_physical_link" is equivalent to S_ISLNK(tree_current_lstat()->st_mode) */
274 static int tree_current_is_physical_link(struct tree *);
275 /* Instead of archive_entry_copy_stat for BY_HANDLE_FILE_INFORMATION */
276 static void tree_archive_entry_copy_bhfi(struct archive_entry *,
277                     struct tree *, const BY_HANDLE_FILE_INFORMATION *);
278 /* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
279 static int tree_current_is_dir(struct tree *);
280 static int update_current_filesystem(struct archive_read_disk *a,
281                     int64_t dev);
282 static int setup_current_filesystem(struct archive_read_disk *);
283 static int tree_target_is_same_as_parent(struct tree *,
284                     const BY_HANDLE_FILE_INFORMATION *);
285
286 static int      _archive_read_disk_open_w(struct archive *, const wchar_t *);
287 static int      _archive_read_free(struct archive *);
288 static int      _archive_read_close(struct archive *);
289 static int      _archive_read_data_block(struct archive *,
290                     const void **, size_t *, int64_t *);
291 static int      _archive_read_next_header(struct archive *,
292                     struct archive_entry **);
293 static int      _archive_read_next_header2(struct archive *,
294                     struct archive_entry *);
295 static const char *trivial_lookup_gname(void *, int64_t gid);
296 static const char *trivial_lookup_uname(void *, int64_t uid);
297 static int      setup_sparse(struct archive_read_disk *, struct archive_entry *);
298 static int      close_and_restore_time(HANDLE, struct tree *,
299                     struct restore_time *);
300 static int      setup_sparse_from_disk(struct archive_read_disk *,
301                     struct archive_entry *, HANDLE);
302
303
304
305 static struct archive_vtable *
306 archive_read_disk_vtable(void)
307 {
308         static struct archive_vtable av;
309         static int inited = 0;
310
311         if (!inited) {
312                 av.archive_free = _archive_read_free;
313                 av.archive_close = _archive_read_close;
314                 av.archive_read_data_block = _archive_read_data_block;
315                 av.archive_read_next_header = _archive_read_next_header;
316                 av.archive_read_next_header2 = _archive_read_next_header2;
317                 inited = 1;
318         }
319         return (&av);
320 }
321
322 const char *
323 archive_read_disk_gname(struct archive *_a, la_int64_t gid)
324 {
325         struct archive_read_disk *a = (struct archive_read_disk *)_a;
326         if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
327                 ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
328                 return (NULL);
329         if (a->lookup_gname == NULL)
330                 return (NULL);
331         return ((*a->lookup_gname)(a->lookup_gname_data, gid));
332 }
333
334 const char *
335 archive_read_disk_uname(struct archive *_a, la_int64_t uid)
336 {
337         struct archive_read_disk *a = (struct archive_read_disk *)_a;
338         if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
339                 ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
340                 return (NULL);
341         if (a->lookup_uname == NULL)
342                 return (NULL);
343         return ((*a->lookup_uname)(a->lookup_uname_data, uid));
344 }
345
346 int
347 archive_read_disk_set_gname_lookup(struct archive *_a,
348     void *private_data,
349     const char * (*lookup_gname)(void *private, la_int64_t gid),
350     void (*cleanup_gname)(void *private))
351 {
352         struct archive_read_disk *a = (struct archive_read_disk *)_a;
353         archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
354             ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
355
356         if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
357                 (a->cleanup_gname)(a->lookup_gname_data);
358
359         a->lookup_gname = lookup_gname;
360         a->cleanup_gname = cleanup_gname;
361         a->lookup_gname_data = private_data;
362         return (ARCHIVE_OK);
363 }
364
365 int
366 archive_read_disk_set_uname_lookup(struct archive *_a,
367     void *private_data,
368     const char * (*lookup_uname)(void *private, int64_t uid),
369     void (*cleanup_uname)(void *private))
370 {
371         struct archive_read_disk *a = (struct archive_read_disk *)_a;
372         archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
373             ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
374
375         if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
376                 (a->cleanup_uname)(a->lookup_uname_data);
377
378         a->lookup_uname = lookup_uname;
379         a->cleanup_uname = cleanup_uname;
380         a->lookup_uname_data = private_data;
381         return (ARCHIVE_OK);
382 }
383
384 /*
385  * Create a new archive_read_disk object and initialize it with global state.
386  */
387 struct archive *
388 archive_read_disk_new(void)
389 {
390         struct archive_read_disk *a;
391
392         a = (struct archive_read_disk *)calloc(1, sizeof(*a));
393         if (a == NULL)
394                 return (NULL);
395         a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
396         a->archive.state = ARCHIVE_STATE_NEW;
397         a->archive.vtable = archive_read_disk_vtable();
398         a->entry = archive_entry_new2(&a->archive);
399         a->lookup_uname = trivial_lookup_uname;
400         a->lookup_gname = trivial_lookup_gname;
401         a->flags = ARCHIVE_READDISK_MAC_COPYFILE;
402         return (&a->archive);
403 }
404
405 static int
406 _archive_read_free(struct archive *_a)
407 {
408         struct archive_read_disk *a = (struct archive_read_disk *)_a;
409         int r;
410
411         if (_a == NULL)
412                 return (ARCHIVE_OK);
413         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
414             ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
415
416         if (a->archive.state != ARCHIVE_STATE_CLOSED)
417                 r = _archive_read_close(&a->archive);
418         else
419                 r = ARCHIVE_OK;
420
421         tree_free(a->tree);
422         if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
423                 (a->cleanup_gname)(a->lookup_gname_data);
424         if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
425                 (a->cleanup_uname)(a->lookup_uname_data);
426         archive_string_free(&a->archive.error_string);
427         archive_entry_free(a->entry);
428         a->archive.magic = 0;
429         free(a);
430         return (r);
431 }
432
433 static int
434 _archive_read_close(struct archive *_a)
435 {
436         struct archive_read_disk *a = (struct archive_read_disk *)_a;
437
438         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
439             ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
440
441         if (a->archive.state != ARCHIVE_STATE_FATAL)
442                 a->archive.state = ARCHIVE_STATE_CLOSED;
443
444         tree_close(a->tree);
445
446         return (ARCHIVE_OK);
447 }
448
449 static void
450 setup_symlink_mode(struct archive_read_disk *a, char symlink_mode, 
451     int follow_symlinks)
452 {
453         a->symlink_mode = symlink_mode;
454         a->follow_symlinks = follow_symlinks;
455         if (a->tree != NULL) {
456                 a->tree->initial_symlink_mode = a->symlink_mode;
457                 a->tree->symlink_mode = a->symlink_mode;
458         }
459 }
460
461 int
462 archive_read_disk_set_symlink_logical(struct archive *_a)
463 {
464         struct archive_read_disk *a = (struct archive_read_disk *)_a;
465         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
466             ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
467         setup_symlink_mode(a, 'L', 1);
468         return (ARCHIVE_OK);
469 }
470
471 int
472 archive_read_disk_set_symlink_physical(struct archive *_a)
473 {
474         struct archive_read_disk *a = (struct archive_read_disk *)_a;
475         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
476             ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
477         setup_symlink_mode(a, 'P', 0);
478         return (ARCHIVE_OK);
479 }
480
481 int
482 archive_read_disk_set_symlink_hybrid(struct archive *_a)
483 {
484         struct archive_read_disk *a = (struct archive_read_disk *)_a;
485         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
486             ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
487         setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
488         return (ARCHIVE_OK);
489 }
490
491 int
492 archive_read_disk_set_atime_restored(struct archive *_a)
493 {
494         struct archive_read_disk *a = (struct archive_read_disk *)_a;
495         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
496             ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
497         a->flags |= ARCHIVE_READDISK_RESTORE_ATIME;
498         if (a->tree != NULL)
499                 a->tree->flags |= needsRestoreTimes;
500         return (ARCHIVE_OK);
501 }
502
503 int
504 archive_read_disk_set_behavior(struct archive *_a, int flags)
505 {
506         struct archive_read_disk *a = (struct archive_read_disk *)_a;
507         int r = ARCHIVE_OK;
508
509         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
510             ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
511
512         a->flags = flags;
513
514         if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
515                 r = archive_read_disk_set_atime_restored(_a);
516         else {
517                 if (a->tree != NULL)
518                         a->tree->flags &= ~needsRestoreTimes;
519         }
520         return (r);
521 }
522
523 /*
524  * Trivial implementations of gname/uname lookup functions.
525  * These are normally overridden by the client, but these stub
526  * versions ensure that we always have something that works.
527  */
528 static const char *
529 trivial_lookup_gname(void *private_data, int64_t gid)
530 {
531         (void)private_data; /* UNUSED */
532         (void)gid; /* UNUSED */
533         return (NULL);
534 }
535
536 static const char *
537 trivial_lookup_uname(void *private_data, int64_t uid)
538 {
539         (void)private_data; /* UNUSED */
540         (void)uid; /* UNUSED */
541         return (NULL);
542 }
543
544 static int64_t
545 align_num_per_sector(struct tree *t, int64_t size)
546 {
547         int64_t surplus;
548
549         size += t->current_filesystem->bytesPerSector -1;
550         surplus = size % t->current_filesystem->bytesPerSector;
551         size -= surplus;
552         return (size);
553 }
554
555 static int
556 start_next_async_read(struct archive_read_disk *a, struct tree *t)
557 {
558         struct la_overlapped *olp;
559         DWORD buffbytes, rbytes;
560
561         if (t->ol_remaining_bytes == 0)
562                 return (ARCHIVE_EOF);
563
564         olp = &(t->ol[t->ol_idx_doing]);
565         t->ol_idx_doing = (t->ol_idx_doing + 1) % MAX_OVERLAPPED;
566
567         /* Allocate read buffer. */
568         if (olp->buff == NULL) {
569                 void *p;
570                 size_t s = (size_t)align_num_per_sector(t, READ_BUFFER_SIZE);
571                 p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE);
572                 if (p == NULL) {
573                         archive_set_error(&a->archive, ENOMEM,
574                             "Couldn't allocate memory");
575                         a->archive.state = ARCHIVE_STATE_FATAL;
576                         return (ARCHIVE_FATAL);
577                 }
578                 olp->buff = p;
579                 olp->buff_size = s;
580                 olp->_a = &a->archive;
581                 olp->ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
582                 if (olp->ol.hEvent == NULL) {
583                         la_dosmaperr(GetLastError());
584                         archive_set_error(&a->archive, errno,
585                             "CreateEvent failed");
586                         a->archive.state = ARCHIVE_STATE_FATAL;
587                         return (ARCHIVE_FATAL);
588                 }
589         } else
590                 ResetEvent(olp->ol.hEvent);
591
592         buffbytes = (DWORD)olp->buff_size;
593         if (buffbytes > t->current_sparse->length)
594                 buffbytes = (DWORD)t->current_sparse->length;
595
596         /* Skip hole. */
597         if (t->current_sparse->offset > t->ol_total) {
598                 t->ol_remaining_bytes -=
599                         t->current_sparse->offset - t->ol_total;
600         }
601
602         olp->offset = t->current_sparse->offset;
603         olp->ol.Offset = (DWORD)(olp->offset & 0xffffffff);
604         olp->ol.OffsetHigh = (DWORD)(olp->offset >> 32);
605
606         if (t->ol_remaining_bytes > buffbytes) {
607                 olp->bytes_expected = buffbytes;
608                 t->ol_remaining_bytes -= buffbytes;
609         } else {
610                 olp->bytes_expected = (size_t)t->ol_remaining_bytes;
611                 t->ol_remaining_bytes = 0;
612         }
613         olp->bytes_transferred = 0;
614         t->current_sparse->offset += buffbytes;
615         t->current_sparse->length -= buffbytes;
616         t->ol_total = t->current_sparse->offset;
617         if (t->current_sparse->length == 0 && t->ol_remaining_bytes > 0)
618                 t->current_sparse++;
619
620         if (!ReadFile(t->entry_fh, olp->buff, buffbytes, &rbytes, &(olp->ol))) {
621                 DWORD lasterr;
622
623                 lasterr = GetLastError();
624                 if (lasterr == ERROR_HANDLE_EOF) {
625                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
626                             "Reading file truncated");
627                         a->archive.state = ARCHIVE_STATE_FATAL;
628                         return (ARCHIVE_FATAL);
629                 } else if (lasterr != ERROR_IO_PENDING) {
630                         if (lasterr == ERROR_NO_DATA)
631                                 errno = EAGAIN;
632                         else if (lasterr == ERROR_ACCESS_DENIED)
633                                 errno = EBADF;
634                         else
635                                 la_dosmaperr(lasterr);
636                         archive_set_error(&a->archive, errno, "Read error");
637                         a->archive.state = ARCHIVE_STATE_FATAL;
638                         return (ARCHIVE_FATAL);
639                 }
640         } else
641                 olp->bytes_transferred = rbytes;
642         t->ol_num_doing++;
643
644         return (t->ol_remaining_bytes == 0)? ARCHIVE_EOF: ARCHIVE_OK;
645 }
646
647 static void
648 cancel_async(struct tree *t)
649 {
650         if (t->ol_num_doing != t->ol_num_done) {
651                 CancelIo(t->entry_fh);
652                 t->ol_num_doing = t->ol_num_done = 0;
653         }
654 }
655
656 static int
657 _archive_read_data_block(struct archive *_a, const void **buff,
658     size_t *size, int64_t *offset)
659 {
660         struct archive_read_disk *a = (struct archive_read_disk *)_a;
661         struct tree *t = a->tree;
662         struct la_overlapped *olp;
663         DWORD bytes_transferred;
664         int r = ARCHIVE_FATAL;
665
666         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
667             "archive_read_data_block");
668
669         if (t->entry_eof || t->entry_remaining_bytes <= 0) {
670                 r = ARCHIVE_EOF;
671                 goto abort_read_data;
672         }
673
674         /*
675          * Make a request to read the file in asynchronous.
676          */
677         if (t->ol_num_doing == 0) {
678                 do {
679                         r = start_next_async_read(a, t);
680                         if (r == ARCHIVE_FATAL)
681                                 goto abort_read_data;
682                         if (!t->async_io)
683                                 break;
684                 } while (r == ARCHIVE_OK && t->ol_num_doing < MAX_OVERLAPPED);
685         } else {
686                 if ((r = start_next_async_read(a, t)) == ARCHIVE_FATAL)
687                         goto abort_read_data;
688         }
689
690         olp = &(t->ol[t->ol_idx_done]);
691         t->ol_idx_done = (t->ol_idx_done + 1) % MAX_OVERLAPPED;
692         if (olp->bytes_transferred)
693                 bytes_transferred = (DWORD)olp->bytes_transferred;
694         else if (!GetOverlappedResult(t->entry_fh, &(olp->ol),
695             &bytes_transferred, TRUE)) {
696                 la_dosmaperr(GetLastError());
697                 archive_set_error(&a->archive, errno,
698                     "GetOverlappedResult failed");
699                 a->archive.state = ARCHIVE_STATE_FATAL;
700                 r = ARCHIVE_FATAL;
701                 goto abort_read_data;
702         }
703         t->ol_num_done++;
704
705         if (bytes_transferred == 0 ||
706             olp->bytes_expected != bytes_transferred) {
707                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
708                     "Reading file truncated");
709                 a->archive.state = ARCHIVE_STATE_FATAL;
710                 r = ARCHIVE_FATAL;
711                 goto abort_read_data;
712         }
713
714         *buff = olp->buff;
715         *size = bytes_transferred;
716         *offset = olp->offset;
717         if (olp->offset > t->entry_total)
718                 t->entry_remaining_bytes -= olp->offset - t->entry_total;
719         t->entry_total = olp->offset + *size;
720         t->entry_remaining_bytes -= *size;
721         if (t->entry_remaining_bytes == 0) {
722                 /* Close the current file descriptor */
723                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
724                 t->entry_fh = INVALID_HANDLE_VALUE;
725                 t->entry_eof = 1;
726         }
727         return (ARCHIVE_OK);
728
729 abort_read_data:
730         *buff = NULL;
731         *size = 0;
732         *offset = t->entry_total;
733         if (t->entry_fh != INVALID_HANDLE_VALUE) {
734                 cancel_async(t);
735                 /* Close the current file descriptor */
736                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
737                 t->entry_fh = INVALID_HANDLE_VALUE;
738         }
739         return (r);
740 }
741
742 static int
743 next_entry(struct archive_read_disk *a, struct tree *t,
744     struct archive_entry *entry)
745 {
746         const BY_HANDLE_FILE_INFORMATION *st;
747         const BY_HANDLE_FILE_INFORMATION *lst;
748         const char*name;
749         int descend, r;
750
751         st = NULL;
752         lst = NULL;
753         t->descend = 0;
754         do {
755                 switch (tree_next(t)) {
756                 case TREE_ERROR_FATAL:
757                         archive_set_error(&a->archive, t->tree_errno,
758                             "%ls: Unable to continue traversing directory tree",
759                             tree_current_path(t));
760                         a->archive.state = ARCHIVE_STATE_FATAL;
761                         return (ARCHIVE_FATAL);
762                 case TREE_ERROR_DIR:
763                         archive_set_error(&a->archive, t->tree_errno,
764                             "%ls: Couldn't visit directory",
765                             tree_current_path(t));
766                         return (ARCHIVE_FAILED);
767                 case 0:
768                         return (ARCHIVE_EOF);
769                 case TREE_POSTDESCENT:
770                 case TREE_POSTASCENT:
771                         break;
772                 case TREE_REGULAR:
773                         lst = tree_current_lstat(t);
774                         if (lst == NULL) {
775                                 archive_set_error(&a->archive, t->tree_errno,
776                                     "%ls: Cannot stat",
777                                     tree_current_path(t));
778                                 return (ARCHIVE_FAILED);
779                         }
780                         break;
781                 }       
782         } while (lst == NULL);
783
784         archive_entry_copy_pathname_w(entry, tree_current_path(t));
785
786         /*
787          * Perform path matching.
788          */
789         if (a->matching) {
790                 r = archive_match_path_excluded(a->matching, entry);
791                 if (r < 0) {
792                         archive_set_error(&(a->archive), errno,
793                             "Failed : %s", archive_error_string(a->matching));
794                         return (r);
795                 }
796                 if (r) {
797                         if (a->excluded_cb_func)
798                                 a->excluded_cb_func(&(a->archive),
799                                     a->excluded_cb_data, entry);
800                         return (ARCHIVE_RETRY);
801                 }
802         }
803
804         /*
805          * Distinguish 'L'/'P'/'H' symlink following.
806          */
807         switch(t->symlink_mode) {
808         case 'H':
809                 /* 'H': After the first item, rest like 'P'. */
810                 t->symlink_mode = 'P';
811                 /* 'H': First item (from command line) like 'L'. */
812                 /* FALLTHROUGH */
813         case 'L':
814                 /* 'L': Do descend through a symlink to dir. */
815                 descend = tree_current_is_dir(t);
816                 /* 'L': Follow symlinks to files. */
817                 a->symlink_mode = 'L';
818                 a->follow_symlinks = 1;
819                 /* 'L': Archive symlinks as targets, if we can. */
820                 st = tree_current_stat(t);
821                 if (st != NULL && !tree_target_is_same_as_parent(t, st))
822                         break;
823                 /* If stat fails, we have a broken symlink;
824                  * in that case, don't follow the link. */
825                 /* FALLTHROUGH */
826         default:
827                 /* 'P': Don't descend through a symlink to dir. */
828                 descend = tree_current_is_physical_dir(t);
829                 /* 'P': Don't follow symlinks to files. */
830                 a->symlink_mode = 'P';
831                 a->follow_symlinks = 0;
832                 /* 'P': Archive symlinks as symlinks. */
833                 st = lst;
834                 break;
835         }
836
837         if (update_current_filesystem(a, bhfi_dev(st)) != ARCHIVE_OK) {
838                 a->archive.state = ARCHIVE_STATE_FATAL;
839                 return (ARCHIVE_FATAL);
840         }
841         if (t->initial_filesystem_id == -1)
842                 t->initial_filesystem_id = t->current_filesystem_id;
843         if (a->flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) {
844                 if (t->initial_filesystem_id != t->current_filesystem_id)
845                         return (ARCHIVE_RETRY);
846         }
847         t->descend = descend;
848
849         tree_archive_entry_copy_bhfi(entry, t, st);
850
851         /* Save the times to be restored. This must be in before
852          * calling archive_read_disk_descend() or any chance of it,
853          * especially, invoking a callback. */
854         t->restore_time.lastWriteTime = st->ftLastWriteTime;
855         t->restore_time.lastAccessTime = st->ftLastAccessTime;
856         t->restore_time.filetype = archive_entry_filetype(entry);
857
858         /*
859          * Perform time matching.
860          */
861         if (a->matching) {
862                 r = archive_match_time_excluded(a->matching, entry);
863                 if (r < 0) {
864                         archive_set_error(&(a->archive), errno,
865                             "Failed : %s", archive_error_string(a->matching));
866                         return (r);
867                 }
868                 if (r) {
869                         if (a->excluded_cb_func)
870                                 a->excluded_cb_func(&(a->archive),
871                                     a->excluded_cb_data, entry);
872                         return (ARCHIVE_RETRY);
873                 }
874         }
875
876         /* Lookup uname/gname */
877         name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
878         if (name != NULL)
879                 archive_entry_copy_uname(entry, name);
880         name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
881         if (name != NULL)
882                 archive_entry_copy_gname(entry, name);
883
884         /*
885          * Perform owner matching.
886          */
887         if (a->matching) {
888                 r = archive_match_owner_excluded(a->matching, entry);
889                 if (r < 0) {
890                         archive_set_error(&(a->archive), errno,
891                             "Failed : %s", archive_error_string(a->matching));
892                         return (r);
893                 }
894                 if (r) {
895                         if (a->excluded_cb_func)
896                                 a->excluded_cb_func(&(a->archive),
897                                     a->excluded_cb_data, entry);
898                         return (ARCHIVE_RETRY);
899                 }
900         }
901
902         /*
903          * Invoke a meta data filter callback.
904          */
905         if (a->metadata_filter_func) {
906                 if (!a->metadata_filter_func(&(a->archive),
907                     a->metadata_filter_data, entry))
908                         return (ARCHIVE_RETRY);
909         }
910
911         archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t));
912
913         r = ARCHIVE_OK;
914         if (archive_entry_filetype(entry) == AE_IFREG &&
915             archive_entry_size(entry) > 0) {
916                 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
917                 if (t->async_io)
918                         flags |= FILE_FLAG_OVERLAPPED;
919                 if (t->direct_io)
920                         flags |= FILE_FLAG_NO_BUFFERING;
921                 else
922                         flags |= FILE_FLAG_SEQUENTIAL_SCAN;
923                 t->entry_fh = CreateFileW(tree_current_access_path(t),
924                     GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
925                 if (t->entry_fh == INVALID_HANDLE_VALUE) {
926                         la_dosmaperr(GetLastError());
927                         archive_set_error(&a->archive, errno,
928                             "Couldn't open %ls", tree_current_path(a->tree));
929                         return (ARCHIVE_FAILED);
930                 }
931
932                 /* Find sparse data from the disk. */
933                 if (archive_entry_hardlink(entry) == NULL &&
934                     (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0)
935                         r = setup_sparse_from_disk(a, entry, t->entry_fh);
936         }
937         return (r);
938 }
939
940 static int
941 _archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
942 {
943        int ret;
944        struct archive_read_disk *a = (struct archive_read_disk *)_a;
945        *entryp = NULL;
946        ret = _archive_read_next_header2(_a, a->entry);
947        *entryp = a->entry;
948        return ret;
949 }
950
951 static int
952 _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
953 {
954         struct archive_read_disk *a = (struct archive_read_disk *)_a;
955         struct tree *t;
956         int r;
957
958         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
959             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
960             "archive_read_next_header2");
961
962         t = a->tree;
963         if (t->entry_fh != INVALID_HANDLE_VALUE) {
964                 cancel_async(t);
965                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
966                 t->entry_fh = INVALID_HANDLE_VALUE;
967         }
968
969         while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY)
970                 archive_entry_clear(entry);
971
972         /*
973          * EOF and FATAL are persistent at this layer.  By
974          * modifying the state, we guarantee that future calls to
975          * read a header or read data will fail.
976          */
977         switch (r) {
978         case ARCHIVE_EOF:
979                 a->archive.state = ARCHIVE_STATE_EOF;
980                 break;
981         case ARCHIVE_OK:
982         case ARCHIVE_WARN:
983                 t->entry_total = 0;
984                 if (archive_entry_filetype(entry) == AE_IFREG) {
985                         t->entry_remaining_bytes = archive_entry_size(entry);
986                         t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
987                         if (!t->entry_eof &&
988                             setup_sparse(a, entry) != ARCHIVE_OK)
989                                 return (ARCHIVE_FATAL);
990                 } else {
991                         t->entry_remaining_bytes = 0;
992                         t->entry_eof = 1;
993                 }
994                 t->ol_idx_doing = t->ol_idx_done = 0;
995                 t->ol_num_doing = t->ol_num_done = 0;
996                 t->ol_remaining_bytes = t->entry_remaining_bytes;
997                 t->ol_total = 0;
998                 a->archive.state = ARCHIVE_STATE_DATA;
999                 break;
1000         case ARCHIVE_RETRY:
1001                 break;
1002         case ARCHIVE_FATAL:
1003                 a->archive.state = ARCHIVE_STATE_FATAL;
1004                 break;
1005         }
1006
1007         __archive_reset_read_data(&a->archive);
1008         return (r);
1009 }
1010
1011 static int
1012 setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
1013 {
1014         struct tree *t = a->tree;
1015         int64_t aligned, length, offset;
1016         int i;
1017
1018         t->sparse_count = archive_entry_sparse_reset(entry);
1019         if (t->sparse_count+1 > t->sparse_list_size) {
1020                 free(t->sparse_list);
1021                 t->sparse_list_size = t->sparse_count + 1;
1022                 t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
1023                     t->sparse_list_size);
1024                 if (t->sparse_list == NULL) {
1025                         t->sparse_list_size = 0;
1026                         archive_set_error(&a->archive, ENOMEM,
1027                             "Can't allocate data");
1028                         a->archive.state = ARCHIVE_STATE_FATAL;
1029                         return (ARCHIVE_FATAL);
1030                 }
1031         }
1032         /*
1033          * Get sparse list and make sure those offsets and lengths are
1034          * aligned by a sector size.
1035          */
1036         for (i = 0; i < t->sparse_count; i++) {
1037                 archive_entry_sparse_next(entry, &offset, &length);
1038                 aligned = align_num_per_sector(t, offset);
1039                 if (aligned != offset) {
1040                         aligned -= t->current_filesystem->bytesPerSector;
1041                         length += offset - aligned;
1042                 }
1043                 t->sparse_list[i].offset = aligned;
1044                 aligned = align_num_per_sector(t, length);
1045                 t->sparse_list[i].length = aligned;
1046         }
1047
1048         aligned = align_num_per_sector(t, archive_entry_size(entry));
1049         if (i == 0) {
1050                 t->sparse_list[i].offset = 0;
1051                 t->sparse_list[i].length = aligned;
1052         } else {
1053                 int j, last = i;
1054
1055                 t->sparse_list[i].offset = aligned;
1056                 t->sparse_list[i].length = 0;
1057                 for (i = 0; i < last; i++) {
1058                         if ((t->sparse_list[i].offset +
1059                                t->sparse_list[i].length) <= 
1060                                         t->sparse_list[i+1].offset)
1061                                 continue;
1062                         /*
1063                          * Now sparse_list[i+1] is overlapped by sparse_list[i].
1064                          * Merge those two.
1065                          */
1066                         length = t->sparse_list[i+1].offset -
1067                                         t->sparse_list[i].offset;
1068                         t->sparse_list[i+1].offset = t->sparse_list[i].offset;
1069                         t->sparse_list[i+1].length += length;
1070                         /* Remove sparse_list[i]. */
1071                         for (j = i; j < last; j++) {
1072                                 t->sparse_list[j].offset =
1073                                     t->sparse_list[j+1].offset;
1074                                 t->sparse_list[j].length =
1075                                     t->sparse_list[j+1].length;
1076                         }
1077                         last--;
1078                 }
1079         }
1080         t->current_sparse = t->sparse_list;
1081
1082         return (ARCHIVE_OK);
1083 }
1084
1085 int
1086 archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
1087     void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
1088     void *_client_data)
1089 {
1090         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1091         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1092             ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
1093         a->matching = _ma;
1094         a->excluded_cb_func = _excluded_func;
1095         a->excluded_cb_data = _client_data;
1096         return (ARCHIVE_OK);
1097 }
1098
1099 int
1100 archive_read_disk_set_metadata_filter_callback(struct archive *_a,
1101     int (*_metadata_filter_func)(struct archive *, void *,
1102     struct archive_entry *), void *_client_data)
1103 {
1104         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1105
1106         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
1107             "archive_read_disk_set_metadata_filter_callback");
1108
1109         a->metadata_filter_func = _metadata_filter_func;
1110         a->metadata_filter_data = _client_data;
1111         return (ARCHIVE_OK);
1112 }
1113
1114 int
1115 archive_read_disk_can_descend(struct archive *_a)
1116 {
1117         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1118         struct tree *t = a->tree;
1119
1120         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1121             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1122             "archive_read_disk_can_descend");
1123
1124         return (t->visit_type == TREE_REGULAR && t->descend);
1125 }
1126
1127 /*
1128  * Called by the client to mark the directory just returned from
1129  * tree_next() as needing to be visited.
1130  */
1131 int
1132 archive_read_disk_descend(struct archive *_a)
1133 {
1134         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1135         struct tree *t = a->tree;
1136
1137         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1138             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1139             "archive_read_disk_descend");
1140
1141         if (t->visit_type != TREE_REGULAR || !t->descend)
1142                 return (ARCHIVE_OK);
1143
1144         if (tree_current_is_physical_dir(t)) {
1145                 tree_push(t, t->basename, t->full_path.s,
1146                     t->current_filesystem_id,
1147                     bhfi_dev(&(t->lst)), bhfi_ino(&(t->lst)),
1148                     &t->restore_time);
1149                 t->stack->flags |= isDir;
1150         } else if (tree_current_is_dir(t)) {
1151                 tree_push(t, t->basename, t->full_path.s,
1152                     t->current_filesystem_id,
1153                     bhfi_dev(&(t->st)), bhfi_ino(&(t->st)),
1154                     &t->restore_time);
1155                 t->stack->flags |= isDirLink;
1156         }
1157         t->descend = 0;
1158         return (ARCHIVE_OK);
1159 }
1160
1161 int
1162 archive_read_disk_open(struct archive *_a, const char *pathname)
1163 {
1164         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1165         struct archive_wstring wpath;
1166         int ret;
1167
1168         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1169             ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
1170             "archive_read_disk_open");
1171         archive_clear_error(&a->archive);
1172
1173         /* Make a wchar_t string from a char string. */
1174         archive_string_init(&wpath);
1175         if (archive_wstring_append_from_mbs(&wpath, pathname,
1176             strlen(pathname)) != 0) {
1177                 if (errno == ENOMEM)
1178                         archive_set_error(&a->archive, ENOMEM,
1179                             "Can't allocate memory");
1180                 else
1181                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1182                             "Can't convert a path to a wchar_t string");
1183                 a->archive.state = ARCHIVE_STATE_FATAL;
1184                 ret = ARCHIVE_FATAL;
1185         } else
1186                 ret = _archive_read_disk_open_w(_a, wpath.s);
1187
1188         archive_wstring_free(&wpath);
1189         return (ret);
1190 }
1191
1192 int
1193 archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
1194 {
1195         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1196
1197         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1198             ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
1199             "archive_read_disk_open_w");
1200         archive_clear_error(&a->archive);
1201
1202         return (_archive_read_disk_open_w(_a, pathname));
1203 }
1204
1205 static int
1206 _archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
1207 {
1208         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1209
1210         if (a->tree != NULL)
1211                 a->tree = tree_reopen(a->tree, pathname,
1212                     a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
1213         else
1214                 a->tree = tree_open(pathname, a->symlink_mode,
1215                     a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
1216         if (a->tree == NULL) {
1217                 archive_set_error(&a->archive, ENOMEM,
1218                     "Can't allocate directory traversal data");
1219                 a->archive.state = ARCHIVE_STATE_FATAL;
1220                 return (ARCHIVE_FATAL);
1221         }
1222         a->archive.state = ARCHIVE_STATE_HEADER;
1223
1224         return (ARCHIVE_OK);
1225 }
1226
1227 /*
1228  * Return a current filesystem ID which is index of the filesystem entry
1229  * you've visited through archive_read_disk.
1230  */
1231 int
1232 archive_read_disk_current_filesystem(struct archive *_a)
1233 {
1234         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1235
1236         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1237             "archive_read_disk_current_filesystem");
1238
1239         return (a->tree->current_filesystem_id);
1240 }
1241
1242 static int
1243 update_current_filesystem(struct archive_read_disk *a, int64_t dev)
1244 {
1245         struct tree *t = a->tree;
1246         int i, fid;
1247
1248         if (t->current_filesystem != NULL &&
1249             t->current_filesystem->dev == dev)
1250                 return (ARCHIVE_OK);
1251
1252         for (i = 0; i < t->max_filesystem_id; i++) {
1253                 if (t->filesystem_table[i].dev == dev) {
1254                         /* There is the filesystem ID we've already generated. */
1255                         t->current_filesystem_id = i;
1256                         t->current_filesystem = &(t->filesystem_table[i]);
1257                         return (ARCHIVE_OK);
1258                 }
1259         }
1260
1261         /*
1262          * There is a new filesystem, we generate a new ID for.
1263          */
1264         fid = t->max_filesystem_id++;
1265         if (t->max_filesystem_id > t->allocated_filesystem) {
1266                 size_t s;
1267                 void *p;
1268
1269                 s = t->max_filesystem_id * 2;
1270                 p = realloc(t->filesystem_table,
1271                         s * sizeof(*t->filesystem_table));
1272                 if (p == NULL) {
1273                         archive_set_error(&a->archive, ENOMEM,
1274                             "Can't allocate tar data");
1275                         return (ARCHIVE_FATAL);
1276                 }
1277                 t->filesystem_table = (struct filesystem *)p;
1278                 t->allocated_filesystem = (int)s;
1279         }
1280         t->current_filesystem_id = fid;
1281         t->current_filesystem = &(t->filesystem_table[fid]);
1282         t->current_filesystem->dev = dev;
1283
1284         return (setup_current_filesystem(a));
1285 }
1286
1287 /*
1288  * Returns 1 if current filesystem is generated filesystem, 0 if it is not
1289  * or -1 if it is unknown.
1290  */
1291 int
1292 archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
1293 {
1294         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1295
1296         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1297             "archive_read_disk_current_filesystem");
1298
1299         return (a->tree->current_filesystem->synthetic);
1300 }
1301
1302 /*
1303  * Returns 1 if current filesystem is remote filesystem, 0 if it is not
1304  * or -1 if it is unknown.
1305  */
1306 int
1307 archive_read_disk_current_filesystem_is_remote(struct archive *_a)
1308 {
1309         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1310
1311         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1312             "archive_read_disk_current_filesystem");
1313
1314         return (a->tree->current_filesystem->remote);
1315 }
1316
1317 /*
1318  * If symlink is broken, statfs or statvfs will fail.
1319  * Use its directory path instead.
1320  */
1321 static wchar_t *
1322 safe_path_for_statfs(struct tree *t)
1323 {
1324         const wchar_t *path;
1325         wchar_t *cp, *p = NULL;
1326
1327         path = tree_current_access_path(t);
1328         if (tree_current_stat(t) == NULL) {
1329                 p = _wcsdup(path);
1330                 cp = wcsrchr(p, '/');
1331                 if (cp != NULL && wcslen(cp) >= 2) {
1332                         cp[1] = '.';
1333                         cp[2] = '\0';
1334                         path = p;
1335                 }
1336         } else
1337                 p = _wcsdup(path);
1338         return (p);
1339 }
1340
1341 /*
1342  * Get conditions of synthetic and remote on Windows
1343  */
1344 static int
1345 setup_current_filesystem(struct archive_read_disk *a)
1346 {
1347         struct tree *t = a->tree;
1348         wchar_t vol[256];
1349         wchar_t *path;
1350
1351         t->current_filesystem->synthetic = -1;/* Not supported */
1352         path = safe_path_for_statfs(t);
1353         if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) {
1354                 free(path);
1355                 t->current_filesystem->remote = -1;
1356                 t->current_filesystem->bytesPerSector = 0;
1357                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1358                         "GetVolumePathName failed: %d", (int)GetLastError());
1359                 return (ARCHIVE_FAILED);
1360         }
1361         free(path);
1362         switch (GetDriveTypeW(vol)) {
1363         case DRIVE_UNKNOWN:
1364         case DRIVE_NO_ROOT_DIR:
1365                 t->current_filesystem->remote = -1;
1366                 break;
1367         case DRIVE_REMOTE:
1368                 t->current_filesystem->remote = 1;
1369                 break;
1370         default:
1371                 t->current_filesystem->remote = 0;
1372                 break;
1373         }
1374
1375         if (!GetDiskFreeSpaceW(vol, NULL,
1376             &(t->current_filesystem->bytesPerSector), NULL, NULL)) {
1377                 t->current_filesystem->bytesPerSector = 0;
1378                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1379                         "GetDiskFreeSpace failed: %d", (int)GetLastError());
1380                 return (ARCHIVE_FAILED);
1381         }
1382
1383         return (ARCHIVE_OK);
1384 }
1385
1386 static int
1387 close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
1388 {
1389         HANDLE handle;
1390         int r = 0;
1391
1392         if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
1393                 return (0);
1394
1395         /* Close a file descriptor.
1396          * It will not be used for SetFileTime() because it has been opened
1397          * by a read only mode.
1398          */
1399         if (h != INVALID_HANDLE_VALUE)
1400                 CloseHandle(h);
1401         if ((t->flags & needsRestoreTimes) == 0)
1402                 return (r);
1403
1404         handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
1405                     0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1406         if (handle == INVALID_HANDLE_VALUE) {
1407                 errno = EINVAL;
1408                 return (-1);
1409         }
1410
1411         if (SetFileTime(handle, NULL, &rt->lastAccessTime,
1412             &rt->lastWriteTime) == 0) {
1413                 errno = EINVAL;
1414                 r = -1;
1415         } else
1416                 r = 0;
1417         CloseHandle(handle);
1418         return (r);
1419 }
1420
1421 /*
1422  * Add a directory path to the current stack.
1423  */
1424 static void
1425 tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
1426     int filesystem_id, int64_t dev, int64_t ino, struct restore_time *rt)
1427 {
1428         struct tree_entry *te;
1429
1430         te = calloc(1, sizeof(*te));
1431         te->next = t->stack;
1432         te->parent = t->current;
1433         if (te->parent)
1434                 te->depth = te->parent->depth + 1;
1435         t->stack = te;
1436         archive_string_init(&te->name);
1437         archive_wstrcpy(&te->name, path);
1438         archive_string_init(&te->full_path);
1439         archive_wstrcpy(&te->full_path, full_path);
1440         te->flags = needsDescent | needsOpen | needsAscent;
1441         te->filesystem_id = filesystem_id;
1442         te->dev = dev;
1443         te->ino = ino;
1444         te->dirname_length = t->dirname_length;
1445         te->full_path_dir_length = t->full_path_dir_length;
1446         te->restore_time.full_path = te->full_path.s;
1447         if (rt != NULL) {
1448                 te->restore_time.lastWriteTime = rt->lastWriteTime;
1449                 te->restore_time.lastAccessTime = rt->lastAccessTime;
1450                 te->restore_time.filetype = rt->filetype;
1451         }
1452 }
1453
1454 /*
1455  * Append a name to the current dir path.
1456  */
1457 static void
1458 tree_append(struct tree *t, const wchar_t *name, size_t name_length)
1459 {
1460         size_t size_needed;
1461
1462         t->path.s[t->dirname_length] = L'\0';
1463         t->path.length = t->dirname_length;
1464         /* Strip trailing '/' from name, unless entire name is "/". */
1465         while (name_length > 1 && name[name_length - 1] == L'/')
1466                 name_length--;
1467
1468         /* Resize pathname buffer as needed. */
1469         size_needed = name_length + t->dirname_length + 2;
1470         archive_wstring_ensure(&t->path, size_needed);
1471         /* Add a separating '/' if it's needed. */
1472         if (t->dirname_length > 0 &&
1473             t->path.s[archive_strlen(&t->path)-1] != L'/')
1474                 archive_wstrappend_wchar(&t->path, L'/');
1475         t->basename = t->path.s + archive_strlen(&t->path);
1476         archive_wstrncat(&t->path, name, name_length);
1477         t->restore_time.full_path = t->basename;
1478         if (t->full_path_dir_length > 0) {
1479                 t->full_path.s[t->full_path_dir_length] = L'\0';
1480                 t->full_path.length = t->full_path_dir_length;
1481                 size_needed = name_length + t->full_path_dir_length + 2;
1482                 archive_wstring_ensure(&t->full_path, size_needed);
1483                 /* Add a separating '\' if it's needed. */
1484                 if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
1485                         archive_wstrappend_wchar(&t->full_path, L'\\');
1486                 archive_wstrncat(&t->full_path, name, name_length);
1487                 t->restore_time.full_path = t->full_path.s;
1488         }
1489 }
1490
1491 /*
1492  * Open a directory tree for traversal.
1493  */
1494 static struct tree *
1495 tree_open(const wchar_t *path, int symlink_mode, int restore_time)
1496 {
1497         struct tree *t;
1498
1499         t = calloc(1, sizeof(*t));
1500         archive_string_init(&(t->full_path));
1501         archive_string_init(&t->path);
1502         archive_wstring_ensure(&t->path, 15);
1503         t->initial_symlink_mode = symlink_mode;
1504         return (tree_reopen(t, path, restore_time));
1505 }
1506
1507 static struct tree *
1508 tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
1509 {
1510         struct archive_wstring ws;
1511         wchar_t *pathname, *p, *base;
1512
1513         t->flags = (restore_time != 0)?needsRestoreTimes:0;
1514         t->visit_type = 0;
1515         t->tree_errno = 0;
1516         t->full_path_dir_length = 0;
1517         t->dirname_length = 0;
1518         t->depth = 0;
1519         t->descend = 0;
1520         t->current = NULL;
1521         t->d = INVALID_HANDLE_VALUE;
1522         t->symlink_mode = t->initial_symlink_mode;
1523         archive_string_empty(&(t->full_path));
1524         archive_string_empty(&t->path);
1525         t->entry_fh = INVALID_HANDLE_VALUE;
1526         t->entry_eof = 0;
1527         t->entry_remaining_bytes = 0;
1528         t->initial_filesystem_id = -1;
1529
1530         /* Get wchar_t strings from char strings. */
1531         archive_string_init(&ws);
1532         archive_wstrcpy(&ws, path);
1533         pathname = ws.s;
1534         /* Get a full-path-name. */
1535         p = __la_win_permissive_name_w(pathname);
1536         if (p == NULL)
1537                 goto failed;
1538         archive_wstrcpy(&(t->full_path), p);
1539         free(p);
1540
1541         /* Convert path separators from '\' to '/' */
1542         for (p = pathname; *p != L'\0'; ++p) {
1543                 if (*p == L'\\')
1544                         *p = L'/';
1545         }
1546         base = pathname;
1547
1548         /* First item is set up a lot like a symlink traversal. */
1549         /* printf("Looking for wildcard in %s\n", path); */
1550         if ((base[0] == L'/' && base[1] == L'/' &&
1551              base[2] == L'?' && base[3] == L'/' &&
1552              (wcschr(base+4, L'*') || wcschr(base+4, L'?'))) ||
1553             (!(base[0] == L'/' && base[1] == L'/' &&
1554                base[2] == L'?' && base[3] == L'/') &&
1555                (wcschr(base, L'*') || wcschr(base, L'?')))) {
1556                 // It has a wildcard in it...
1557                 // Separate the last element.
1558                 p = wcsrchr(base, L'/');
1559                 if (p != NULL) {
1560                         *p = L'\0';
1561                         tree_append(t, base, p - base);
1562                         t->dirname_length = archive_strlen(&t->path);
1563                         base = p + 1;
1564                 }
1565                 p = wcsrchr(t->full_path.s, L'\\');
1566                 if (p != NULL) {
1567                         *p = L'\0';
1568                         t->full_path.length = wcslen(t->full_path.s);
1569                         t->full_path_dir_length = archive_strlen(&t->full_path);
1570                 }
1571         }
1572         tree_push(t, base, t->full_path.s, 0, 0, 0, NULL);
1573         archive_wstring_free(&ws);
1574         t->stack->flags = needsFirstVisit;
1575         /*
1576          * Debug flag for Direct IO(No buffering) or Async IO.
1577          * Those dependent on environment variable switches
1578          * will be removed until next release.
1579          */
1580         {
1581                 const char *e;
1582                 if ((e = getenv("LIBARCHIVE_DIRECT_IO")) != NULL) {
1583                         if (e[0] == '0')
1584                                 t->direct_io = 0;
1585                         else
1586                                 t->direct_io = 1;
1587                         fprintf(stderr, "LIBARCHIVE_DIRECT_IO=%s\n",
1588                                 (t->direct_io)?"Enabled":"Disabled");
1589                 } else
1590                         t->direct_io = DIRECT_IO;
1591                 if ((e = getenv("LIBARCHIVE_ASYNC_IO")) != NULL) {
1592                         if (e[0] == '0')
1593                                 t->async_io = 0;
1594                         else
1595                                 t->async_io = 1;
1596                         fprintf(stderr, "LIBARCHIVE_ASYNC_IO=%s\n",
1597                             (t->async_io)?"Enabled":"Disabled");
1598                 } else
1599                         t->async_io = ASYNC_IO;
1600         }
1601         return (t);
1602 failed:
1603         archive_wstring_free(&ws);
1604         tree_free(t);
1605         return (NULL);
1606 }
1607
1608 static int
1609 tree_descent(struct tree *t)
1610 {
1611         t->dirname_length = archive_strlen(&t->path);
1612         t->full_path_dir_length = archive_strlen(&t->full_path);
1613         t->depth++;
1614         return (0);
1615 }
1616
1617 /*
1618  * We've finished a directory; ascend back to the parent.
1619  */
1620 static int
1621 tree_ascend(struct tree *t)
1622 {
1623         struct tree_entry *te;
1624
1625         te = t->stack;
1626         t->depth--;
1627         close_and_restore_time(INVALID_HANDLE_VALUE, t, &te->restore_time);
1628         return (0);
1629 }
1630
1631 /*
1632  * Pop the working stack.
1633  */
1634 static void
1635 tree_pop(struct tree *t)
1636 {
1637         struct tree_entry *te;
1638
1639         t->full_path.s[t->full_path_dir_length] = L'\0';
1640         t->full_path.length = t->full_path_dir_length;
1641         t->path.s[t->dirname_length] = L'\0';
1642         t->path.length = t->dirname_length;
1643         if (t->stack == t->current && t->current != NULL)
1644                 t->current = t->current->parent;
1645         te = t->stack;
1646         t->stack = te->next;
1647         t->dirname_length = te->dirname_length;
1648         t->basename = t->path.s + t->dirname_length;
1649         t->full_path_dir_length = te->full_path_dir_length;
1650         while (t->basename[0] == L'/')
1651                 t->basename++;
1652         archive_wstring_free(&te->name);
1653         archive_wstring_free(&te->full_path);
1654         free(te);
1655 }
1656
1657 /*
1658  * Get the next item in the tree traversal.
1659  */
1660 static int
1661 tree_next(struct tree *t)
1662 {
1663         int r;
1664
1665         while (t->stack != NULL) {
1666                 /* If there's an open dir, get the next entry from there. */
1667                 if (t->d != INVALID_HANDLE_VALUE) {
1668                         r = tree_dir_next_windows(t, NULL);
1669                         if (r == 0)
1670                                 continue;
1671                         return (r);
1672                 }
1673
1674                 if (t->stack->flags & needsFirstVisit) {
1675                         wchar_t *d = t->stack->name.s;
1676                         t->stack->flags &= ~needsFirstVisit;
1677                         if (!(d[0] == L'/' && d[1] == L'/' &&
1678                               d[2] == L'?' && d[3] == L'/') &&
1679                             (wcschr(d, L'*') || wcschr(d, L'?'))) {
1680                                 r = tree_dir_next_windows(t, d);
1681                                 if (r == 0)
1682                                         continue;
1683                                 return (r);
1684                         } else {
1685                                 HANDLE h = FindFirstFileW(d, &t->_findData);
1686                                 if (h == INVALID_HANDLE_VALUE) {
1687                                         la_dosmaperr(GetLastError());
1688                                         t->tree_errno = errno;
1689                                         t->visit_type = TREE_ERROR_DIR;
1690                                         return (t->visit_type);
1691                                 }
1692                                 t->findData = &t->_findData;
1693                                 FindClose(h);
1694                         }
1695                         /* Top stack item needs a regular visit. */
1696                         t->current = t->stack;
1697                         tree_append(t, t->stack->name.s,
1698                             archive_strlen(&(t->stack->name)));
1699                         //t->dirname_length = t->path_length;
1700                         //tree_pop(t);
1701                         t->stack->flags &= ~needsFirstVisit;
1702                         return (t->visit_type = TREE_REGULAR);
1703                 } else if (t->stack->flags & needsDescent) {
1704                         /* Top stack item is dir to descend into. */
1705                         t->current = t->stack;
1706                         tree_append(t, t->stack->name.s,
1707                             archive_strlen(&(t->stack->name)));
1708                         t->stack->flags &= ~needsDescent;
1709                         r = tree_descent(t);
1710                         if (r != 0) {
1711                                 tree_pop(t);
1712                                 t->visit_type = r;
1713                         } else
1714                                 t->visit_type = TREE_POSTDESCENT;
1715                         return (t->visit_type);
1716                 } else if (t->stack->flags & needsOpen) {
1717                         t->stack->flags &= ~needsOpen;
1718                         r = tree_dir_next_windows(t, L"*");
1719                         if (r == 0)
1720                                 continue;
1721                         return (r);
1722                 } else if (t->stack->flags & needsAscent) {
1723                         /* Top stack item is dir and we're done with it. */
1724                         r = tree_ascend(t);
1725                         tree_pop(t);
1726                         t->visit_type = r != 0 ? r : TREE_POSTASCENT;
1727                         return (t->visit_type);
1728                 } else {
1729                         /* Top item on stack is dead. */
1730                         tree_pop(t);
1731                         t->flags &= ~hasLstat;
1732                         t->flags &= ~hasStat;
1733                 }
1734         }
1735         return (t->visit_type = 0);
1736 }
1737
1738 static int
1739 tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
1740 {
1741         const wchar_t *name;
1742         size_t namelen;
1743         int r;
1744
1745         for (;;) {
1746                 if (pattern != NULL) {
1747                         struct archive_wstring pt;
1748
1749                         archive_string_init(&pt);
1750                         archive_wstring_ensure(&pt,
1751                             archive_strlen(&(t->full_path))
1752                               + 2 + wcslen(pattern));
1753                         archive_wstring_copy(&pt, &(t->full_path));
1754                         archive_wstrappend_wchar(&pt, L'\\');
1755                         archive_wstrcat(&pt, pattern);
1756                         t->d = FindFirstFileW(pt.s, &t->_findData);
1757                         archive_wstring_free(&pt);
1758                         if (t->d == INVALID_HANDLE_VALUE) {
1759                                 la_dosmaperr(GetLastError());
1760                                 t->tree_errno = errno;
1761                                 r = tree_ascend(t); /* Undo "chdir" */
1762                                 tree_pop(t);
1763                                 t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
1764                                 return (t->visit_type);
1765                         }
1766                         t->findData = &t->_findData;
1767                         pattern = NULL;
1768                 } else if (!FindNextFileW(t->d, &t->_findData)) {
1769                         FindClose(t->d);
1770                         t->d = INVALID_HANDLE_VALUE;
1771                         t->findData = NULL;
1772                         return (0);
1773                 }
1774                 name = t->findData->cFileName;
1775                 namelen = wcslen(name);
1776                 t->flags &= ~hasLstat;
1777                 t->flags &= ~hasStat;
1778                 if (name[0] == L'.' && name[1] == L'\0')
1779                         continue;
1780                 if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
1781                         continue;
1782                 tree_append(t, name, namelen);
1783                 return (t->visit_type = TREE_REGULAR);
1784         }
1785 }
1786
1787 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1788 static void
1789 fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
1790 {
1791         ULARGE_INTEGER utc;
1792
1793         utc.HighPart = filetime->dwHighDateTime;
1794         utc.LowPart  = filetime->dwLowDateTime;
1795         if (utc.QuadPart >= EPOC_TIME) {
1796                 utc.QuadPart -= EPOC_TIME;
1797                 /* milli seconds base */
1798                 *t = (time_t)(utc.QuadPart / 10000000);
1799                 /* nano seconds base */
1800                 *ns = (long)(utc.QuadPart % 10000000) * 100;
1801         } else {
1802                 *t = 0;
1803                 *ns = 0;
1804         }
1805 }
1806
1807 static void
1808 entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
1809         const WIN32_FIND_DATAW *findData,
1810         const BY_HANDLE_FILE_INFORMATION *bhfi)
1811 {
1812         time_t secs;
1813         long nsecs;
1814         mode_t mode;
1815
1816         fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
1817         archive_entry_set_atime(entry, secs, nsecs);
1818         fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
1819         archive_entry_set_mtime(entry, secs, nsecs);
1820         fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
1821         archive_entry_set_birthtime(entry, secs, nsecs);
1822         archive_entry_set_ctime(entry, secs, nsecs);
1823         archive_entry_set_dev(entry, bhfi_dev(bhfi));
1824         archive_entry_set_ino64(entry, bhfi_ino(bhfi));
1825         if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1826                 archive_entry_set_nlink(entry, bhfi->nNumberOfLinks + 1);
1827         else
1828                 archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
1829         archive_entry_set_size(entry,
1830             (((int64_t)bhfi->nFileSizeHigh) << 32)
1831             + bhfi->nFileSizeLow);
1832         archive_entry_set_uid(entry, 0);
1833         archive_entry_set_gid(entry, 0);
1834         archive_entry_set_rdev(entry, 0);
1835
1836         mode = S_IRUSR | S_IRGRP | S_IROTH;
1837         if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
1838                 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
1839         if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
1840             findData != NULL &&
1841             findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
1842                 mode |= S_IFLNK;
1843         else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1844                 mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
1845         else {
1846                 const wchar_t *p;
1847
1848                 mode |= S_IFREG;
1849                 p = wcsrchr(path, L'.');
1850                 if (p != NULL && wcslen(p) == 4) {
1851                         switch (p[1]) {
1852                         case L'B': case L'b':
1853                                 if ((p[2] == L'A' || p[2] == L'a' ) &&
1854                                     (p[3] == L'T' || p[3] == L't' ))
1855                                         mode |= S_IXUSR | S_IXGRP | S_IXOTH;
1856                                 break;
1857                         case L'C': case L'c':
1858                                 if (((p[2] == L'M' || p[2] == L'm' ) &&
1859                                     (p[3] == L'D' || p[3] == L'd' )))
1860                                         mode |= S_IXUSR | S_IXGRP | S_IXOTH;
1861                                 break;
1862                         case L'E': case L'e':
1863                                 if ((p[2] == L'X' || p[2] == L'x' ) &&
1864                                     (p[3] == L'E' || p[3] == L'e' ))
1865                                         mode |= S_IXUSR | S_IXGRP | S_IXOTH;
1866                                 break;
1867                         default:
1868                                 break;
1869                         }
1870                 }
1871         }
1872         archive_entry_set_mode(entry, mode);
1873 }
1874
1875 static void
1876 tree_archive_entry_copy_bhfi(struct archive_entry *entry, struct tree *t,
1877         const BY_HANDLE_FILE_INFORMATION *bhfi)
1878 {
1879         entry_copy_bhfi(entry, tree_current_path(t), t->findData, bhfi);
1880 }
1881
1882 static int
1883 tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
1884  int sim_lstat)
1885 {
1886         HANDLE h;
1887         int r;
1888         DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
1889         
1890         if (sim_lstat && tree_current_is_physical_link(t))
1891                 flag |= FILE_FLAG_OPEN_REPARSE_POINT;
1892         h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
1893             OPEN_EXISTING, flag, NULL);
1894         if (h == INVALID_HANDLE_VALUE) {
1895                 la_dosmaperr(GetLastError());
1896                 t->tree_errno = errno;
1897                 return (0);
1898         }
1899         r = GetFileInformationByHandle(h, st);
1900         CloseHandle(h);
1901         return (r);
1902 }
1903
1904 /*
1905  * Get the stat() data for the entry just returned from tree_next().
1906  */
1907 static const BY_HANDLE_FILE_INFORMATION *
1908 tree_current_stat(struct tree *t)
1909 {
1910         if (!(t->flags & hasStat)) {
1911                 if (!tree_current_file_information(t, &t->st, 0))
1912                         return NULL;
1913                 t->flags |= hasStat;
1914         }
1915         return (&t->st);
1916 }
1917
1918 /*
1919  * Get the lstat() data for the entry just returned from tree_next().
1920  */
1921 static const BY_HANDLE_FILE_INFORMATION *
1922 tree_current_lstat(struct tree *t)
1923 {
1924         if (!(t->flags & hasLstat)) {
1925                 if (!tree_current_file_information(t, &t->lst, 1))
1926                         return NULL;
1927                 t->flags |= hasLstat;
1928         }
1929         return (&t->lst);
1930 }
1931
1932 /*
1933  * Test whether current entry is a dir or link to a dir.
1934  */
1935 static int
1936 tree_current_is_dir(struct tree *t)
1937 {
1938         if (t->findData)
1939                 return (t->findData->dwFileAttributes
1940                     & FILE_ATTRIBUTE_DIRECTORY);
1941         return (0);
1942 }
1943
1944 /*
1945  * Test whether current entry is a physical directory.  Usually, we
1946  * already have at least one of stat() or lstat() in memory, so we
1947  * use tricks to try to avoid an extra trip to the disk.
1948  */
1949 static int
1950 tree_current_is_physical_dir(struct tree *t)
1951 {
1952         if (tree_current_is_physical_link(t))
1953                 return (0);
1954         return (tree_current_is_dir(t));
1955 }
1956
1957 /*
1958  * Test whether current entry is a symbolic link.
1959  */
1960 static int
1961 tree_current_is_physical_link(struct tree *t)
1962 {
1963         if (t->findData)
1964                 return ((t->findData->dwFileAttributes
1965                                 & FILE_ATTRIBUTE_REPARSE_POINT) &&
1966                         (t->findData->dwReserved0
1967                             == IO_REPARSE_TAG_SYMLINK));
1968         return (0);
1969 }
1970
1971 /*
1972  * Test whether the same file has been in the tree as its parent.
1973  */
1974 static int
1975 tree_target_is_same_as_parent(struct tree *t,
1976     const BY_HANDLE_FILE_INFORMATION *st)
1977 {
1978         struct tree_entry *te;
1979         int64_t dev = bhfi_dev(st);
1980         int64_t ino = bhfi_ino(st);
1981
1982         for (te = t->current->parent; te != NULL; te = te->parent) {
1983                 if (te->dev == dev && te->ino == ino)
1984                         return (1);
1985         }
1986         return (0);
1987 }
1988
1989 /*
1990  * Return the access path for the entry just returned from tree_next().
1991  */
1992 static const wchar_t *
1993 tree_current_access_path(struct tree *t)
1994 {
1995         return (t->full_path.s);
1996 }
1997
1998 /*
1999  * Return the full path for the entry just returned from tree_next().
2000  */
2001 static const wchar_t *
2002 tree_current_path(struct tree *t)
2003 {
2004         return (t->path.s);
2005 }
2006
2007 /*
2008  * Terminate the traversal.
2009  */
2010 static void
2011 tree_close(struct tree *t)
2012 {
2013
2014         if (t == NULL)
2015                 return;
2016         if (t->entry_fh != INVALID_HANDLE_VALUE) {
2017                 cancel_async(t);
2018                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
2019                 t->entry_fh = INVALID_HANDLE_VALUE;
2020         }
2021         /* Close the handle of FindFirstFileW */
2022         if (t->d != INVALID_HANDLE_VALUE) {
2023                 FindClose(t->d);
2024                 t->d = INVALID_HANDLE_VALUE;
2025                 t->findData = NULL;
2026         }
2027         /* Release anything remaining in the stack. */
2028         while (t->stack != NULL)
2029                 tree_pop(t);
2030 }
2031
2032 /*
2033  * Release any resources.
2034  */
2035 static void
2036 tree_free(struct tree *t)
2037 {
2038         int i;
2039
2040         if (t == NULL)
2041                 return;
2042         archive_wstring_free(&t->path);
2043         archive_wstring_free(&t->full_path);
2044         free(t->sparse_list);
2045         free(t->filesystem_table);
2046         for (i = 0; i < MAX_OVERLAPPED; i++) {
2047                 if (t->ol[i].buff)
2048                         VirtualFree(t->ol[i].buff, 0, MEM_RELEASE);
2049                 CloseHandle(t->ol[i].ol.hEvent);
2050         }
2051         free(t);
2052 }
2053
2054
2055 /*
2056  * Populate the archive_entry with metadata from the disk.
2057  */
2058 int
2059 archive_read_disk_entry_from_file(struct archive *_a,
2060     struct archive_entry *entry, int fd, const struct stat *st)
2061 {
2062         struct archive_read_disk *a = (struct archive_read_disk *)_a;
2063         const wchar_t *path;
2064         const wchar_t *wname;
2065         const char *name;
2066         HANDLE h;
2067         BY_HANDLE_FILE_INFORMATION bhfi;
2068         DWORD fileAttributes = 0;
2069         int r;
2070
2071         archive_clear_error(_a);
2072         wname = archive_entry_sourcepath_w(entry);
2073         if (wname == NULL)
2074                 wname = archive_entry_pathname_w(entry);
2075         if (wname == NULL) {
2076                 archive_set_error(&a->archive, EINVAL,
2077                     "Can't get a wide character version of the path");
2078                 return (ARCHIVE_FAILED);
2079         }
2080         path = __la_win_permissive_name_w(wname);
2081
2082         if (st == NULL) {
2083                 /*
2084                  * Get metadata through GetFileInformationByHandle().
2085                  */
2086                 if (fd >= 0) {
2087                         h = (HANDLE)_get_osfhandle(fd);
2088                         r = GetFileInformationByHandle(h, &bhfi);
2089                         if (r == 0) {
2090                                 la_dosmaperr(GetLastError());
2091                                 archive_set_error(&a->archive, errno,
2092                                     "Can't GetFileInformationByHandle");
2093                                 return (ARCHIVE_FAILED);
2094                         }
2095                         entry_copy_bhfi(entry, path, NULL, &bhfi);
2096                 } else {
2097                         WIN32_FIND_DATAW findData;
2098                         DWORD flag, desiredAccess;
2099         
2100                         h = FindFirstFileW(path, &findData);
2101                         if (h == INVALID_HANDLE_VALUE) {
2102                                 la_dosmaperr(GetLastError());
2103                                 archive_set_error(&a->archive, errno,
2104                                     "Can't FindFirstFileW");
2105                                 return (ARCHIVE_FAILED);
2106                         }
2107                         FindClose(h);
2108
2109                         flag = FILE_FLAG_BACKUP_SEMANTICS;
2110                         if (!a->follow_symlinks &&
2111                             (findData.dwFileAttributes
2112                               & FILE_ATTRIBUTE_REPARSE_POINT) &&
2113                                   (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
2114                                 flag |= FILE_FLAG_OPEN_REPARSE_POINT;
2115                                 desiredAccess = 0;
2116                         } else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
2117                                 desiredAccess = 0;
2118                         } else
2119                                 desiredAccess = GENERIC_READ;
2120
2121                         h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
2122                             OPEN_EXISTING, flag, NULL);
2123                         if (h == INVALID_HANDLE_VALUE) {
2124                                 la_dosmaperr(GetLastError());
2125                                 archive_set_error(&a->archive, errno,
2126                                     "Can't CreateFileW");
2127                                 return (ARCHIVE_FAILED);
2128                         }
2129                         r = GetFileInformationByHandle(h, &bhfi);
2130                         if (r == 0) {
2131                                 la_dosmaperr(GetLastError());
2132                                 archive_set_error(&a->archive, errno,
2133                                     "Can't GetFileInformationByHandle");
2134                                 CloseHandle(h);
2135                                 return (ARCHIVE_FAILED);
2136                         }
2137                         entry_copy_bhfi(entry, path, &findData, &bhfi);
2138                 }
2139                 fileAttributes = bhfi.dwFileAttributes;
2140         } else {
2141                 archive_entry_copy_stat(entry, st);
2142                 h = INVALID_HANDLE_VALUE;
2143         }
2144
2145         /* Lookup uname/gname */
2146         name = archive_read_disk_uname(_a, archive_entry_uid(entry));
2147         if (name != NULL)
2148                 archive_entry_copy_uname(entry, name);
2149         name = archive_read_disk_gname(_a, archive_entry_gid(entry));
2150         if (name != NULL)
2151                 archive_entry_copy_gname(entry, name);
2152
2153         /*
2154          * Can this file be sparse file ?
2155          */
2156         if (archive_entry_filetype(entry) != AE_IFREG
2157             || archive_entry_size(entry) <= 0
2158                 || archive_entry_hardlink(entry) != NULL) {
2159                 if (h != INVALID_HANDLE_VALUE && fd < 0)
2160                         CloseHandle(h);
2161                 return (ARCHIVE_OK);
2162         }
2163
2164         if (h == INVALID_HANDLE_VALUE) {
2165                 if (fd >= 0) {
2166                         h = (HANDLE)_get_osfhandle(fd);
2167                 } else {
2168                         h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
2169                             OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2170                         if (h == INVALID_HANDLE_VALUE) {
2171                                 la_dosmaperr(GetLastError());
2172                                 archive_set_error(&a->archive, errno,
2173                                     "Can't CreateFileW");
2174                                 return (ARCHIVE_FAILED);
2175                         }
2176                 }
2177                 r = GetFileInformationByHandle(h, &bhfi);
2178                 if (r == 0) {
2179                         la_dosmaperr(GetLastError());
2180                         archive_set_error(&a->archive, errno,
2181                             "Can't GetFileInformationByHandle");
2182                         if (h != INVALID_HANDLE_VALUE && fd < 0)
2183                                 CloseHandle(h);
2184                         return (ARCHIVE_FAILED);
2185                 }
2186                 fileAttributes = bhfi.dwFileAttributes;
2187         }
2188
2189         /* Sparse file must be set a mark, FILE_ATTRIBUTE_SPARSE_FILE */
2190         if ((fileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
2191                 if (fd < 0)
2192                         CloseHandle(h);
2193                 return (ARCHIVE_OK);
2194         }
2195
2196         r = setup_sparse_from_disk(a, entry, h);
2197         if (fd < 0)
2198                 CloseHandle(h);
2199
2200         return (r);
2201 }
2202
2203 /*
2204  * Windows sparse interface.
2205  */
2206 #if defined(__MINGW32__) && !defined(FSCTL_QUERY_ALLOCATED_RANGES)
2207 #define FSCTL_QUERY_ALLOCATED_RANGES 0x940CF
2208 typedef struct {
2209         LARGE_INTEGER FileOffset;
2210         LARGE_INTEGER Length;
2211 } FILE_ALLOCATED_RANGE_BUFFER;
2212 #endif
2213
2214 static int
2215 setup_sparse_from_disk(struct archive_read_disk *a,
2216     struct archive_entry *entry, HANDLE handle)
2217 {
2218         FILE_ALLOCATED_RANGE_BUFFER range, *outranges = NULL;
2219         size_t outranges_size;
2220         int64_t entry_size = archive_entry_size(entry);
2221         int exit_sts = ARCHIVE_OK;
2222
2223         range.FileOffset.QuadPart = 0;
2224         range.Length.QuadPart = entry_size;
2225         outranges_size = 2048;
2226         outranges = (FILE_ALLOCATED_RANGE_BUFFER *)malloc(outranges_size);
2227         if (outranges == NULL) {
2228                 archive_set_error(&a->archive, ENOMEM,
2229                         "Couldn't allocate memory");
2230                 exit_sts = ARCHIVE_FATAL;
2231                 goto exit_setup_sparse;
2232         }
2233
2234         for (;;) {
2235                 DWORD retbytes;
2236                 BOOL ret;
2237
2238                 for (;;) {
2239                         ret = DeviceIoControl(handle,
2240                             FSCTL_QUERY_ALLOCATED_RANGES,
2241                             &range, sizeof(range), outranges,
2242                             (DWORD)outranges_size, &retbytes, NULL);
2243                         if (ret == 0 && GetLastError() == ERROR_MORE_DATA) {
2244                                 free(outranges);
2245                                 outranges_size *= 2;
2246                                 outranges = (FILE_ALLOCATED_RANGE_BUFFER *)
2247                                     malloc(outranges_size);
2248                                 if (outranges == NULL) {
2249                                         archive_set_error(&a->archive, ENOMEM,
2250                                             "Couldn't allocate memory");
2251                                         exit_sts = ARCHIVE_FATAL;
2252                                         goto exit_setup_sparse;
2253                                 }
2254                                 continue;
2255                         } else
2256                                 break;
2257                 }
2258                 if (ret != 0) {
2259                         if (retbytes > 0) {
2260                                 DWORD i, n;
2261
2262                                 n = retbytes / sizeof(outranges[0]);
2263                                 if (n == 1 &&
2264                                     outranges[0].FileOffset.QuadPart == 0 &&
2265                                     outranges[0].Length.QuadPart == entry_size)
2266                                         break;/* This is not sparse. */
2267                                 for (i = 0; i < n; i++)
2268                                         archive_entry_sparse_add_entry(entry,
2269                                             outranges[i].FileOffset.QuadPart,
2270                                                 outranges[i].Length.QuadPart);
2271                                 range.FileOffset.QuadPart =
2272                                     outranges[n-1].FileOffset.QuadPart
2273                                     + outranges[n-1].Length.QuadPart;
2274                                 range.Length.QuadPart =
2275                                     entry_size - range.FileOffset.QuadPart;
2276                                 if (range.Length.QuadPart > 0)
2277                                         continue;
2278                         } else {
2279                                 /* The entire file is a hole. Add one data block of size 0 at the end. */
2280                                 archive_entry_sparse_add_entry(entry,
2281                                     entry_size,
2282                                     0);
2283                         }
2284                         break;
2285                 } else {
2286                         la_dosmaperr(GetLastError());
2287                         archive_set_error(&a->archive, errno,
2288                             "DeviceIoControl Failed: %lu", GetLastError());
2289                         exit_sts = ARCHIVE_FAILED;
2290                         goto exit_setup_sparse;
2291                 }
2292         }
2293 exit_setup_sparse:
2294         free(outranges);
2295
2296         return (exit_sts);
2297 }
2298
2299 #endif