Imported Upstream version 3.3.0
[platform/upstream/libarchive.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 BUFFER_SIZE     (1024 * 8)
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, 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, 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, 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->enable_copyfile = 1;
402         a->traverse_mount_points = 1;
403         return (&a->archive);
404 }
405
406 static int
407 _archive_read_free(struct archive *_a)
408 {
409         struct archive_read_disk *a = (struct archive_read_disk *)_a;
410         int r;
411
412         if (_a == NULL)
413                 return (ARCHIVE_OK);
414         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
415             ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
416
417         if (a->archive.state != ARCHIVE_STATE_CLOSED)
418                 r = _archive_read_close(&a->archive);
419         else
420                 r = ARCHIVE_OK;
421
422         tree_free(a->tree);
423         if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
424                 (a->cleanup_gname)(a->lookup_gname_data);
425         if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
426                 (a->cleanup_uname)(a->lookup_uname_data);
427         archive_string_free(&a->archive.error_string);
428         archive_entry_free(a->entry);
429         a->archive.magic = 0;
430         free(a);
431         return (r);
432 }
433
434 static int
435 _archive_read_close(struct archive *_a)
436 {
437         struct archive_read_disk *a = (struct archive_read_disk *)_a;
438
439         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
440             ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
441
442         if (a->archive.state != ARCHIVE_STATE_FATAL)
443                 a->archive.state = ARCHIVE_STATE_CLOSED;
444
445         tree_close(a->tree);
446
447         return (ARCHIVE_OK);
448 }
449
450 static void
451 setup_symlink_mode(struct archive_read_disk *a, char symlink_mode, 
452     int follow_symlinks)
453 {
454         a->symlink_mode = symlink_mode;
455         a->follow_symlinks = follow_symlinks;
456         if (a->tree != NULL) {
457                 a->tree->initial_symlink_mode = a->symlink_mode;
458                 a->tree->symlink_mode = a->symlink_mode;
459         }
460 }
461
462 int
463 archive_read_disk_set_symlink_logical(struct archive *_a)
464 {
465         struct archive_read_disk *a = (struct archive_read_disk *)_a;
466         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
467             ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
468         setup_symlink_mode(a, 'L', 1);
469         return (ARCHIVE_OK);
470 }
471
472 int
473 archive_read_disk_set_symlink_physical(struct archive *_a)
474 {
475         struct archive_read_disk *a = (struct archive_read_disk *)_a;
476         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
477             ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
478         setup_symlink_mode(a, 'P', 0);
479         return (ARCHIVE_OK);
480 }
481
482 int
483 archive_read_disk_set_symlink_hybrid(struct archive *_a)
484 {
485         struct archive_read_disk *a = (struct archive_read_disk *)_a;
486         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
487             ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
488         setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
489         return (ARCHIVE_OK);
490 }
491
492 int
493 archive_read_disk_set_atime_restored(struct archive *_a)
494 {
495         struct archive_read_disk *a = (struct archive_read_disk *)_a;
496         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
497             ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
498         a->restore_time = 1;
499         if (a->tree != NULL)
500                 a->tree->flags |= needsRestoreTimes;
501         return (ARCHIVE_OK);
502 }
503
504 int
505 archive_read_disk_set_behavior(struct archive *_a, int flags)
506 {
507         struct archive_read_disk *a = (struct archive_read_disk *)_a;
508         int r = ARCHIVE_OK;
509
510         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
511             ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
512
513         if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
514                 r = archive_read_disk_set_atime_restored(_a);
515         else {
516                 a->restore_time = 0;
517                 if (a->tree != NULL)
518                         a->tree->flags &= ~needsRestoreTimes;
519         }
520         if (flags & ARCHIVE_READDISK_HONOR_NODUMP)
521                 a->honor_nodump = 1;
522         else
523                 a->honor_nodump = 0;
524         if (flags & ARCHIVE_READDISK_MAC_COPYFILE)
525                 a->enable_copyfile = 1;
526         else
527                 a->enable_copyfile = 0;
528         if (flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
529                 a->traverse_mount_points = 0;
530         else
531                 a->traverse_mount_points = 1;
532         return (r);
533 }
534
535 /*
536  * Trivial implementations of gname/uname lookup functions.
537  * These are normally overridden by the client, but these stub
538  * versions ensure that we always have something that works.
539  */
540 static const char *
541 trivial_lookup_gname(void *private_data, int64_t gid)
542 {
543         (void)private_data; /* UNUSED */
544         (void)gid; /* UNUSED */
545         return (NULL);
546 }
547
548 static const char *
549 trivial_lookup_uname(void *private_data, int64_t uid)
550 {
551         (void)private_data; /* UNUSED */
552         (void)uid; /* UNUSED */
553         return (NULL);
554 }
555
556 static int64_t
557 align_num_per_sector(struct tree *t, int64_t size)
558 {
559         int64_t surplus;
560
561         size += t->current_filesystem->bytesPerSector -1;
562         surplus = size % t->current_filesystem->bytesPerSector;
563         size -= surplus;
564         return (size);
565 }
566
567 static int
568 start_next_async_read(struct archive_read_disk *a, struct tree *t)
569 {
570         struct la_overlapped *olp;
571         DWORD buffbytes, rbytes;
572
573         if (t->ol_remaining_bytes == 0)
574                 return (ARCHIVE_EOF);
575
576         olp = &(t->ol[t->ol_idx_doing]);
577         t->ol_idx_doing = (t->ol_idx_doing + 1) % MAX_OVERLAPPED;
578
579         /* Allocate read buffer. */
580         if (olp->buff == NULL) {
581                 void *p;
582                 size_t s = (size_t)align_num_per_sector(t, BUFFER_SIZE);
583                 p = VirtualAlloc(NULL, s, MEM_COMMIT, PAGE_READWRITE);
584                 if (p == NULL) {
585                         archive_set_error(&a->archive, ENOMEM,
586                             "Couldn't allocate memory");
587                         a->archive.state = ARCHIVE_STATE_FATAL;
588                         return (ARCHIVE_FATAL);
589                 }
590                 olp->buff = p;
591                 olp->buff_size = s;
592                 olp->_a = &a->archive;
593                 olp->ol.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
594                 if (olp->ol.hEvent == NULL) {
595                         la_dosmaperr(GetLastError());
596                         archive_set_error(&a->archive, errno,
597                             "CreateEvent failed");
598                         a->archive.state = ARCHIVE_STATE_FATAL;
599                         return (ARCHIVE_FATAL);
600                 }
601         } else
602                 ResetEvent(olp->ol.hEvent);
603
604         buffbytes = (DWORD)olp->buff_size;
605         if (buffbytes > t->current_sparse->length)
606                 buffbytes = (DWORD)t->current_sparse->length;
607
608         /* Skip hole. */
609         if (t->current_sparse->offset > t->ol_total) {
610                 t->ol_remaining_bytes -=
611                         t->current_sparse->offset - t->ol_total;
612         }
613
614         olp->offset = t->current_sparse->offset;
615         olp->ol.Offset = (DWORD)(olp->offset & 0xffffffff);
616         olp->ol.OffsetHigh = (DWORD)(olp->offset >> 32);
617
618         if (t->ol_remaining_bytes > buffbytes) {
619                 olp->bytes_expected = buffbytes;
620                 t->ol_remaining_bytes -= buffbytes;
621         } else {
622                 olp->bytes_expected = (size_t)t->ol_remaining_bytes;
623                 t->ol_remaining_bytes = 0;
624         }
625         olp->bytes_transferred = 0;
626         t->current_sparse->offset += buffbytes;
627         t->current_sparse->length -= buffbytes;
628         t->ol_total = t->current_sparse->offset;
629         if (t->current_sparse->length == 0 && t->ol_remaining_bytes > 0)
630                 t->current_sparse++;
631
632         if (!ReadFile(t->entry_fh, olp->buff, buffbytes, &rbytes, &(olp->ol))) {
633                 DWORD lasterr;
634
635                 lasterr = GetLastError();
636                 if (lasterr == ERROR_HANDLE_EOF) {
637                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
638                             "Reading file truncated");
639                         a->archive.state = ARCHIVE_STATE_FATAL;
640                         return (ARCHIVE_FATAL);
641                 } else if (lasterr != ERROR_IO_PENDING) {
642                         if (lasterr == ERROR_NO_DATA)
643                                 errno = EAGAIN;
644                         else if (lasterr == ERROR_ACCESS_DENIED)
645                                 errno = EBADF;
646                         else
647                                 la_dosmaperr(lasterr);
648                         archive_set_error(&a->archive, errno, "Read error");
649                         a->archive.state = ARCHIVE_STATE_FATAL;
650                         return (ARCHIVE_FATAL);
651                 }
652         } else
653                 olp->bytes_transferred = rbytes;
654         t->ol_num_doing++;
655
656         return (t->ol_remaining_bytes == 0)? ARCHIVE_EOF: ARCHIVE_OK;
657 }
658
659 static void
660 cancel_async(struct tree *t)
661 {
662         if (t->ol_num_doing != t->ol_num_done) {
663                 CancelIo(t->entry_fh);
664                 t->ol_num_doing = t->ol_num_done = 0;
665         }
666 }
667
668 static int
669 _archive_read_data_block(struct archive *_a, const void **buff,
670     size_t *size, int64_t *offset)
671 {
672         struct archive_read_disk *a = (struct archive_read_disk *)_a;
673         struct tree *t = a->tree;
674         struct la_overlapped *olp;
675         DWORD bytes_transferred;
676         int r = ARCHIVE_FATAL;
677
678         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
679             "archive_read_data_block");
680
681         if (t->entry_eof || t->entry_remaining_bytes <= 0) {
682                 r = ARCHIVE_EOF;
683                 goto abort_read_data;
684         }
685
686         /*
687          * Make a request to read the file in asynchronous.
688          */
689         if (t->ol_num_doing == 0) {
690                 do {
691                         r = start_next_async_read(a, t);
692                         if (r == ARCHIVE_FATAL)
693                                 goto abort_read_data;
694                         if (!t->async_io)
695                                 break;
696                 } while (r == ARCHIVE_OK && t->ol_num_doing < MAX_OVERLAPPED);
697         } else {
698                 if (start_next_async_read(a, t) == ARCHIVE_FATAL)
699                         goto abort_read_data;
700         }
701
702         olp = &(t->ol[t->ol_idx_done]);
703         t->ol_idx_done = (t->ol_idx_done + 1) % MAX_OVERLAPPED;
704         if (olp->bytes_transferred)
705                 bytes_transferred = (DWORD)olp->bytes_transferred;
706         else if (!GetOverlappedResult(t->entry_fh, &(olp->ol),
707             &bytes_transferred, TRUE)) {
708                 la_dosmaperr(GetLastError());
709                 archive_set_error(&a->archive, errno,
710                     "GetOverlappedResult failed");
711                 a->archive.state = ARCHIVE_STATE_FATAL;
712                 r = ARCHIVE_FATAL;
713                 goto abort_read_data;
714         }
715         t->ol_num_done++;
716
717         if (bytes_transferred == 0 ||
718             olp->bytes_expected != bytes_transferred) {
719                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
720                     "Reading file truncated");
721                 a->archive.state = ARCHIVE_STATE_FATAL;
722                 r = ARCHIVE_FATAL;
723                 goto abort_read_data;
724         }
725
726         *buff = olp->buff;
727         *size = bytes_transferred;
728         *offset = olp->offset;
729         if (olp->offset > t->entry_total)
730                 t->entry_remaining_bytes -= olp->offset - t->entry_total;
731         t->entry_total = olp->offset + *size;
732         t->entry_remaining_bytes -= *size;
733         if (t->entry_remaining_bytes == 0) {
734                 /* Close the current file descriptor */
735                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
736                 t->entry_fh = INVALID_HANDLE_VALUE;
737                 t->entry_eof = 1;
738         }
739         return (ARCHIVE_OK);
740
741 abort_read_data:
742         *buff = NULL;
743         *size = 0;
744         *offset = t->entry_total;
745         if (t->entry_fh != INVALID_HANDLE_VALUE) {
746                 cancel_async(t);
747                 /* Close the current file descriptor */
748                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
749                 t->entry_fh = INVALID_HANDLE_VALUE;
750         }
751         return (r);
752 }
753
754 static int
755 next_entry(struct archive_read_disk *a, struct tree *t,
756     struct archive_entry *entry)
757 {
758         const BY_HANDLE_FILE_INFORMATION *st;
759         const BY_HANDLE_FILE_INFORMATION *lst;
760         const char*name;
761         int descend, r;
762
763         st = NULL;
764         lst = NULL;
765         t->descend = 0;
766         do {
767                 switch (tree_next(t)) {
768                 case TREE_ERROR_FATAL:
769                         archive_set_error(&a->archive, t->tree_errno,
770                             "%ls: Unable to continue traversing directory tree",
771                             tree_current_path(t));
772                         a->archive.state = ARCHIVE_STATE_FATAL;
773                         return (ARCHIVE_FATAL);
774                 case TREE_ERROR_DIR:
775                         archive_set_error(&a->archive, t->tree_errno,
776                             "%ls: Couldn't visit directory",
777                             tree_current_path(t));
778                         return (ARCHIVE_FAILED);
779                 case 0:
780                         return (ARCHIVE_EOF);
781                 case TREE_POSTDESCENT:
782                 case TREE_POSTASCENT:
783                         break;
784                 case TREE_REGULAR:
785                         lst = tree_current_lstat(t);
786                         if (lst == NULL) {
787                                 archive_set_error(&a->archive, t->tree_errno,
788                                     "%ls: Cannot stat",
789                                     tree_current_path(t));
790                                 return (ARCHIVE_FAILED);
791                         }
792                         break;
793                 }       
794         } while (lst == NULL);
795
796         archive_entry_copy_pathname_w(entry, tree_current_path(t));
797
798         /*
799          * Perform path matching.
800          */
801         if (a->matching) {
802                 r = archive_match_path_excluded(a->matching, entry);
803                 if (r < 0) {
804                         archive_set_error(&(a->archive), errno,
805                             "Failed : %s", archive_error_string(a->matching));
806                         return (r);
807                 }
808                 if (r) {
809                         if (a->excluded_cb_func)
810                                 a->excluded_cb_func(&(a->archive),
811                                     a->excluded_cb_data, entry);
812                         return (ARCHIVE_RETRY);
813                 }
814         }
815
816         /*
817          * Distinguish 'L'/'P'/'H' symlink following.
818          */
819         switch(t->symlink_mode) {
820         case 'H':
821                 /* 'H': After the first item, rest like 'P'. */
822                 t->symlink_mode = 'P';
823                 /* 'H': First item (from command line) like 'L'. */
824                 /* FALLTHROUGH */
825         case 'L':
826                 /* 'L': Do descend through a symlink to dir. */
827                 descend = tree_current_is_dir(t);
828                 /* 'L': Follow symlinks to files. */
829                 a->symlink_mode = 'L';
830                 a->follow_symlinks = 1;
831                 /* 'L': Archive symlinks as targets, if we can. */
832                 st = tree_current_stat(t);
833                 if (st != NULL && !tree_target_is_same_as_parent(t, st))
834                         break;
835                 /* If stat fails, we have a broken symlink;
836                  * in that case, don't follow the link. */
837                 /* FALLTHROUGH */
838         default:
839                 /* 'P': Don't descend through a symlink to dir. */
840                 descend = tree_current_is_physical_dir(t);
841                 /* 'P': Don't follow symlinks to files. */
842                 a->symlink_mode = 'P';
843                 a->follow_symlinks = 0;
844                 /* 'P': Archive symlinks as symlinks. */
845                 st = lst;
846                 break;
847         }
848
849         if (update_current_filesystem(a, bhfi_dev(st)) != ARCHIVE_OK) {
850                 a->archive.state = ARCHIVE_STATE_FATAL;
851                 return (ARCHIVE_FATAL);
852         }
853         if (t->initial_filesystem_id == -1)
854                 t->initial_filesystem_id = t->current_filesystem_id;
855         if (!a->traverse_mount_points) {
856                 if (t->initial_filesystem_id != t->current_filesystem_id)
857                         return (ARCHIVE_RETRY);
858         }
859         t->descend = descend;
860
861         tree_archive_entry_copy_bhfi(entry, t, st);
862
863         /* Save the times to be restored. This must be in before
864          * calling archive_read_disk_descend() or any chance of it,
865          * especially, invoking a callback. */
866         t->restore_time.lastWriteTime = st->ftLastWriteTime;
867         t->restore_time.lastAccessTime = st->ftLastAccessTime;
868         t->restore_time.filetype = archive_entry_filetype(entry);
869
870         /*
871          * Perform time matching.
872          */
873         if (a->matching) {
874                 r = archive_match_time_excluded(a->matching, entry);
875                 if (r < 0) {
876                         archive_set_error(&(a->archive), errno,
877                             "Failed : %s", archive_error_string(a->matching));
878                         return (r);
879                 }
880                 if (r) {
881                         if (a->excluded_cb_func)
882                                 a->excluded_cb_func(&(a->archive),
883                                     a->excluded_cb_data, entry);
884                         return (ARCHIVE_RETRY);
885                 }
886         }
887
888         /* Lookup uname/gname */
889         name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
890         if (name != NULL)
891                 archive_entry_copy_uname(entry, name);
892         name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
893         if (name != NULL)
894                 archive_entry_copy_gname(entry, name);
895
896         /*
897          * Perform owner matching.
898          */
899         if (a->matching) {
900                 r = archive_match_owner_excluded(a->matching, entry);
901                 if (r < 0) {
902                         archive_set_error(&(a->archive), errno,
903                             "Failed : %s", archive_error_string(a->matching));
904                         return (r);
905                 }
906                 if (r) {
907                         if (a->excluded_cb_func)
908                                 a->excluded_cb_func(&(a->archive),
909                                     a->excluded_cb_data, entry);
910                         return (ARCHIVE_RETRY);
911                 }
912         }
913
914         /*
915          * Invoke a meta data filter callback.
916          */
917         if (a->metadata_filter_func) {
918                 if (!a->metadata_filter_func(&(a->archive),
919                     a->metadata_filter_data, entry))
920                         return (ARCHIVE_RETRY);
921         }
922
923         archive_entry_copy_sourcepath_w(entry, tree_current_access_path(t));
924
925         r = ARCHIVE_OK;
926         if (archive_entry_filetype(entry) == AE_IFREG &&
927             archive_entry_size(entry) > 0) {
928                 DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
929                 if (t->async_io)
930                         flags |= FILE_FLAG_OVERLAPPED;
931                 if (t->direct_io)
932                         flags |= FILE_FLAG_NO_BUFFERING;
933                 else
934                         flags |= FILE_FLAG_SEQUENTIAL_SCAN;
935                 t->entry_fh = CreateFileW(tree_current_access_path(t),
936                     GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
937                 if (t->entry_fh == INVALID_HANDLE_VALUE) {
938                         archive_set_error(&a->archive, errno,
939                             "Couldn't open %ls", tree_current_path(a->tree));
940                         return (ARCHIVE_FAILED);
941                 }
942
943                 /* Find sparse data from the disk. */
944                 if (archive_entry_hardlink(entry) == NULL &&
945                     (st->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0)
946                         r = setup_sparse_from_disk(a, entry, t->entry_fh);
947         }
948         return (r);
949 }
950
951 static int
952 _archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
953 {
954        int ret;
955        struct archive_read_disk *a = (struct archive_read_disk *)_a;
956        *entryp = NULL;
957        ret = _archive_read_next_header2(_a, a->entry);
958        *entryp = a->entry;
959        return ret;
960 }
961
962 static int
963 _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
964 {
965         struct archive_read_disk *a = (struct archive_read_disk *)_a;
966         struct tree *t;
967         int r;
968
969         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
970             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
971             "archive_read_next_header2");
972
973         t = a->tree;
974         if (t->entry_fh != INVALID_HANDLE_VALUE) {
975                 cancel_async(t);
976                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
977                 t->entry_fh = INVALID_HANDLE_VALUE;
978         }
979
980         while ((r = next_entry(a, t, entry)) == ARCHIVE_RETRY)
981                 archive_entry_clear(entry);
982
983         /*
984          * EOF and FATAL are persistent at this layer.  By
985          * modifying the state, we guarantee that future calls to
986          * read a header or read data will fail.
987          */
988         switch (r) {
989         case ARCHIVE_EOF:
990                 a->archive.state = ARCHIVE_STATE_EOF;
991                 break;
992         case ARCHIVE_OK:
993         case ARCHIVE_WARN:
994                 t->entry_total = 0;
995                 if (archive_entry_filetype(entry) == AE_IFREG) {
996                         t->entry_remaining_bytes = archive_entry_size(entry);
997                         t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
998                         if (!t->entry_eof &&
999                             setup_sparse(a, entry) != ARCHIVE_OK)
1000                                 return (ARCHIVE_FATAL);
1001                 } else {
1002                         t->entry_remaining_bytes = 0;
1003                         t->entry_eof = 1;
1004                 }
1005                 t->ol_idx_doing = t->ol_idx_done = 0;
1006                 t->ol_num_doing = t->ol_num_done = 0;
1007                 t->ol_remaining_bytes = t->entry_remaining_bytes;
1008                 t->ol_total = 0;
1009                 a->archive.state = ARCHIVE_STATE_DATA;
1010                 break;
1011         case ARCHIVE_RETRY:
1012                 break;
1013         case ARCHIVE_FATAL:
1014                 a->archive.state = ARCHIVE_STATE_FATAL;
1015                 break;
1016         }
1017
1018         __archive_reset_read_data(&a->archive);
1019         return (r);
1020 }
1021
1022 static int
1023 setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
1024 {
1025         struct tree *t = a->tree;
1026         int64_t aligned, length, offset;
1027         int i;
1028
1029         t->sparse_count = archive_entry_sparse_reset(entry);
1030         if (t->sparse_count+1 > t->sparse_list_size) {
1031                 free(t->sparse_list);
1032                 t->sparse_list_size = t->sparse_count + 1;
1033                 t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
1034                     t->sparse_list_size);
1035                 if (t->sparse_list == NULL) {
1036                         t->sparse_list_size = 0;
1037                         archive_set_error(&a->archive, ENOMEM,
1038                             "Can't allocate data");
1039                         a->archive.state = ARCHIVE_STATE_FATAL;
1040                         return (ARCHIVE_FATAL);
1041                 }
1042         }
1043         /*
1044          * Get sparse list and make sure those offsets and lengths are
1045          * aligned by a sector size.
1046          */
1047         for (i = 0; i < t->sparse_count; i++) {
1048                 archive_entry_sparse_next(entry, &offset, &length);
1049                 aligned = align_num_per_sector(t, offset);
1050                 if (aligned != offset) {
1051                         aligned -= t->current_filesystem->bytesPerSector;
1052                         length += offset - aligned;
1053                 }
1054                 t->sparse_list[i].offset = aligned;
1055                 aligned = align_num_per_sector(t, length);
1056                 t->sparse_list[i].length = aligned;
1057         }
1058
1059         aligned = align_num_per_sector(t, archive_entry_size(entry));
1060         if (i == 0) {
1061                 t->sparse_list[i].offset = 0;
1062                 t->sparse_list[i].length = aligned;
1063         } else {
1064                 int j, last = i;
1065
1066                 t->sparse_list[i].offset = aligned;
1067                 t->sparse_list[i].length = 0;
1068                 for (i = 0; i < last; i++) {
1069                         if ((t->sparse_list[i].offset +
1070                                t->sparse_list[i].length) <= 
1071                                         t->sparse_list[i+1].offset)
1072                                 continue;
1073                         /*
1074                          * Now sparse_list[i+1] is overlapped by sparse_list[i].
1075                          * Merge those two.
1076                          */
1077                         length = t->sparse_list[i+1].offset -
1078                                         t->sparse_list[i].offset;
1079                         t->sparse_list[i+1].offset = t->sparse_list[i].offset;
1080                         t->sparse_list[i+1].length += length;
1081                         /* Remove sparse_list[i]. */
1082                         for (j = i; j < last; j++) {
1083                                 t->sparse_list[j].offset =
1084                                     t->sparse_list[j+1].offset;
1085                                 t->sparse_list[j].length =
1086                                     t->sparse_list[j+1].length;
1087                         }
1088                         last--;
1089                 }
1090         }
1091         t->current_sparse = t->sparse_list;
1092
1093         return (ARCHIVE_OK);
1094 }
1095
1096 int
1097 archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
1098     void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
1099     void *_client_data)
1100 {
1101         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1102         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1103             ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
1104         a->matching = _ma;
1105         a->excluded_cb_func = _excluded_func;
1106         a->excluded_cb_data = _client_data;
1107         return (ARCHIVE_OK);
1108 }
1109
1110 int
1111 archive_read_disk_set_metadata_filter_callback(struct archive *_a,
1112     int (*_metadata_filter_func)(struct archive *, void *,
1113     struct archive_entry *), void *_client_data)
1114 {
1115         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1116
1117         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
1118             "archive_read_disk_set_metadata_filter_callback");
1119
1120         a->metadata_filter_func = _metadata_filter_func;
1121         a->metadata_filter_data = _client_data;
1122         return (ARCHIVE_OK);
1123 }
1124
1125 int
1126 archive_read_disk_can_descend(struct archive *_a)
1127 {
1128         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1129         struct tree *t = a->tree;
1130
1131         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1132             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1133             "archive_read_disk_can_descend");
1134
1135         return (t->visit_type == TREE_REGULAR && t->descend);
1136 }
1137
1138 /*
1139  * Called by the client to mark the directory just returned from
1140  * tree_next() as needing to be visited.
1141  */
1142 int
1143 archive_read_disk_descend(struct archive *_a)
1144 {
1145         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1146         struct tree *t = a->tree;
1147
1148         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1149             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1150             "archive_read_disk_descend");
1151
1152         if (t->visit_type != TREE_REGULAR || !t->descend)
1153                 return (ARCHIVE_OK);
1154
1155         if (tree_current_is_physical_dir(t)) {
1156                 tree_push(t, t->basename, t->full_path.s,
1157                     t->current_filesystem_id,
1158                     bhfi_dev(&(t->lst)), bhfi_ino(&(t->lst)),
1159                     &t->restore_time);
1160                 t->stack->flags |= isDir;
1161         } else if (tree_current_is_dir(t)) {
1162                 tree_push(t, t->basename, t->full_path.s,
1163                     t->current_filesystem_id,
1164                     bhfi_dev(&(t->st)), bhfi_ino(&(t->st)),
1165                     &t->restore_time);
1166                 t->stack->flags |= isDirLink;
1167         }
1168         t->descend = 0;
1169         return (ARCHIVE_OK);
1170 }
1171
1172 int
1173 archive_read_disk_open(struct archive *_a, const char *pathname)
1174 {
1175         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1176         struct archive_wstring wpath;
1177         int ret;
1178
1179         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1180             ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
1181             "archive_read_disk_open");
1182         archive_clear_error(&a->archive);
1183
1184         /* Make a wchar_t string from a char string. */
1185         archive_string_init(&wpath);
1186         if (archive_wstring_append_from_mbs(&wpath, pathname,
1187             strlen(pathname)) != 0) {
1188                 if (errno == ENOMEM)
1189                         archive_set_error(&a->archive, ENOMEM,
1190                             "Can't allocate memory");
1191                 else
1192                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1193                             "Can't convert a path to a wchar_t string");
1194                 a->archive.state = ARCHIVE_STATE_FATAL;
1195                 ret = ARCHIVE_FATAL;
1196         } else
1197                 ret = _archive_read_disk_open_w(_a, wpath.s);
1198
1199         archive_wstring_free(&wpath);
1200         return (ret);
1201 }
1202
1203 int
1204 archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
1205 {
1206         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1207
1208         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1209             ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
1210             "archive_read_disk_open_w");
1211         archive_clear_error(&a->archive);
1212
1213         return (_archive_read_disk_open_w(_a, pathname));
1214 }
1215
1216 static int
1217 _archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
1218 {
1219         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1220
1221         if (a->tree != NULL)
1222                 a->tree = tree_reopen(a->tree, pathname, a->restore_time);
1223         else
1224                 a->tree = tree_open(pathname, a->symlink_mode, a->restore_time);
1225         if (a->tree == NULL) {
1226                 archive_set_error(&a->archive, ENOMEM,
1227                     "Can't allocate directory traversal data");
1228                 a->archive.state = ARCHIVE_STATE_FATAL;
1229                 return (ARCHIVE_FATAL);
1230         }
1231         a->archive.state = ARCHIVE_STATE_HEADER;
1232
1233         return (ARCHIVE_OK);
1234 }
1235
1236 /*
1237  * Return a current filesystem ID which is index of the filesystem entry
1238  * you've visited through archive_read_disk.
1239  */
1240 int
1241 archive_read_disk_current_filesystem(struct archive *_a)
1242 {
1243         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1244
1245         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1246             "archive_read_disk_current_filesystem");
1247
1248         return (a->tree->current_filesystem_id);
1249 }
1250
1251 static int
1252 update_current_filesystem(struct archive_read_disk *a, int64_t dev)
1253 {
1254         struct tree *t = a->tree;
1255         int i, fid;
1256
1257         if (t->current_filesystem != NULL &&
1258             t->current_filesystem->dev == dev)
1259                 return (ARCHIVE_OK);
1260
1261         for (i = 0; i < t->max_filesystem_id; i++) {
1262                 if (t->filesystem_table[i].dev == dev) {
1263                         /* There is the filesystem ID we've already generated. */
1264                         t->current_filesystem_id = i;
1265                         t->current_filesystem = &(t->filesystem_table[i]);
1266                         return (ARCHIVE_OK);
1267                 }
1268         }
1269
1270         /*
1271          * There is a new filesystem, we generate a new ID for.
1272          */
1273         fid = t->max_filesystem_id++;
1274         if (t->max_filesystem_id > t->allocated_filesystem) {
1275                 size_t s;
1276                 void *p;
1277
1278                 s = t->max_filesystem_id * 2;
1279                 p = realloc(t->filesystem_table,
1280                         s * sizeof(*t->filesystem_table));
1281                 if (p == NULL) {
1282                         archive_set_error(&a->archive, ENOMEM,
1283                             "Can't allocate tar data");
1284                         return (ARCHIVE_FATAL);
1285                 }
1286                 t->filesystem_table = (struct filesystem *)p;
1287                 t->allocated_filesystem = (int)s;
1288         }
1289         t->current_filesystem_id = fid;
1290         t->current_filesystem = &(t->filesystem_table[fid]);
1291         t->current_filesystem->dev = dev;
1292
1293         return (setup_current_filesystem(a));
1294 }
1295
1296 /*
1297  * Returns 1 if current filesystem is generated filesystem, 0 if it is not
1298  * or -1 if it is unknown.
1299  */
1300 int
1301 archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
1302 {
1303         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1304
1305         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1306             "archive_read_disk_current_filesystem");
1307
1308         return (a->tree->current_filesystem->synthetic);
1309 }
1310
1311 /*
1312  * Returns 1 if current filesystem is remote filesystem, 0 if it is not
1313  * or -1 if it is unknown.
1314  */
1315 int
1316 archive_read_disk_current_filesystem_is_remote(struct archive *_a)
1317 {
1318         struct archive_read_disk *a = (struct archive_read_disk *)_a;
1319
1320         archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1321             "archive_read_disk_current_filesystem");
1322
1323         return (a->tree->current_filesystem->remote);
1324 }
1325
1326 /*
1327  * If symlink is broken, statfs or statvfs will fail.
1328  * Use its directory path instead.
1329  */
1330 static wchar_t *
1331 safe_path_for_statfs(struct tree *t)
1332 {
1333         const wchar_t *path;
1334         wchar_t *cp, *p = NULL;
1335
1336         path = tree_current_access_path(t);
1337         if (tree_current_stat(t) == NULL) {
1338                 p = _wcsdup(path);
1339                 cp = wcsrchr(p, '/');
1340                 if (cp != NULL && wcslen(cp) >= 2) {
1341                         cp[1] = '.';
1342                         cp[2] = '\0';
1343                         path = p;
1344                 }
1345         } else
1346                 p = _wcsdup(path);
1347         return (p);
1348 }
1349
1350 /*
1351  * Get conditions of synthetic and remote on Windows
1352  */
1353 static int
1354 setup_current_filesystem(struct archive_read_disk *a)
1355 {
1356         struct tree *t = a->tree;
1357         wchar_t vol[256];
1358         wchar_t *path;
1359
1360         t->current_filesystem->synthetic = -1;/* Not supported */
1361         path = safe_path_for_statfs(t);
1362         if (!GetVolumePathNameW(path, vol, sizeof(vol)/sizeof(vol[0]))) {
1363                 free(path);
1364                 t->current_filesystem->remote = -1;
1365                 t->current_filesystem->bytesPerSector = 0;
1366                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1367                         "GetVolumePathName failed: %d", (int)GetLastError());
1368                 return (ARCHIVE_FAILED);
1369         }
1370         free(path);
1371         switch (GetDriveTypeW(vol)) {
1372         case DRIVE_UNKNOWN:
1373         case DRIVE_NO_ROOT_DIR:
1374                 t->current_filesystem->remote = -1;
1375                 break;
1376         case DRIVE_REMOTE:
1377                 t->current_filesystem->remote = 1;
1378                 break;
1379         default:
1380                 t->current_filesystem->remote = 0;
1381                 break;
1382         }
1383
1384         if (!GetDiskFreeSpaceW(vol, NULL,
1385             &(t->current_filesystem->bytesPerSector), NULL, NULL)) {
1386                 t->current_filesystem->bytesPerSector = 0;
1387                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1388                         "GetDiskFreeSpace failed: %d", (int)GetLastError());
1389                 return (ARCHIVE_FAILED);
1390         }
1391
1392         return (ARCHIVE_OK);
1393 }
1394
1395 static int
1396 close_and_restore_time(HANDLE h, struct tree *t, struct restore_time *rt)
1397 {
1398         HANDLE handle;
1399         int r = 0;
1400
1401         if (h == INVALID_HANDLE_VALUE && AE_IFLNK == rt->filetype)
1402                 return (0);
1403
1404         /* Close a file descriptor.
1405          * It will not be used for SetFileTime() because it has been opened
1406          * by a read only mode.
1407          */
1408         if (h != INVALID_HANDLE_VALUE)
1409                 CloseHandle(h);
1410         if ((t->flags & needsRestoreTimes) == 0)
1411                 return (r);
1412
1413         handle = CreateFileW(rt->full_path, FILE_WRITE_ATTRIBUTES,
1414                     0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
1415         if (handle == INVALID_HANDLE_VALUE) {
1416                 errno = EINVAL;
1417                 return (-1);
1418         }
1419
1420         if (SetFileTime(handle, NULL, &rt->lastAccessTime,
1421             &rt->lastWriteTime) == 0) {
1422                 errno = EINVAL;
1423                 r = -1;
1424         } else
1425                 r = 0;
1426         CloseHandle(handle);
1427         return (r);
1428 }
1429
1430 /*
1431  * Add a directory path to the current stack.
1432  */
1433 static void
1434 tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path,
1435     int filesystem_id, int64_t dev, int64_t ino, struct restore_time *rt)
1436 {
1437         struct tree_entry *te;
1438
1439         te = calloc(1, sizeof(*te));
1440         te->next = t->stack;
1441         te->parent = t->current;
1442         if (te->parent)
1443                 te->depth = te->parent->depth + 1;
1444         t->stack = te;
1445         archive_string_init(&te->name);
1446         archive_wstrcpy(&te->name, path);
1447         archive_string_init(&te->full_path);
1448         archive_wstrcpy(&te->full_path, full_path);
1449         te->flags = needsDescent | needsOpen | needsAscent;
1450         te->filesystem_id = filesystem_id;
1451         te->dev = dev;
1452         te->ino = ino;
1453         te->dirname_length = t->dirname_length;
1454         te->full_path_dir_length = t->full_path_dir_length;
1455         te->restore_time.full_path = te->full_path.s;
1456         if (rt != NULL) {
1457                 te->restore_time.lastWriteTime = rt->lastWriteTime;
1458                 te->restore_time.lastAccessTime = rt->lastAccessTime;
1459                 te->restore_time.filetype = rt->filetype;
1460         }
1461 }
1462
1463 /*
1464  * Append a name to the current dir path.
1465  */
1466 static void
1467 tree_append(struct tree *t, const wchar_t *name, size_t name_length)
1468 {
1469         size_t size_needed;
1470
1471         t->path.s[t->dirname_length] = L'\0';
1472         t->path.length = t->dirname_length;
1473         /* Strip trailing '/' from name, unless entire name is "/". */
1474         while (name_length > 1 && name[name_length - 1] == L'/')
1475                 name_length--;
1476
1477         /* Resize pathname buffer as needed. */
1478         size_needed = name_length + t->dirname_length + 2;
1479         archive_wstring_ensure(&t->path, size_needed);
1480         /* Add a separating '/' if it's needed. */
1481         if (t->dirname_length > 0 &&
1482             t->path.s[archive_strlen(&t->path)-1] != L'/')
1483                 archive_wstrappend_wchar(&t->path, L'/');
1484         t->basename = t->path.s + archive_strlen(&t->path);
1485         archive_wstrncat(&t->path, name, name_length);
1486         t->restore_time.full_path = t->basename;
1487         if (t->full_path_dir_length > 0) {
1488                 t->full_path.s[t->full_path_dir_length] = L'\0';
1489                 t->full_path.length = t->full_path_dir_length;
1490                 size_needed = name_length + t->full_path_dir_length + 2;
1491                 archive_wstring_ensure(&t->full_path, size_needed);
1492                 /* Add a separating '\' if it's needed. */
1493                 if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\')
1494                         archive_wstrappend_wchar(&t->full_path, L'\\');
1495                 archive_wstrncat(&t->full_path, name, name_length);
1496                 t->restore_time.full_path = t->full_path.s;
1497         }
1498 }
1499
1500 /*
1501  * Open a directory tree for traversal.
1502  */
1503 static struct tree *
1504 tree_open(const wchar_t *path, int symlink_mode, int restore_time)
1505 {
1506         struct tree *t;
1507
1508         t = calloc(1, sizeof(*t));
1509         archive_string_init(&(t->full_path));
1510         archive_string_init(&t->path);
1511         archive_wstring_ensure(&t->path, 15);
1512         t->initial_symlink_mode = symlink_mode;
1513         return (tree_reopen(t, path, restore_time));
1514 }
1515
1516 static struct tree *
1517 tree_reopen(struct tree *t, const wchar_t *path, int restore_time)
1518 {
1519         struct archive_wstring ws;
1520         wchar_t *pathname, *p, *base;
1521
1522         t->flags = (restore_time)?needsRestoreTimes:0;
1523         t->visit_type = 0;
1524         t->tree_errno = 0;
1525         t->full_path_dir_length = 0;
1526         t->dirname_length = 0;
1527         t->depth = 0;
1528         t->descend = 0;
1529         t->current = NULL;
1530         t->d = INVALID_HANDLE_VALUE;
1531         t->symlink_mode = t->initial_symlink_mode;
1532         archive_string_empty(&(t->full_path));
1533         archive_string_empty(&t->path);
1534         t->entry_fh = INVALID_HANDLE_VALUE;
1535         t->entry_eof = 0;
1536         t->entry_remaining_bytes = 0;
1537         t->initial_filesystem_id = -1;
1538
1539         /* Get wchar_t strings from char strings. */
1540         archive_string_init(&ws);
1541         archive_wstrcpy(&ws, path);
1542         pathname = ws.s;
1543         /* Get a full-path-name. */
1544         p = __la_win_permissive_name_w(pathname);
1545         if (p == NULL)
1546                 goto failed;
1547         archive_wstrcpy(&(t->full_path), p);
1548         free(p);
1549
1550         /* Convert path separators from '\' to '/' */
1551         for (p = pathname; *p != L'\0'; ++p) {
1552                 if (*p == L'\\')
1553                         *p = L'/';
1554         }
1555         base = pathname;
1556
1557         /* First item is set up a lot like a symlink traversal. */
1558         /* printf("Looking for wildcard in %s\n", path); */
1559         if ((base[0] == L'/' && base[1] == L'/' &&
1560              base[2] == L'?' && base[3] == L'/' &&
1561              (wcschr(base+4, L'*') || wcschr(base+4, L'?'))) ||
1562             (!(base[0] == L'/' && base[1] == L'/' &&
1563                base[2] == L'?' && base[3] == L'/') &&
1564                (wcschr(base, L'*') || wcschr(base, L'?')))) {
1565                 // It has a wildcard in it...
1566                 // Separate the last element.
1567                 p = wcsrchr(base, L'/');
1568                 if (p != NULL) {
1569                         *p = L'\0';
1570                         tree_append(t, base, p - base);
1571                         t->dirname_length = archive_strlen(&t->path);
1572                         base = p + 1;
1573                 }
1574                 p = wcsrchr(t->full_path.s, L'\\');
1575                 if (p != NULL) {
1576                         *p = L'\0';
1577                         t->full_path.length = wcslen(t->full_path.s);
1578                         t->full_path_dir_length = archive_strlen(&t->full_path);
1579                 }
1580         }
1581         tree_push(t, base, t->full_path.s, 0, 0, 0, NULL);
1582         archive_wstring_free(&ws);
1583         t->stack->flags = needsFirstVisit;
1584         /*
1585          * Debug flag for Direct IO(No buffering) or Async IO.
1586          * Those dependent on environment variable switches
1587          * will be removed until next release.
1588          */
1589         {
1590                 const char *e;
1591                 if ((e = getenv("LIBARCHIVE_DIRECT_IO")) != NULL) {
1592                         if (e[0] == '0')
1593                                 t->direct_io = 0;
1594                         else
1595                                 t->direct_io = 1;
1596                         fprintf(stderr, "LIBARCHIVE_DIRECT_IO=%s\n",
1597                                 (t->direct_io)?"Enabled":"Disabled");
1598                 } else
1599                         t->direct_io = DIRECT_IO;
1600                 if ((e = getenv("LIBARCHIVE_ASYNC_IO")) != NULL) {
1601                         if (e[0] == '0')
1602                                 t->async_io = 0;
1603                         else
1604                                 t->async_io = 1;
1605                         fprintf(stderr, "LIBARCHIVE_ASYNC_IO=%s\n",
1606                             (t->async_io)?"Enabled":"Disabled");
1607                 } else
1608                         t->async_io = ASYNC_IO;
1609         }
1610         return (t);
1611 failed:
1612         archive_wstring_free(&ws);
1613         tree_free(t);
1614         return (NULL);
1615 }
1616
1617 static int
1618 tree_descent(struct tree *t)
1619 {
1620         t->dirname_length = archive_strlen(&t->path);
1621         t->full_path_dir_length = archive_strlen(&t->full_path);
1622         t->depth++;
1623         return (0);
1624 }
1625
1626 /*
1627  * We've finished a directory; ascend back to the parent.
1628  */
1629 static int
1630 tree_ascend(struct tree *t)
1631 {
1632         struct tree_entry *te;
1633
1634         te = t->stack;
1635         t->depth--;
1636         close_and_restore_time(INVALID_HANDLE_VALUE, t, &te->restore_time);
1637         return (0);
1638 }
1639
1640 /*
1641  * Pop the working stack.
1642  */
1643 static void
1644 tree_pop(struct tree *t)
1645 {
1646         struct tree_entry *te;
1647
1648         t->full_path.s[t->full_path_dir_length] = L'\0';
1649         t->full_path.length = t->full_path_dir_length;
1650         t->path.s[t->dirname_length] = L'\0';
1651         t->path.length = t->dirname_length;
1652         if (t->stack == t->current && t->current != NULL)
1653                 t->current = t->current->parent;
1654         te = t->stack;
1655         t->stack = te->next;
1656         t->dirname_length = te->dirname_length;
1657         t->basename = t->path.s + t->dirname_length;
1658         t->full_path_dir_length = te->full_path_dir_length;
1659         while (t->basename[0] == L'/')
1660                 t->basename++;
1661         archive_wstring_free(&te->name);
1662         archive_wstring_free(&te->full_path);
1663         free(te);
1664 }
1665
1666 /*
1667  * Get the next item in the tree traversal.
1668  */
1669 static int
1670 tree_next(struct tree *t)
1671 {
1672         int r;
1673
1674         while (t->stack != NULL) {
1675                 /* If there's an open dir, get the next entry from there. */
1676                 if (t->d != INVALID_HANDLE_VALUE) {
1677                         r = tree_dir_next_windows(t, NULL);
1678                         if (r == 0)
1679                                 continue;
1680                         return (r);
1681                 }
1682
1683                 if (t->stack->flags & needsFirstVisit) {
1684                         wchar_t *d = t->stack->name.s;
1685                         t->stack->flags &= ~needsFirstVisit;
1686                         if (!(d[0] == L'/' && d[1] == L'/' &&
1687                               d[2] == L'?' && d[3] == L'/') &&
1688                             (wcschr(d, L'*') || wcschr(d, L'?'))) {
1689                                 r = tree_dir_next_windows(t, d);
1690                                 if (r == 0)
1691                                         continue;
1692                                 return (r);
1693                         } else {
1694                                 HANDLE h = FindFirstFileW(d, &t->_findData);
1695                                 if (h == INVALID_HANDLE_VALUE) {
1696                                         la_dosmaperr(GetLastError());
1697                                         t->tree_errno = errno;
1698                                         t->visit_type = TREE_ERROR_DIR;
1699                                         return (t->visit_type);
1700                                 }
1701                                 t->findData = &t->_findData;
1702                                 FindClose(h);
1703                         }
1704                         /* Top stack item needs a regular visit. */
1705                         t->current = t->stack;
1706                         tree_append(t, t->stack->name.s,
1707                             archive_strlen(&(t->stack->name)));
1708                         //t->dirname_length = t->path_length;
1709                         //tree_pop(t);
1710                         t->stack->flags &= ~needsFirstVisit;
1711                         return (t->visit_type = TREE_REGULAR);
1712                 } else if (t->stack->flags & needsDescent) {
1713                         /* Top stack item is dir to descend into. */
1714                         t->current = t->stack;
1715                         tree_append(t, t->stack->name.s,
1716                             archive_strlen(&(t->stack->name)));
1717                         t->stack->flags &= ~needsDescent;
1718                         r = tree_descent(t);
1719                         if (r != 0) {
1720                                 tree_pop(t);
1721                                 t->visit_type = r;
1722                         } else
1723                                 t->visit_type = TREE_POSTDESCENT;
1724                         return (t->visit_type);
1725                 } else if (t->stack->flags & needsOpen) {
1726                         t->stack->flags &= ~needsOpen;
1727                         r = tree_dir_next_windows(t, L"*");
1728                         if (r == 0)
1729                                 continue;
1730                         return (r);
1731                 } else if (t->stack->flags & needsAscent) {
1732                         /* Top stack item is dir and we're done with it. */
1733                         r = tree_ascend(t);
1734                         tree_pop(t);
1735                         t->visit_type = r != 0 ? r : TREE_POSTASCENT;
1736                         return (t->visit_type);
1737                 } else {
1738                         /* Top item on stack is dead. */
1739                         tree_pop(t);
1740                         t->flags &= ~hasLstat;
1741                         t->flags &= ~hasStat;
1742                 }
1743         }
1744         return (t->visit_type = 0);
1745 }
1746
1747 static int
1748 tree_dir_next_windows(struct tree *t, const wchar_t *pattern)
1749 {
1750         const wchar_t *name;
1751         size_t namelen;
1752         int r;
1753
1754         for (;;) {
1755                 if (pattern != NULL) {
1756                         struct archive_wstring pt;
1757
1758                         archive_string_init(&pt);
1759                         archive_wstring_ensure(&pt,
1760                             archive_strlen(&(t->full_path))
1761                               + 2 + wcslen(pattern));
1762                         archive_wstring_copy(&pt, &(t->full_path));
1763                         archive_wstrappend_wchar(&pt, L'\\');
1764                         archive_wstrcat(&pt, pattern);
1765                         t->d = FindFirstFileW(pt.s, &t->_findData);
1766                         archive_wstring_free(&pt);
1767                         if (t->d == INVALID_HANDLE_VALUE) {
1768                                 la_dosmaperr(GetLastError());
1769                                 t->tree_errno = errno;
1770                                 r = tree_ascend(t); /* Undo "chdir" */
1771                                 tree_pop(t);
1772                                 t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
1773                                 return (t->visit_type);
1774                         }
1775                         t->findData = &t->_findData;
1776                         pattern = NULL;
1777                 } else if (!FindNextFileW(t->d, &t->_findData)) {
1778                         FindClose(t->d);
1779                         t->d = INVALID_HANDLE_VALUE;
1780                         t->findData = NULL;
1781                         return (0);
1782                 }
1783                 name = t->findData->cFileName;
1784                 namelen = wcslen(name);
1785                 t->flags &= ~hasLstat;
1786                 t->flags &= ~hasStat;
1787                 if (name[0] == L'.' && name[1] == L'\0')
1788                         continue;
1789                 if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0')
1790                         continue;
1791                 tree_append(t, name, namelen);
1792                 return (t->visit_type = TREE_REGULAR);
1793         }
1794 }
1795
1796 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1797 static void
1798 fileTimeToUtc(const FILETIME *filetime, time_t *t, long *ns)
1799 {
1800         ULARGE_INTEGER utc;
1801
1802         utc.HighPart = filetime->dwHighDateTime;
1803         utc.LowPart  = filetime->dwLowDateTime;
1804         if (utc.QuadPart >= EPOC_TIME) {
1805                 utc.QuadPart -= EPOC_TIME;
1806                 /* milli seconds base */
1807                 *t = (time_t)(utc.QuadPart / 10000000);
1808                 /* nano seconds base */
1809                 *ns = (long)(utc.QuadPart % 10000000) * 100;
1810         } else {
1811                 *t = 0;
1812                 *ns = 0;
1813         }
1814 }
1815
1816 static void
1817 entry_copy_bhfi(struct archive_entry *entry, const wchar_t *path,
1818         const WIN32_FIND_DATAW *findData,
1819         const BY_HANDLE_FILE_INFORMATION *bhfi)
1820 {
1821         time_t secs;
1822         long nsecs;
1823         mode_t mode;
1824
1825         fileTimeToUtc(&bhfi->ftLastAccessTime, &secs, &nsecs);
1826         archive_entry_set_atime(entry, secs, nsecs);
1827         fileTimeToUtc(&bhfi->ftLastWriteTime, &secs, &nsecs);
1828         archive_entry_set_mtime(entry, secs, nsecs);
1829         fileTimeToUtc(&bhfi->ftCreationTime, &secs, &nsecs);
1830         archive_entry_set_birthtime(entry, secs, nsecs);
1831         archive_entry_set_ctime(entry, secs, nsecs);
1832         archive_entry_set_dev(entry, bhfi_dev(bhfi));
1833         archive_entry_set_ino64(entry, bhfi_ino(bhfi));
1834         if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1835                 archive_entry_set_nlink(entry, bhfi->nNumberOfLinks + 1);
1836         else
1837                 archive_entry_set_nlink(entry, bhfi->nNumberOfLinks);
1838         archive_entry_set_size(entry,
1839             (((int64_t)bhfi->nFileSizeHigh) << 32)
1840             + bhfi->nFileSizeLow);
1841         archive_entry_set_uid(entry, 0);
1842         archive_entry_set_gid(entry, 0);
1843         archive_entry_set_rdev(entry, 0);
1844
1845         mode = S_IRUSR | S_IRGRP | S_IROTH;
1846         if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
1847                 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
1848         if ((bhfi->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
1849             findData != NULL &&
1850             findData->dwReserved0 == IO_REPARSE_TAG_SYMLINK)
1851                 mode |= S_IFLNK;
1852         else if (bhfi->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1853                 mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
1854         else {
1855                 const wchar_t *p;
1856
1857                 mode |= S_IFREG;
1858                 p = wcsrchr(path, L'.');
1859                 if (p != NULL && wcslen(p) == 4) {
1860                         switch (p[1]) {
1861                         case L'B': case L'b':
1862                                 if ((p[2] == L'A' || p[2] == L'a' ) &&
1863                                     (p[3] == L'T' || p[3] == L't' ))
1864                                         mode |= S_IXUSR | S_IXGRP | S_IXOTH;
1865                                 break;
1866                         case L'C': case L'c':
1867                                 if (((p[2] == L'M' || p[2] == L'm' ) &&
1868                                     (p[3] == L'D' || p[3] == L'd' )))
1869                                         mode |= S_IXUSR | S_IXGRP | S_IXOTH;
1870                                 break;
1871                         case L'E': case L'e':
1872                                 if ((p[2] == L'X' || p[2] == L'x' ) &&
1873                                     (p[3] == L'E' || p[3] == L'e' ))
1874                                         mode |= S_IXUSR | S_IXGRP | S_IXOTH;
1875                                 break;
1876                         default:
1877                                 break;
1878                         }
1879                 }
1880         }
1881         archive_entry_set_mode(entry, mode);
1882 }
1883
1884 static void
1885 tree_archive_entry_copy_bhfi(struct archive_entry *entry, struct tree *t,
1886         const BY_HANDLE_FILE_INFORMATION *bhfi)
1887 {
1888         entry_copy_bhfi(entry, tree_current_path(t), t->findData, bhfi);
1889 }
1890
1891 static int
1892 tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
1893  int sim_lstat)
1894 {
1895         HANDLE h;
1896         int r;
1897         DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
1898         
1899         if (sim_lstat && tree_current_is_physical_link(t))
1900                 flag |= FILE_FLAG_OPEN_REPARSE_POINT;
1901         h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
1902             OPEN_EXISTING, flag, NULL);
1903         if (h == INVALID_HANDLE_VALUE) {
1904                 la_dosmaperr(GetLastError());
1905                 t->tree_errno = errno;
1906                 return (0);
1907         }
1908         r = GetFileInformationByHandle(h, st);
1909         CloseHandle(h);
1910         return (r);
1911 }
1912
1913 /*
1914  * Get the stat() data for the entry just returned from tree_next().
1915  */
1916 static const BY_HANDLE_FILE_INFORMATION *
1917 tree_current_stat(struct tree *t)
1918 {
1919         if (!(t->flags & hasStat)) {
1920                 if (!tree_current_file_information(t, &t->st, 0))
1921                         return NULL;
1922                 t->flags |= hasStat;
1923         }
1924         return (&t->st);
1925 }
1926
1927 /*
1928  * Get the lstat() data for the entry just returned from tree_next().
1929  */
1930 static const BY_HANDLE_FILE_INFORMATION *
1931 tree_current_lstat(struct tree *t)
1932 {
1933         if (!(t->flags & hasLstat)) {
1934                 if (!tree_current_file_information(t, &t->lst, 1))
1935                         return NULL;
1936                 t->flags |= hasLstat;
1937         }
1938         return (&t->lst);
1939 }
1940
1941 /*
1942  * Test whether current entry is a dir or link to a dir.
1943  */
1944 static int
1945 tree_current_is_dir(struct tree *t)
1946 {
1947         if (t->findData)
1948                 return (t->findData->dwFileAttributes
1949                     & FILE_ATTRIBUTE_DIRECTORY);
1950         return (0);
1951 }
1952
1953 /*
1954  * Test whether current entry is a physical directory.  Usually, we
1955  * already have at least one of stat() or lstat() in memory, so we
1956  * use tricks to try to avoid an extra trip to the disk.
1957  */
1958 static int
1959 tree_current_is_physical_dir(struct tree *t)
1960 {
1961         if (tree_current_is_physical_link(t))
1962                 return (0);
1963         return (tree_current_is_dir(t));
1964 }
1965
1966 /*
1967  * Test whether current entry is a symbolic link.
1968  */
1969 static int
1970 tree_current_is_physical_link(struct tree *t)
1971 {
1972         if (t->findData)
1973                 return ((t->findData->dwFileAttributes
1974                                 & FILE_ATTRIBUTE_REPARSE_POINT) &&
1975                         (t->findData->dwReserved0
1976                             == IO_REPARSE_TAG_SYMLINK));
1977         return (0);
1978 }
1979
1980 /*
1981  * Test whether the same file has been in the tree as its parent.
1982  */
1983 static int
1984 tree_target_is_same_as_parent(struct tree *t,
1985     const BY_HANDLE_FILE_INFORMATION *st)
1986 {
1987         struct tree_entry *te;
1988         int64_t dev = bhfi_dev(st);
1989         int64_t ino = bhfi_ino(st);
1990
1991         for (te = t->current->parent; te != NULL; te = te->parent) {
1992                 if (te->dev == dev && te->ino == ino)
1993                         return (1);
1994         }
1995         return (0);
1996 }
1997
1998 /*
1999  * Return the access path for the entry just returned from tree_next().
2000  */
2001 static const wchar_t *
2002 tree_current_access_path(struct tree *t)
2003 {
2004         return (t->full_path.s);
2005 }
2006
2007 /*
2008  * Return the full path for the entry just returned from tree_next().
2009  */
2010 static const wchar_t *
2011 tree_current_path(struct tree *t)
2012 {
2013         return (t->path.s);
2014 }
2015
2016 /*
2017  * Terminate the traversal.
2018  */
2019 static void
2020 tree_close(struct tree *t)
2021 {
2022
2023         if (t == NULL)
2024                 return;
2025         if (t->entry_fh != INVALID_HANDLE_VALUE) {
2026                 cancel_async(t);
2027                 close_and_restore_time(t->entry_fh, t, &t->restore_time);
2028                 t->entry_fh = INVALID_HANDLE_VALUE;
2029         }
2030         /* Close the handle of FindFirstFileW */
2031         if (t->d != INVALID_HANDLE_VALUE) {
2032                 FindClose(t->d);
2033                 t->d = INVALID_HANDLE_VALUE;
2034                 t->findData = NULL;
2035         }
2036         /* Release anything remaining in the stack. */
2037         while (t->stack != NULL)
2038                 tree_pop(t);
2039 }
2040
2041 /*
2042  * Release any resources.
2043  */
2044 static void
2045 tree_free(struct tree *t)
2046 {
2047         int i;
2048
2049         if (t == NULL)
2050                 return;
2051         archive_wstring_free(&t->path);
2052         archive_wstring_free(&t->full_path);
2053         free(t->sparse_list);
2054         free(t->filesystem_table);
2055         for (i = 0; i < MAX_OVERLAPPED; i++) {
2056                 if (t->ol[i].buff)
2057                         VirtualFree(t->ol[i].buff, 0, MEM_RELEASE);
2058                 CloseHandle(t->ol[i].ol.hEvent);
2059         }
2060         free(t);
2061 }
2062
2063
2064 /*
2065  * Populate the archive_entry with metadata from the disk.
2066  */
2067 int
2068 archive_read_disk_entry_from_file(struct archive *_a,
2069     struct archive_entry *entry, int fd, const struct stat *st)
2070 {
2071         struct archive_read_disk *a = (struct archive_read_disk *)_a;
2072         const wchar_t *path;
2073         const wchar_t *wname;
2074         const char *name;
2075         HANDLE h;
2076         BY_HANDLE_FILE_INFORMATION bhfi;
2077         DWORD fileAttributes = 0;
2078         int r;
2079
2080         archive_clear_error(_a);
2081         wname = archive_entry_sourcepath_w(entry);
2082         if (wname == NULL)
2083                 wname = archive_entry_pathname_w(entry);
2084         if (wname == NULL) {
2085                 archive_set_error(&a->archive, EINVAL,
2086                     "Can't get a wide character version of the path");
2087                 return (ARCHIVE_FAILED);
2088         }
2089         path = __la_win_permissive_name_w(wname);
2090
2091         if (st == NULL) {
2092                 /*
2093                  * Get metadata through GetFileInformationByHandle().
2094                  */
2095                 if (fd >= 0) {
2096                         h = (HANDLE)_get_osfhandle(fd);
2097                         r = GetFileInformationByHandle(h, &bhfi);
2098                         if (r == 0) {
2099                                 la_dosmaperr(GetLastError());
2100                                 archive_set_error(&a->archive, errno,
2101                                     "Can't GetFileInformationByHandle");
2102                                 return (ARCHIVE_FAILED);
2103                         }
2104                         entry_copy_bhfi(entry, path, NULL, &bhfi);
2105                 } else {
2106                         WIN32_FIND_DATAW findData;
2107                         DWORD flag, desiredAccess;
2108         
2109                         h = FindFirstFileW(path, &findData);
2110                         if (h == INVALID_HANDLE_VALUE) {
2111                                 la_dosmaperr(GetLastError());
2112                                 archive_set_error(&a->archive, errno,
2113                                     "Can't FindFirstFileW");
2114                                 return (ARCHIVE_FAILED);
2115                         }
2116                         FindClose(h);
2117
2118                         flag = FILE_FLAG_BACKUP_SEMANTICS;
2119                         if (!a->follow_symlinks &&
2120                             (findData.dwFileAttributes
2121                               & FILE_ATTRIBUTE_REPARSE_POINT) &&
2122                                   (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
2123                                 flag |= FILE_FLAG_OPEN_REPARSE_POINT;
2124                                 desiredAccess = 0;
2125                         } else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
2126                                 desiredAccess = 0;
2127                         } else
2128                                 desiredAccess = GENERIC_READ;
2129
2130                         h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
2131                             OPEN_EXISTING, flag, NULL);
2132                         if (h == INVALID_HANDLE_VALUE) {
2133                                 la_dosmaperr(GetLastError());
2134                                 archive_set_error(&a->archive, errno,
2135                                     "Can't CreateFileW");
2136                                 return (ARCHIVE_FAILED);
2137                         }
2138                         r = GetFileInformationByHandle(h, &bhfi);
2139                         if (r == 0) {
2140                                 la_dosmaperr(GetLastError());
2141                                 archive_set_error(&a->archive, errno,
2142                                     "Can't GetFileInformationByHandle");
2143                                 CloseHandle(h);
2144                                 return (ARCHIVE_FAILED);
2145                         }
2146                         entry_copy_bhfi(entry, path, &findData, &bhfi);
2147                 }
2148                 fileAttributes = bhfi.dwFileAttributes;
2149         } else {
2150                 archive_entry_copy_stat(entry, st);
2151                 h = INVALID_HANDLE_VALUE;
2152         }
2153
2154         /* Lookup uname/gname */
2155         name = archive_read_disk_uname(_a, archive_entry_uid(entry));
2156         if (name != NULL)
2157                 archive_entry_copy_uname(entry, name);
2158         name = archive_read_disk_gname(_a, archive_entry_gid(entry));
2159         if (name != NULL)
2160                 archive_entry_copy_gname(entry, name);
2161
2162         /*
2163          * Can this file be sparse file ?
2164          */
2165         if (archive_entry_filetype(entry) != AE_IFREG
2166             || archive_entry_size(entry) <= 0
2167                 || archive_entry_hardlink(entry) != NULL) {
2168                 if (h != INVALID_HANDLE_VALUE && fd < 0)
2169                         CloseHandle(h);
2170                 return (ARCHIVE_OK);
2171         }
2172
2173         if (h == INVALID_HANDLE_VALUE) {
2174                 if (fd >= 0) {
2175                         h = (HANDLE)_get_osfhandle(fd);
2176                 } else {
2177                         h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
2178                             OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2179                         if (h == INVALID_HANDLE_VALUE) {
2180                                 la_dosmaperr(GetLastError());
2181                                 archive_set_error(&a->archive, errno,
2182                                     "Can't CreateFileW");
2183                                 return (ARCHIVE_FAILED);
2184                         }
2185                 }
2186                 r = GetFileInformationByHandle(h, &bhfi);
2187                 if (r == 0) {
2188                         la_dosmaperr(GetLastError());
2189                         archive_set_error(&a->archive, errno,
2190                             "Can't GetFileInformationByHandle");
2191                         if (h != INVALID_HANDLE_VALUE && fd < 0)
2192                                 CloseHandle(h);
2193                         return (ARCHIVE_FAILED);
2194                 }
2195                 fileAttributes = bhfi.dwFileAttributes;
2196         }
2197
2198         /* Sparse file must be set a mark, FILE_ATTRIBUTE_SPARSE_FILE */
2199         if ((fileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
2200                 if (fd < 0)
2201                         CloseHandle(h);
2202                 return (ARCHIVE_OK);
2203         }
2204
2205         r = setup_sparse_from_disk(a, entry, h);
2206         if (fd < 0)
2207                 CloseHandle(h);
2208
2209         return (r);
2210 }
2211
2212 /*
2213  * Windows sparse interface.
2214  */
2215 #if defined(__MINGW32__) && !defined(FSCTL_QUERY_ALLOCATED_RANGES)
2216 #define FSCTL_QUERY_ALLOCATED_RANGES 0x940CF
2217 typedef struct {
2218         LARGE_INTEGER FileOffset;
2219         LARGE_INTEGER Length;
2220 } FILE_ALLOCATED_RANGE_BUFFER;
2221 #endif
2222
2223 static int
2224 setup_sparse_from_disk(struct archive_read_disk *a,
2225     struct archive_entry *entry, HANDLE handle)
2226 {
2227         FILE_ALLOCATED_RANGE_BUFFER range, *outranges = NULL;
2228         size_t outranges_size;
2229         int64_t entry_size = archive_entry_size(entry);
2230         int exit_sts = ARCHIVE_OK;
2231
2232         range.FileOffset.QuadPart = 0;
2233         range.Length.QuadPart = entry_size;
2234         outranges_size = 2048;
2235         outranges = (FILE_ALLOCATED_RANGE_BUFFER *)malloc(outranges_size);
2236         if (outranges == NULL) {
2237                 archive_set_error(&a->archive, ENOMEM,
2238                         "Couldn't allocate memory");
2239                 exit_sts = ARCHIVE_FATAL;
2240                 goto exit_setup_sparse;
2241         }
2242
2243         for (;;) {
2244                 DWORD retbytes;
2245                 BOOL ret;
2246
2247                 for (;;) {
2248                         ret = DeviceIoControl(handle,
2249                             FSCTL_QUERY_ALLOCATED_RANGES,
2250                             &range, sizeof(range), outranges,
2251                             (DWORD)outranges_size, &retbytes, NULL);
2252                         if (ret == 0 && GetLastError() == ERROR_MORE_DATA) {
2253                                 free(outranges);
2254                                 outranges_size *= 2;
2255                                 outranges = (FILE_ALLOCATED_RANGE_BUFFER *)
2256                                     malloc(outranges_size);
2257                                 if (outranges == NULL) {
2258                                         archive_set_error(&a->archive, ENOMEM,
2259                                             "Couldn't allocate memory");
2260                                         exit_sts = ARCHIVE_FATAL;
2261                                         goto exit_setup_sparse;
2262                                 }
2263                                 continue;
2264                         } else
2265                                 break;
2266                 }
2267                 if (ret != 0) {
2268                         if (retbytes > 0) {
2269                                 DWORD i, n;
2270
2271                                 n = retbytes / sizeof(outranges[0]);
2272                                 if (n == 1 &&
2273                                     outranges[0].FileOffset.QuadPart == 0 &&
2274                                     outranges[0].Length.QuadPart == entry_size)
2275                                         break;/* This is not sparse. */
2276                                 for (i = 0; i < n; i++)
2277                                         archive_entry_sparse_add_entry(entry,
2278                                             outranges[i].FileOffset.QuadPart,
2279                                                 outranges[i].Length.QuadPart);
2280                                 range.FileOffset.QuadPart =
2281                                     outranges[n-1].FileOffset.QuadPart
2282                                     + outranges[n-1].Length.QuadPart;
2283                                 range.Length.QuadPart =
2284                                     entry_size - range.FileOffset.QuadPart;
2285                                 if (range.Length.QuadPart > 0)
2286                                         continue;
2287                         } else {
2288                                 /* The remaining data is hole. */
2289                                 archive_entry_sparse_add_entry(entry,
2290                                     range.FileOffset.QuadPart,
2291                                     range.Length.QuadPart);
2292                         }
2293                         break;
2294                 } else {
2295                         la_dosmaperr(GetLastError());
2296                         archive_set_error(&a->archive, errno,
2297                             "DeviceIoControl Failed: %lu", GetLastError());
2298                         exit_sts = ARCHIVE_FAILED;
2299                         goto exit_setup_sparse;
2300                 }
2301         }
2302 exit_setup_sparse:
2303         free(outranges);
2304
2305         return (exit_sts);
2306 }
2307
2308 #endif