archive_read_disk_windows.c 67 KB

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