]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/attribs.c
cygwin_conv with length check
[bacula/bacula] / bacula / src / findlib / attribs.c
1 /*
2  *  Encode and decode standard Unix attributes and
3  *   Extended attributes for Win32 and
4  *   other non-Unix systems, or Unix systems with ACLs, ...
5  *
6  *    Kern Sibbald, October MMII
7  *
8  *   Version $Id$
9  *
10  */
11 /*
12    Copyright (C) 2002-2005 Kern Sibbald
13
14    This program is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of
17    the License, or (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22    General Public License for more details.
23
24    You should have received a copy of the GNU General Public
25    License along with this program; if not, write to the Free
26    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27    MA 02111-1307, USA.
28
29  */
30
31 #include "bacula.h"
32 #include "find.h"
33
34 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
35
36 #include "../lib/winapi.h"
37
38
39 /* Forward referenced subroutines */
40 static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd);
41 void unix_name_to_win32(POOLMEM **win32_name, char *name);
42 void win_error(JCR *jcr, char *prefix, POOLMEM *ofile);
43 HANDLE bget_handle(BFILE *bfd);
44 #endif
45
46 /* For old systems that don't have lchown() use chown() */
47 #ifndef HAVE_LCHOWN
48 #define lchown chown
49 #endif
50
51 /*=============================================================*/
52 /*                                                             */
53 /*             ***  A l l  S y s t e m s ***                   */
54 /*                                                             */
55 /*=============================================================*/
56
57 /*
58  * Return the data stream that will be used
59  */
60 int select_data_stream(FF_PKT *ff_pkt)
61 {
62    int stream;
63
64    /* Note, no sparse option for win32_data */
65    if (!is_portable_backup(&ff_pkt->bfd)) {
66       stream = STREAM_WIN32_DATA;
67       ff_pkt->flags &= ~FO_SPARSE;
68    } else if (ff_pkt->flags & FO_SPARSE) {
69       stream = STREAM_SPARSE_DATA;
70    } else {
71       stream = STREAM_FILE_DATA;
72    }
73 #ifdef HAVE_LIBZ
74    if (ff_pkt->flags & FO_GZIP) {
75       if (stream == STREAM_WIN32_DATA) {
76          stream = STREAM_WIN32_GZIP_DATA;
77       } else if (stream == STREAM_FILE_DATA) {
78          stream = STREAM_GZIP_DATA;
79       } else {
80          stream = STREAM_SPARSE_GZIP_DATA;
81       }
82    }
83 #endif
84    return stream;
85 }
86
87
88 /*
89  * Encode a stat structure into a base64 character string
90  *   All systems must create such a structure.
91  *   In addition, we tack on the LinkFI, which is non-zero in
92  *   the case of a hard linked file that has no data.  This
93  *   is a File Index pointing to the link that does have the
94  *   data (always the first one encountered in a save).
95  * You may piggyback attributes on this packet by encoding
96  *   them in the encode_attribsEx() subroutine, but this is
97  *   not recommended.
98  */
99 void encode_stat(char *buf, FF_PKT *ff_pkt, int data_stream)
100 {
101    char *p = buf;
102    struct stat *statp = &ff_pkt->statp;
103    /*
104     *  Encode a stat packet.  I should have done this more intelligently
105     *   with a length so that it could be easily expanded.
106     */
107    p += to_base64((int64_t)statp->st_dev, p);
108    *p++ = ' ';                        /* separate fields with a space */
109    p += to_base64((int64_t)statp->st_ino, p);
110    *p++ = ' ';
111    p += to_base64((int64_t)statp->st_mode, p);
112    *p++ = ' ';
113    p += to_base64((int64_t)statp->st_nlink, p);
114    *p++ = ' ';
115    p += to_base64((int64_t)statp->st_uid, p);
116    *p++ = ' ';
117    p += to_base64((int64_t)statp->st_gid, p);
118    *p++ = ' ';
119    p += to_base64((int64_t)statp->st_rdev, p);
120    *p++ = ' ';
121    p += to_base64((int64_t)statp->st_size, p);
122    *p++ = ' ';
123 #ifndef HAVE_MINGW
124    p += to_base64((int64_t)statp->st_blksize, p);
125    *p++ = ' ';
126    p += to_base64((int64_t)statp->st_blocks, p);
127    *p++ = ' ';
128 #else
129    p += to_base64((int64_t)0, p); /* output place holder */
130    *p++ = ' ';
131    p += to_base64((int64_t)0, p); /* output place holder */
132    *p++ = ' ';
133 #endif
134    p += to_base64((int64_t)statp->st_atime, p);
135    *p++ = ' ';
136    p += to_base64((int64_t)statp->st_mtime, p);
137    *p++ = ' ';
138    p += to_base64((int64_t)statp->st_ctime, p);
139    *p++ = ' ';
140    p += to_base64((int64_t)ff_pkt->LinkFI, p);
141    *p++ = ' ';
142
143 #ifdef HAVE_CHFLAGS
144    /* FreeBSD function */
145    p += to_base64((int64_t)statp->st_flags, p);  /* output st_flags */
146 #else
147    p += to_base64((int64_t)0, p);     /* output place holder */
148 #endif
149    *p++ = ' ';
150    p += to_base64((int64_t)data_stream, p);
151    *p = 0;
152    return;
153 }
154
155
156 /* Do casting according to unknown type to keep compiler happy */
157 #if !HAVE_GCC & HAVE_SUN_OS
158 #define plug(st, val) st = val        /* brain damaged compiler */
159 #else
160 template <class T> void plug(T &st, uint64_t val)
161     { st = static_cast<T>(val); }
162 #endif
163
164
165 /* Decode a stat packet from base64 characters */
166 int decode_stat(char *buf, struct stat *statp, int32_t *LinkFI)
167 {
168    char *p = buf;
169    int64_t val;
170
171    p += from_base64(&val, p);
172    plug(statp->st_dev, val);
173    p++;
174    p += from_base64(&val, p);
175    plug(statp->st_ino, val);
176    p++;
177    p += from_base64(&val, p);
178    plug(statp->st_mode, val);
179    p++;
180    p += from_base64(&val, p);
181    plug(statp->st_nlink, val);
182    p++;
183    p += from_base64(&val, p);
184    plug(statp->st_uid, val);
185    p++;
186    p += from_base64(&val, p);
187    plug(statp->st_gid, val);
188    p++;
189    p += from_base64(&val, p);
190    plug(statp->st_rdev, val);
191    p++;
192    p += from_base64(&val, p);
193    plug(statp->st_size, val);
194    p++;
195 #ifndef HAVE_MINGW
196    p += from_base64(&val, p);
197    plug(statp->st_blksize, val);
198    p++;
199    p += from_base64(&val, p);
200    plug(statp->st_blocks, val);
201    p++;
202 #else
203    p += from_base64(&val, p);
204 //   plug(statp->st_blksize, val);
205    p++;
206    p += from_base64(&val, p);
207 //   plug(statp->st_blocks, val);
208    p++;
209 #endif
210    p += from_base64(&val, p);
211    plug(statp->st_atime, val);
212    p++;
213    p += from_base64(&val, p);
214    plug(statp->st_mtime, val);
215    p++;
216    p += from_base64(&val, p);
217    plug(statp->st_ctime, val);
218
219    /* Optional FileIndex of hard linked file data */
220    if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
221       p++;
222       p += from_base64(&val, p);
223       *LinkFI = (uint32_t)val;
224    } else {
225       *LinkFI = 0;
226       return 0;
227    }
228
229    /* FreeBSD user flags */
230    if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
231       p++;
232       p += from_base64(&val, p);
233 #ifdef HAVE_CHFLAGS
234       plug(statp->st_flags, val);
235    } else {
236       statp->st_flags  = 0;
237 #endif
238    }
239
240    /* Look for data stream id */
241    if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
242       p++;
243       p += from_base64(&val, p);
244    } else {
245       val = 0;
246    }
247    return (int)val;
248 }
249
250 /* Decode a LinkFI field of encoded stat packet */
251 int32_t decode_LinkFI(char *buf, struct stat *statp)
252 {
253    char *p = buf;
254    int64_t val;
255
256    skip_nonspaces(&p);                /* st_dev */
257    p++;                               /* skip space */
258    skip_nonspaces(&p);                /* st_ino */
259    p++;
260    p += from_base64(&val, p);
261    plug(statp->st_mode, val);         /* st_mode */
262    p++;
263    skip_nonspaces(&p);                /* st_nlink */
264    p++;
265    skip_nonspaces(&p);                /* st_uid */
266    p++;
267    skip_nonspaces(&p);                /* st_gid */
268    p++;
269    skip_nonspaces(&p);                /* st_rdev */
270    p++;
271    skip_nonspaces(&p);                /* st_size */
272    p++;
273    skip_nonspaces(&p);                /* st_blksize */
274    p++;
275    skip_nonspaces(&p);                /* st_blocks */
276    p++;
277    skip_nonspaces(&p);                /* st_atime */
278    p++;
279    skip_nonspaces(&p);                /* st_mtime */
280    p++;
281    skip_nonspaces(&p);                /* st_ctime */
282
283    /* Optional FileIndex of hard linked file data */
284    if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
285       p++;
286       p += from_base64(&val, p);
287       return (int32_t)val;
288    }
289    return 0;
290 }
291
292 /*
293  * Set file modes, permissions and times
294  *
295  *  fname is the original filename
296  *  ofile is the output filename (may be in a different directory)
297  *
298  * Returns:  true  on success
299  *           false on failure
300  */
301 bool set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
302 {
303    struct utimbuf ut;
304    mode_t old_mask;
305    bool ok = true;
306    off_t fsize;
307
308 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
309    if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX &&
310        set_win32_attributes(jcr, attr, ofd)) {
311        if (is_bopen(ofd)) {
312            bclose(ofd);
313        }
314        pm_strcpy(attr->ofname, "*none*");
315        return true;
316    }
317    if (attr->data_stream == STREAM_WIN32_DATA ||
318        attr->data_stream == STREAM_WIN32_GZIP_DATA) {
319       if (is_bopen(ofd)) {
320          bclose(ofd);
321       }
322       pm_strcpy(attr->ofname, "*none*");
323       return true;
324    }
325
326
327    /*
328     * If Windows stuff failed, e.g. attempt to restore Unix file
329     *  to Windows, simply fall through and we will do it the
330     *  universal way.
331     */
332 #endif
333
334    old_mask = umask(0);
335    if (is_bopen(ofd)) {
336       char ec1[50], ec2[50];
337       fsize = blseek(ofd, 0, SEEK_CUR);
338       bclose(ofd);                    /* first close file */
339       if (fsize > 0 && fsize != (off_t)attr->statp.st_size) {
340          Jmsg3(jcr, M_ERROR, 0, _("File size of restored file %s not correct. Original %s, restored %s.\n"),
341             attr->ofname, edit_uint64(attr->statp.st_size, ec1),
342             edit_uint64(fsize, ec2));
343       }
344    }
345
346    ut.actime = attr->statp.st_atime;
347    ut.modtime = attr->statp.st_mtime;
348
349    /* ***FIXME**** optimize -- don't do if already correct */
350    /*
351     * For link, change owner of link using lchown, but don't
352     *   try to do a chmod as that will update the file behind it.
353     */
354    if (attr->type == FT_LNK) {
355       /* Change owner of link, not of real file */
356       if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
357          berrno be;
358          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
359             attr->ofname, be.strerror());
360          ok = false;
361       }
362    } else {
363       if (chown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
364          berrno be;
365          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
366             attr->ofname, be.strerror());
367          ok = false;
368       }
369       if (chmod(attr->ofname, attr->statp.st_mode) < 0) {
370          berrno be;
371          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"),
372             attr->ofname, be.strerror());
373          ok = false;
374       }
375
376       /*
377        * Reset file times.
378        */
379       if (utime(attr->ofname, &ut) < 0) {
380          berrno be;
381          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file times %s: ERR=%s\n"),
382             attr->ofname, be.strerror());
383          ok = false;
384       }
385 #ifdef HAVE_CHFLAGS
386       /*
387        * FreeBSD user flags
388        *
389        * Note, this should really be done before the utime() above,
390        *  but if the immutable bit is set, it will make the utimes()
391        *  fail.
392        */
393       if (chflags(attr->ofname, attr->statp.st_flags) < 0) {
394          berrno be;
395          Jmsg2(jcr, M_ERROR, 0, _("Unable to set file flags %s: ERR=%s\n"),
396             attr->ofname, be.strerror());
397          ok = false;
398       }
399 #endif
400    }
401    pm_strcpy(attr->ofname, "*none*");
402    umask(old_mask);
403    return ok;
404 }
405
406
407 /*=============================================================*/
408 /*                                                             */
409 /*                 * * *  U n i x * * * *                      */
410 /*                                                             */
411 /*=============================================================*/
412
413 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
414
415 /*
416  * It is possible to piggyback additional data e.g. ACLs on
417  *   the encode_stat() data by returning the extended attributes
418  *   here.  They must be "self-contained" (i.e. you keep track
419  *   of your own length), and they must be in ASCII string
420  *   format. Using this feature is not recommended.
421  * The code below shows how to return nothing.  See the Win32
422  *   code below for returning something in the attributes.
423  */
424 int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
425 {
426 #ifdef HAVE_DARWIN_OS
427    /*
428     * We save the Mac resource fork length so that on a
429     * restore, we can be sure we put back the whole resource.
430     */
431    char *p;
432    p = attribsEx;
433    if (ff_pkt->flags & FO_HFSPLUS) {
434       p += to_base64((uint64_t)(ff_pkt->hfsinfo.rsrclength), p);
435    }
436    *p = 0;
437 #else
438    *attribsEx = 0;                    /* no extended attributes */
439 #endif
440    return STREAM_UNIX_ATTRIBUTES;
441 }
442
443 #endif
444
445
446
447 /*=============================================================*/
448 /*                                                             */
449 /*                 * * *  W i n 3 2 * * * *                    */
450 /*                                                             */
451 /*=============================================================*/
452
453 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
454
455 int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
456 {
457    char *p = attribsEx;
458    WIN32_FILE_ATTRIBUTE_DATA atts;
459    ULARGE_INTEGER li;
460
461    attribsEx[0] = 0;                  /* no extended attributes */
462
463    // try unicode version
464    if (p_GetFileAttributesExW)  {
465       unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname);
466
467       WCHAR szBuf[MAX_PATH_UNICODE];
468       UTF8_2_wchar(szBuf, ff_pkt->sys_fname, MAX_PATH_UNICODE);
469
470       if (!p_GetFileAttributesExW(szBuf, GetFileExInfoStandard,
471                               (LPVOID)&atts)) {
472          win_error(jcr, "GetFileAttributesExW:", ff_pkt->sys_fname);
473          return STREAM_UNIX_ATTRIBUTES;
474       }
475    }
476    else   {
477       if (!p_GetFileAttributesExA)
478          return STREAM_UNIX_ATTRIBUTES;
479
480       unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname);
481
482       if (!p_GetFileAttributesExA(ff_pkt->sys_fname, GetFileExInfoStandard,
483                               (LPVOID)&atts)) {
484          win_error(jcr, "GetFileAttributesExA:", ff_pkt->sys_fname);
485          return STREAM_UNIX_ATTRIBUTES;
486       }
487    }
488
489    p += to_base64((uint64_t)atts.dwFileAttributes, p);
490    *p++ = ' ';                        /* separate fields with a space */
491    li.LowPart = atts.ftCreationTime.dwLowDateTime;
492    li.HighPart = atts.ftCreationTime.dwHighDateTime;
493    p += to_base64((uint64_t)li.QuadPart, p);
494    *p++ = ' ';
495    li.LowPart = atts.ftLastAccessTime.dwLowDateTime;
496    li.HighPart = atts.ftLastAccessTime.dwHighDateTime;
497    p += to_base64((uint64_t)li.QuadPart, p);
498    *p++ = ' ';
499    li.LowPart = atts.ftLastWriteTime.dwLowDateTime;
500    li.HighPart = atts.ftLastWriteTime.dwHighDateTime;
501    p += to_base64((uint64_t)li.QuadPart, p);
502    *p++ = ' ';
503    p += to_base64((uint64_t)atts.nFileSizeHigh, p);
504    *p++ = ' ';
505    p += to_base64((uint64_t)atts.nFileSizeLow, p);
506    *p = 0;
507    return STREAM_UNIX_ATTRIBUTES_EX;
508 }
509
510 /* Define attributes that are legal to set with SetFileAttributes() */
511 #define SET_ATTRS ( \
512          FILE_ATTRIBUTE_ARCHIVE| \
513          FILE_ATTRIBUTE_HIDDEN| \
514          FILE_ATTRIBUTE_NORMAL| \
515          FILE_ATTRIBUTE_NOT_CONTENT_INDEXED| \
516          FILE_ATTRIBUTE_OFFLINE| \
517          FILE_ATTRIBUTE_READONLY| \
518          FILE_ATTRIBUTE_SYSTEM| \
519          FILE_ATTRIBUTE_TEMPORARY)
520
521
522 /*
523  * Set Extended File Attributes for Win32
524  *
525  *  fname is the original filename
526  *  ofile is the output filename (may be in a different directory)
527  *
528  * Returns:  true  on success
529  *           false on failure
530  */
531 static bool set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
532 {
533    char *p = attr->attrEx;
534    int64_t val;
535    WIN32_FILE_ATTRIBUTE_DATA atts;
536    ULARGE_INTEGER li;
537    POOLMEM *win32_ofile;
538
539    // if we have neither ansi nor wchar version, we leave
540    if (!(p_SetFileAttributesW || p_SetFileAttributesA))
541       return false;
542
543    if (!p || !*p) {                   /* we should have attributes */
544       Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid);
545       if (is_bopen(ofd)) {
546          bclose(ofd);
547       }
548       return false;
549    } else {
550       Dmsg2(100, "Attribs %s = %s\n", attr->ofname, attr->attrEx);
551    }
552
553    p += from_base64(&val, p);
554    plug(atts.dwFileAttributes, val);
555    p++;                               /* skip space */
556    p += from_base64(&val, p);
557    li.QuadPart = val;
558    atts.ftCreationTime.dwLowDateTime = li.LowPart;
559    atts.ftCreationTime.dwHighDateTime = li.HighPart;
560    p++;                               /* skip space */
561    p += from_base64(&val, p);
562    li.QuadPart = val;
563    atts.ftLastAccessTime.dwLowDateTime = li.LowPart;
564    atts.ftLastAccessTime.dwHighDateTime = li.HighPart;
565    p++;                               /* skip space */
566    p += from_base64(&val, p);
567    li.QuadPart = val;
568    atts.ftLastWriteTime.dwLowDateTime = li.LowPart;
569    atts.ftLastWriteTime.dwHighDateTime = li.HighPart;
570    p++;
571    p += from_base64(&val, p);
572    plug(atts.nFileSizeHigh, val);
573    p++;
574    p += from_base64(&val, p);
575    plug(atts.nFileSizeLow, val);
576
577    /* Convert to Windows path format */
578    win32_ofile = get_pool_memory(PM_FNAME);
579    unix_name_to_win32(&win32_ofile, attr->ofname);
580
581
582
583    /* At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */
584
585    if (!is_bopen(ofd)) {
586       Dmsg1(100, "File not open: %s\n", attr->ofname);
587       bopen(ofd, attr->ofname, O_WRONLY|O_BINARY, 0);   /* attempt to open the file */
588    }
589
590    if (is_bopen(ofd)) {
591       Dmsg1(100, "SetFileTime %s\n", attr->ofname);
592       if (!SetFileTime(bget_handle(ofd),
593                          &atts.ftCreationTime,
594                          &atts.ftLastAccessTime,
595                          &atts.ftLastWriteTime)) {
596          win_error(jcr, "SetFileTime:", win32_ofile);
597       }
598       bclose(ofd);
599    }
600
601    Dmsg1(100, "SetFileAtts %s\n", attr->ofname);
602    if (!(atts.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 
603    {
604       if (p_SetFileAttributesW) {
605    WCHAR szBuf[MAX_PATH_UNICODE];
606    UTF8_2_wchar(szBuf, win32_ofile, MAX_PATH_UNICODE);
607
608    if (!SetFileAttributesW(szBuf, atts.dwFileAttributes & SET_ATTRS)) {
609          win_error(jcr, "SetFileAttributesW:", win32_ofile);
610         }
611       }
612       else {
613       if (!SetFileAttributes(win32_ofile, atts.dwFileAttributes & SET_ATTRS)) {
614          win_error(jcr, "SetFileAttributesA:", win32_ofile);
615          }
616       }
617    }
618    free_pool_memory(win32_ofile);
619    return true;
620 }
621
622 void win_error(JCR *jcr, char *prefix, POOLMEM *win32_ofile)
623 {
624    DWORD lerror = GetLastError();
625    LPTSTR msg;
626    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
627                  FORMAT_MESSAGE_FROM_SYSTEM,
628                  NULL,
629                  lerror,
630                  0,
631                  (LPTSTR)&msg,
632                  0,
633                  NULL);
634    Dmsg3(100, "Error in %s on file %s: ERR=%s\n", prefix, win32_ofile, msg);
635    strip_trailing_junk(msg);
636    Jmsg(jcr, M_ERROR, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg);
637    LocalFree(msg);
638 }
639
640 void win_error(JCR *jcr, char *prefix, DWORD lerror)
641 {
642    LPTSTR msg;
643    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
644                  FORMAT_MESSAGE_FROM_SYSTEM,
645                  NULL,
646                  lerror,
647                  0,
648                  (LPTSTR)&msg,
649                  0,
650                  NULL);
651    strip_trailing_junk(msg);
652    if (jcr) {
653       Jmsg2(jcr, M_ERROR, 0, _("Error in %s: ERR=%s\n"), prefix, msg);
654    } else {
655       MessageBox(NULL, msg, prefix, MB_OK);
656    }
657    LocalFree(msg);
658 }
659
660
661 /* Cygwin API definition */
662 extern "C" void cygwin_conv_to_win32_path(const char *path, char *win32_path, DWORD dwSize);
663
664 void unix_name_to_win32(POOLMEM **win32_name, char *name)
665 {
666    /* One extra byte should suffice, but we double it */
667    /* add MAX_PATH bytes for VSS shadow copy name */
668    DWORD dwSize = 2*strlen(name)+MAX_PATH;
669    *win32_name = check_pool_memory_size(*win32_name, dwSize);
670    cygwin_conv_to_win32_path(name, *win32_name, dwSize);
671 }
672
673 #endif  /* HAVE_CYGWIN */