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