Changeset 2998 for trunk/src


Ignore:
Timestamp:
Nov 5, 2016, 8:37:35 PM (9 years ago)
Author:
bird
Message:

fts-nt.c: Wide char support, part 1.

Location:
trunk/src/lib/nt
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/nt/fts-nt.c

    r2992 r2998  
    8686#include "ntdir.h"
    8787
    88 static FTSENT   *fts_alloc(FTS *, char *, size_t);
     88static FTSENT   *fts_alloc(FTS *sp, char const *name, size_t namelen, wchar_t const *wcsname, size_t cwcname);
     89static FTSENT   *fts_alloc_ansi(FTS *sp, char const *name, size_t namelen);
     90static FTSENT   *fts_alloc_utf16(FTS *sp, wchar_t const *wcsname, size_t cwcname);
    8991static FTSENT   *fts_build(FTS *, int);
    9092static void      fts_lfree(FTSENT *);
    9193static void      fts_load(FTS *, FTSENT *);
    9294static size_t    fts_maxarglen(char * const *);
     95static size_t    fts_maxarglenw(wchar_t * const *);
    9396static void      fts_padjust(FTS *, FTSENT *);
    94 static int       fts_palloc(FTS *, size_t);
     97static void      fts_padjustw(FTS *, FTSENT *);
     98static int       fts_palloc(FTS *, size_t, size_t);
    9599static FTSENT   *fts_sort(FTS *, FTSENT *, size_t);
    96100static int       fts_stat(FTS *, FTSENT *, int, HANDLE);
     
    126130
    127131
    128 FTS * FTSCALL
    129 nt_fts_open(char * const *argv, int options,
     132static FTS * FTSCALL
     133nt_fts_open_common(char * const *argv, wchar_t * const *wcsargv, int options,
    130134    int (*compar)(const FTSENT * const *, const FTSENT * const *))
    131135{
     
    135139        FTSENT *parent, *tmp;
    136140        size_t len, nitems;
     141
     142    birdResolveImports();
    137143
    138144        /* Options check. */
     
    163169         * to hold the user's paths.
    164170         */
    165         if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
     171        if (fts_palloc(sp, MAX(argv ? fts_maxarglen(argv) : 1, MAXPATHLEN),
     172                                   MAX(wcsargv ? fts_maxarglenw(wcsargv) : 1, MAXPATHLEN)) )
    166173                goto mem1;
    167174
    168175        /* Allocate/initialize root's parent. */
    169         if ((parent = fts_alloc(sp, "", 0)) == NULL)
     176        if ((parent = fts_alloc(sp, NULL, 0, NULL, 0)) == NULL)
    170177                goto mem2;
    171178        parent->fts_level = FTS_ROOTPARENTLEVEL;
     
    177184                       appended so it won't matter if a slash is appended afterwards.
    178185                       2. DOS slashes are converted to UNIX ones. */
    179                 char *slash;
    180                 len = strlen(*argv);
    181                 if (len == 2 && argv[0][1] == ':') {
    182                         char tmp[4];
    183                         tmp[0] = argv[0][0];
    184                         tmp[1] = ':';
    185                         tmp[2] = '.';
    186                         tmp[3] = '\0';
    187                         p = fts_alloc(sp, tmp, 3);
     186                wchar_t *wcslash;
     187
     188                if (wcsargv) {
     189                        len = wcslen(*wcsargv);
     190                        if (len == 2 && wcsargv[0][1] == ':') {
     191                                wchar_t wcsdrive[4];
     192                                wcsdrive[0] = wcsargv[0][0];
     193                                wcsdrive[1] = ':';
     194                                wcsdrive[2] = '.';
     195                                wcsdrive[3] = '\0';
     196                                p = fts_alloc_utf16(sp, wcsdrive, 3);
     197                        } else {
     198                                p = fts_alloc_utf16(sp, *wcsargv, len);
     199                        }
    188200                } else {
    189                         p = fts_alloc(sp, *argv, len);
    190                 }
    191 #if 1 /* bird */
     201                        len = strlen(*argv);
     202                        if (len == 2 && argv[0][1] == ':') {
     203                                char szdrive[4];
     204                                szdrive[0] = argv[0][0];
     205                                szdrive[1] = ':';
     206                                szdrive[2] = '.';
     207                                szdrive[3] = '\0';
     208                                p = fts_alloc_ansi(sp, szdrive, 3);
     209                        } else {
     210                                p = fts_alloc_ansi(sp, *argv, len);
     211                        }
     212                }
    192213                if (p != NULL) { /* likely */ } else { goto mem3; }
    193 #endif
    194                 slash = strchr(p->fts_name, '\\');
    195                 while (slash != NULL) {
    196                         *slash++ = '/';
    197                         slash = strchr(p->fts_name, '\\');
    198                 }
     214
     215                wcslash = wcschr(p->fts_wcsname, '\\');
     216                while (wcslash != NULL) {
     217                        *wcslash++ = '/';
     218                        wcslash = wcschr(p->fts_wcsname, '\\');
     219                }
     220
     221                if (p->fts_name) {
     222                        char *slash = strchr(p->fts_name, '\\');
     223                        while (slash != NULL) {
     224                                *slash++ = '/';
     225                                slash = strchr(p->fts_name, '\\');
     226                        }
     227                }
     228
    199229                p->fts_level = FTS_ROOTLEVEL;
    200230                p->fts_parent = parent;
    201231                p->fts_accpath = p->fts_name;
     232                p->fts_wcsaccpath = p->fts_wcsname;
    202233                p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), INVALID_HANDLE_VALUE);
    203234
     
    231262         * so that everything about the "current" node is ignored.
    232263         */
    233         if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
     264        if ((sp->fts_cur = fts_alloc(sp, NULL, 0, NULL, 0)) == NULL)
    234265                goto mem3;
    235266        sp->fts_cur->fts_link = root;
     
    238269        return (sp);
    239270
    240 mem3:   fts_lfree(root);
     271mem3:
     272        fts_lfree(root);
    241273        free(parent);
    242 mem2:   free(sp->fts_path);
    243 mem1:   free(sp);
     274mem2:
     275        free(sp->fts_path);
     276        free(sp->fts_wcspath);
     277mem1:
     278        free(sp);
    244279        return (NULL);
    245280}
    246281
    247282
     283FTS * FTSCALL
     284nt_fts_open(char * const *argv, int options,
     285    int (*compar)(const FTSENT * const *, const FTSENT * const *))
     286{
     287        return nt_fts_open_common(argv, NULL, options, compar);
     288}
     289
     290
     291FTS * FTSCALL
     292nt_fts_openw(wchar_t * const *argv, int options,
     293    int (*compar)(const FTSENT * const *, const FTSENT * const *))
     294{
     295        return nt_fts_open_common(NULL, argv, options, compar);
     296}
     297
     298
     299/**
     300 * Called by fts_read for FTS_ROOTLEVEL entries only.
     301 */
    248302static void
    249303fts_load(FTS *sp, FTSENT *p)
    250304{
    251305        size_t len;
    252         char *cp;
     306        wchar_t *pwc;
    253307
    254308        /*
     
    259313         * known that the path will fit.
    260314         */
    261         len = p->fts_pathlen = p->fts_namelen;
    262         memmove(sp->fts_path, p->fts_name, len + 1);
    263         if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
    264                 len = strlen(++cp);
    265                 memmove(p->fts_name, cp, len + 1);
    266                 p->fts_namelen = len;
    267         }
    268         p->fts_accpath = p->fts_path = sp->fts_path;
     315    if (!(sp->fts_options & FTS_NO_ANSI)) {
     316                char *cp;
     317                len = p->fts_pathlen = p->fts_namelen;
     318                memmove(sp->fts_path, p->fts_name, len + 1);
     319                cp = strrchr(p->fts_name, '/');
     320                if (cp != NULL && (cp != p->fts_name || cp[1])) {
     321                        len = strlen(++cp);
     322                        memmove(p->fts_name, cp, len + 1);
     323                        p->fts_namelen = len;
     324                }
     325                p->fts_accpath = p->fts_path = sp->fts_path;
     326        }
     327
     328        len = p->fts_cwcpath = p->fts_cwcname;
     329        memmove(sp->fts_wcspath, p->fts_wcsname, (len + 1) * sizeof(wchar_t));
     330        pwc = wcsrchr(p->fts_wcsname, '/');
     331        if (pwc != NULL && (pwc != p->fts_wcsname || pwc[1])) {
     332                len = wcslen(++pwc);
     333                memmove(p->fts_wcsname, pwc, (len + 1) * sizeof(wchar_t));
     334                p->fts_cwcname = len;
     335        }
     336        p->fts_wcsaccpath = p->fts_wcspath = sp->fts_wcspath;
     337
    269338        sp->fts_dev = p->fts_dev;
    270339}
     
    296365                free(sp->fts_array);
    297366        free(sp->fts_path);
     367        free(sp->fts_wcspath);
    298368
    299369        /* Free up the stream pointer. */
     
    306376 * appended which would cause paths to be written as "....//foo".
    307377 */
    308 #define NAPPEND(p)                                                      \
    309         (p->fts_path[p->fts_pathlen - 1] == '/'                         \
    310             ? p->fts_pathlen - 1 : p->fts_pathlen)
     378#define NAPPEND(p)  ( p->fts_pathlen - (p->fts_path[p->fts_pathlen - 1]    ==  '/') )
     379#define NAPPENDW(p) ( p->fts_cwcpath - (p->fts_wcspath[p->fts_cwcpath - 1] == L'/') )
    311380
    312381static void
     
    327396        FTSENT *p, *tmp;
    328397        int instr;
    329         char *t;
     398        wchar_t *pwc;
    330399
    331400        /* If finished or unrecoverable error, return NULL. */
     
    447516                fts_free_entry(tmp);
    448517
    449 name:           t = sp->fts_path + NAPPEND(p->fts_parent);
    450                 *t++ = '/';
    451                 memmove(t, p->fts_name, p->fts_namelen + 1);
     518name:
     519                if (!(sp->fts_options & FTS_NO_ANSI)) {
     520                        char *t = sp->fts_path + NAPPEND(p->fts_parent);
     521                        *t++ = '/';
     522                        memmove(t, p->fts_name, p->fts_namelen + 1);
     523                }
     524                pwc = sp->fts_wcspath + NAPPENDW(p->fts_parent);
     525                *pwc++ = '/';
     526                memmove(pwc, p->fts_wcsname, (p->fts_cwcname + 1) * sizeof(wchar_t));
    452527                return (sp->fts_cur = p);
    453528        }
     
    468543
    469544        /* NUL terminate the pathname. */
    470         sp->fts_path[p->fts_pathlen] = '\0';
     545        if (!(sp->fts_options & FTS_NO_ANSI))
     546                sp->fts_path[p->fts_pathlen] = '\0';
     547        sp->fts_wcspath[ p->fts_cwcpath] = '\0';
    471548
    472549        /*
     
    478555         *     and clear fts_symfd now.
    479556         */
    480         if (p->fts_flags & FTS_SYMFOLLOW) {
     557        if (p->fts_flags & FTS_SYMFOLLOW)
    481558                p->fts_symfd = INVALID_HANDLE_VALUE;
    482         }
    483559    if (p->fts_dirfd != INVALID_HANDLE_VALUE) {
    484560                birdCloseFile(p->fts_dirfd);
     
    614690        FTSENT *cur, *tail;
    615691        DIR *dirp;
    616         void *oldaddr;
    617         char *cp;
    618         int saved_errno, doadjust;
     692        int saved_errno, doadjust, doadjust_utf16;
    619693        long level;
    620         size_t dnamlen, len, maxlen, nitems;
     694        size_t len, cwcdir, maxlen, cwcmax, nitems;
    621695        unsigned fDirOpenFlags;
    622696
     
    676750         * each new name into the path.
    677751         */
    678         len = NAPPEND(cur);
    679         cp = sp->fts_path + len;
    680         *cp++ = '/';
    681         len++;
    682         maxlen = sp->fts_pathlen - len;
     752    if (sp->fts_options & FTS_NO_ANSI) {
     753                len = maxlen = 0;
     754        } else {
     755                len = NAPPEND(cur);
     756                sp->fts_path[len] = '/'; /// @todo unnecessary?
     757                len++;
     758                maxlen = sp->fts_pathlen - len;
     759        }
     760
     761        cwcdir = NAPPENDW(cur);
     762        sp->fts_wcspath[cwcdir] = '/'; /// @todo unnecessary?
     763        cwcdir++;
     764        cwcmax = sp->fts_cwcpath - len;
    683765
    684766        level = cur->fts_level + 1;
    685767
    686768        /* Read the directory, attaching each entry to the `link' pointer. */
    687         doadjust = 0;
     769        doadjust = doadjust_utf16 = 0;
    688770        for (head = tail = NULL, nitems = 0; dirp && (dp = birdDirRead(dirp));) {
    689                 dnamlen = dp->d_namlen;
    690771                if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
    691772                        continue;
    692773
    693                 if ((p = fts_alloc(sp, dp->d_name, dnamlen)) == NULL)
     774                if ((p = fts_alloc_ansi(sp, dp->d_name, dp->d_namlen)) == NULL)
    694775                        goto mem1;
    695                 if (dnamlen >= maxlen) {        /* include space for NUL */
    696                         oldaddr = sp->fts_path;
    697                         if (fts_palloc(sp, dnamlen + len + 1)) {
     776
     777                if (p->fts_namelen >= maxlen
     778                 || p->fts_cwcname >= cwcmax) {  /* include space for NUL */
     779                        void *oldaddr = sp->fts_path;
     780                        wchar_t *oldwcspath = sp->fts_wcspath;
     781                        if (fts_palloc(sp,
     782                                                   p->fts_namelen >= maxlen ? len + p->fts_namelen + 1 : 0,
     783                                                   p->fts_cwcname >= cwcmax ? cwcdir + p->fts_cwcname + 1 : 0)) {
    698784                                /*
    699785                                 * No more memory for path or structures.  Save
     
    714800                        }
    715801                        /* Did realloc() change the pointer? */
    716                         if (oldaddr != sp->fts_path) {
    717                                 doadjust = 1;
    718                                 if (1 /*ISSET(FTS_NOCHDIR)*/)
    719                                         cp = sp->fts_path + len;
    720                         }
     802                        doadjust       |= oldaddr != sp->fts_path;
     803                        doadjust_utf16 |= oldwcspath != sp->fts_wcspath;
    721804                        maxlen = sp->fts_pathlen - len;
     805                        cwcmax = sp->fts_cwcpath - cwcdir;
    722806                }
    723807
    724808                p->fts_level = level;
    725809                p->fts_parent = sp->fts_cur;
    726                 p->fts_pathlen = len + dnamlen;
     810                p->fts_pathlen = len + p->fts_namelen;
     811                p->fts_cwcpath = cwcdir + p->fts_cwcname;
    727812                p->fts_accpath = p->fts_path;
     813                p->fts_wcsaccpath = p->fts_wcspath;
    728814                p->fts_stat = dp->d_stat;
    729815                p->fts_info = fts_process_stats(p, &dp->d_stat);
     
    748834        if (doadjust)
    749835                fts_padjust(sp, head);
     836        if (doadjust_utf16)
     837                fts_padjustw(sp, head);
    750838
    751839        /*
    752840         * Reset the path back to original state.
    753841         */
    754         sp->fts_path[cur->fts_pathlen] = '\0';
     842        sp->fts_path[cur->fts_pathlen] = '\0';   // @todo necessary?
     843        sp->fts_wcspath[cur->fts_cwcpath] = '\0';   // @todo necessary?
    755844
    756845        /* If didn't find anything, return NULL. */
     
    903992
    904993static FTSENT *
    905 fts_alloc(FTS *sp, char *name, size_t namelen)
     994fts_alloc(FTS *sp, char const *name, size_t namelen, wchar_t const *wcsname, size_t cwcname)
    906995{
    907996        FTSENT *p;
    908997        size_t len;
    909998
    910         struct ftsent_withstat {
    911                 FTSENT  ent;
    912                 struct  stat statbuf;
    913         };
    914 
    915999        /*
    9161000         * The file name is a variable length array.  Allocate the FTSENT
    9171001         * structure and the file name.
    9181002         */
    919         len = sizeof(FTSENT) + namelen + 1;
    920         if ((p = malloc(len)) == NULL)
    921                 return (NULL);
    922 
    923         p->fts_name = (char *)(p + 1);
    924         p->fts_statp = &p->fts_stat;
    925 
    926         /* Copy the name and guarantee NUL termination. */
    927         memcpy(p->fts_name, name, namelen);
    928         p->fts_name[namelen] = '\0';
    929         p->fts_namelen = namelen;
    930         p->fts_path = sp->fts_path;
    931         p->fts_errno = 0;
    932         p->fts_flags = 0;
    933         p->fts_instr = FTS_NOINSTR;
    934         p->fts_number = 0;
    935         p->fts_pointer = NULL;
    936         p->fts_fts = sp;
    937         p->fts_symfd = INVALID_HANDLE_VALUE;
    938         p->fts_dirfd = INVALID_HANDLE_VALUE;
     1003        len = sizeof(FTSENT) + (cwcname + 1) * sizeof(wchar_t);
     1004        if (!(sp->fts_options & FTS_NO_ANSI))
     1005            len += namelen + 1;
     1006        p = malloc(len);
     1007        if (p) {
     1008                /* Copy the names and guarantee NUL termination. */
     1009                p->fts_wcsname = (wchar_t *)(p + 1);
     1010                memcpy(p->fts_wcsname, wcsname, cwcname * sizeof(wchar_t));
     1011                p->fts_wcsname[cwcname];
     1012                p->fts_cwcname = cwcname;
     1013                if (!(sp->fts_options & FTS_NO_ANSI)) {
     1014                        p->fts_name = (char *)(p->fts_wcsname + cwcname + 1);
     1015                        memcpy(p->fts_name, name, namelen);
     1016                        p->fts_name[namelen] = '\0';
     1017                        p->fts_namelen = namelen;
     1018                } else {
     1019                        p->fts_name = NULL;
     1020                        p->fts_namelen = 0;
     1021                }
     1022
     1023                p->fts_path = sp->fts_path;
     1024                p->fts_wcspath = sp->fts_wcspath;
     1025                p->fts_statp = &p->fts_stat;
     1026                p->fts_errno = 0;
     1027                p->fts_flags = 0;
     1028                p->fts_instr = FTS_NOINSTR;
     1029                p->fts_number = 0;
     1030                p->fts_pointer = NULL;
     1031                p->fts_fts = sp;
     1032                p->fts_symfd = INVALID_HANDLE_VALUE;
     1033                p->fts_dirfd = INVALID_HANDLE_VALUE;
     1034        }
    9391035        return (p);
    9401036}
     1037
     1038
     1039/**
     1040 * Converts the ANSI name to UTF-16 and calls fts_alloc.
     1041 *
     1042 * @returns Pointer to allocated and mostly initialized FTSENT structure on
     1043 *          success.  NULL on failure, caller needs to record it.
     1044 * @param   sp                  Pointer to FTS instance.
     1045 * @param   name                The ANSI name.
     1046 * @param   namelen             The ANSI name length.
     1047 */
     1048static FTSENT *
     1049fts_alloc_ansi(FTS *sp, char const *name, size_t namelen)
     1050{
     1051        MY_UNICODE_STRING UniStr;
     1052        MY_ANSI_STRING AnsiStr;
     1053        MY_NTSTATUS rcNt;
     1054        FTSENT *pRet;
     1055
     1056        UniStr.Buffer = NULL;
     1057        UniStr.MaximumLength = UniStr.Length = 0;
     1058
     1059        AnsiStr.Buffer = (char *)name;
     1060        AnsiStr.Length = AnsiStr.MaximumLength = (USHORT)namelen;
     1061
     1062        rcNt = g_pfnRtlAnsiStringToUnicodeString(&UniStr, &AnsiStr, TRUE /*fAllocate*/);
     1063        if (NT_SUCCESS(rcNt)) {
     1064                pRet = fts_alloc(sp, name, namelen, UniStr.Buffer, UniStr.Length / sizeof(wchar_t));
     1065                HeapFree(GetProcessHeap(), 0, UniStr.Buffer);
     1066        } else {
     1067                pRet = NULL;
     1068        }
     1069        return pRet;
     1070}
     1071
     1072
     1073/**
     1074 * Converts the UTF-16 name to ANSI (if necessary) and calls fts_alloc.
     1075 *
     1076 * @returns Pointer to allocated and mostly initialized FTSENT structure on
     1077 *          success.  NULL on failure, caller needs to record it.
     1078 * @param   sp                  Pointer to FTS instance.
     1079 * @param   wcsname             The UTF-16 name.
     1080 * @param   cwcname             The UTF-16 name length.
     1081 */
     1082static FTSENT *
     1083fts_alloc_utf16(FTS *sp, wchar_t const *wcsname, size_t cwcname)
     1084{
     1085    FTSENT *pRet;
     1086
     1087    if (sp->fts_options & FTS_NO_ANSI) {
     1088                pRet = fts_alloc(sp, NULL, 0, wcsname, cwcname);
     1089    } else {
     1090                MY_UNICODE_STRING UniStr;
     1091                MY_ANSI_STRING AnsiStr;
     1092                MY_NTSTATUS rcNt;
     1093
     1094                UniStr.Buffer = (wchar_t *)wcsname;
     1095                UniStr.MaximumLength = UniStr.Length = (USHORT)(cwcname * sizeof(wchar_t));
     1096
     1097                AnsiStr.Buffer = NULL;
     1098                AnsiStr.Length = AnsiStr.MaximumLength = 0;
     1099
     1100                rcNt = g_pfnRtlUnicodeStringToAnsiString(&AnsiStr, &UniStr, TRUE /*fAllocate*/);
     1101                if (NT_SUCCESS(rcNt)) {
     1102                        pRet = fts_alloc(sp, AnsiStr.Buffer, AnsiStr.Length, wcsname, cwcname);
     1103                        HeapFree(GetProcessHeap(), 0, AnsiStr.Buffer);
     1104                } else {
     1105                        pRet = NULL;
     1106                }
     1107        }
     1108    return pRet;
     1109}
     1110
    9411111
    9421112static void
     
    9601130 */
    9611131static int
    962 fts_palloc(FTS *sp, size_t more)
     1132fts_palloc(FTS *sp, size_t more, size_t cwcmore)
    9631133{
    9641134        void *ptr;
    9651135
    966         sp->fts_pathlen += more + 256;
    967         ptr = realloc(sp->fts_path, sp->fts_pathlen);
    968         if (ptr) {
    969                 /*likely */
    970         } else {
    971                 free(sp->fts_path);
    972         }
    973         sp->fts_path = ptr;
    974         return (ptr == NULL);
     1136        /** @todo Isn't more and cwcmore minimum buffer sizes rather than what needs
     1137         *        to be added to the buffer??  This code makes no sense when looking at
     1138         *        the way the caller checks things out! */
     1139
     1140    if (more) {
     1141                sp->fts_pathlen += more + 256;
     1142                ptr = realloc(sp->fts_path, sp->fts_pathlen);
     1143                if (ptr) {
     1144                        sp->fts_path = ptr;
     1145                } else {
     1146                        free(sp->fts_path);
     1147                        sp->fts_path = NULL;
     1148                        free(sp->fts_wcspath);
     1149                        sp->fts_wcspath = NULL;
     1150                        return 1;
     1151                }
     1152    }
     1153
     1154    if (cwcmore) {
     1155                sp->fts_cwcpath += cwcmore + 256;
     1156                ptr = realloc(sp->fts_wcspath, sp->fts_cwcpath);
     1157                if (ptr) {
     1158                        sp->fts_wcspath = ptr;
     1159                } else {
     1160                        free(sp->fts_path);
     1161                        sp->fts_path = NULL;
     1162                        free(sp->fts_wcspath);
     1163                        sp->fts_wcspath = NULL;
     1164                        return 1;
     1165                }
     1166    }
     1167        return 0;
    9751168}
    9761169
     
    10031196}
    10041197
     1198/*
     1199 * When the UTF-16 path is realloc'd, have to fix all of the pointers in
     1200 * structures already returned.
     1201 */
     1202static void
     1203fts_padjustw(FTS *sp, FTSENT *head)
     1204{
     1205        FTSENT *p;
     1206        wchar_t *addr = sp->fts_wcspath;
     1207
     1208#define ADJUSTW(p) \
     1209                do {    \
     1210                        if ((p)->fts_wcsaccpath != (p)->fts_wcsname) \
     1211                                (p)->fts_wcsaccpath = addr + ((p)->fts_wcsaccpath - (p)->fts_wcspath); \
     1212                        (p)->fts_wcspath = addr;                                                \
     1213                } while (0)
     1214
     1215        /* Adjust the current set of children. */
     1216        for (p = sp->fts_child; p; p = p->fts_link)
     1217                ADJUSTW(p);
     1218
     1219        /* Adjust the rest of the tree, including the current level. */
     1220        for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
     1221                ADJUSTW(p);
     1222                p = p->fts_link ? p->fts_link : p->fts_parent;
     1223        }
     1224}
     1225
    10051226static size_t
    10061227fts_maxarglen(char * const *argv)
     
    10141235}
    10151236
     1237/** Returns the max string size (including term). */
     1238static size_t
     1239fts_maxarglenw(wchar_t * const *argv)
     1240{
     1241        size_t max = 0;
     1242        for (; *argv; ++argv) {
     1243                size_t len = wcslen(*argv);
     1244                if (len > max)
     1245                        max = len;
     1246        }
     1247        return max + 1;
     1248}
     1249
  • trunk/src/lib/nt/fts-nt.h

    r2997 r2998  
    6767        char *fts_path;                 /* path for this descent */
    6868        size_t fts_pathlen;             /* sizeof(path) */
     69        wchar_t *fts_wcspath;           /* NT: UTF-16 path for this descent. */
     70        size_t fts_cwcpath;             /* NT: size of fts_wcspath buffer */
    6971        size_t fts_nitems;              /* elements in the sort array */
    7072        int (FTSCALL *fts_compar)       /* compare function */
     
    8587#define FTS_NAMEONLY    0x100           /* (private) child names only */
    8688#define FTS_STOP        0x200           /* (private) unrecoverable error */
     89#define FTS_NO_ANSI     0x40000000      /* NT: No ansi name or access path. */
    8790        int fts_options;                /* fts_open options, global flags */
    8891        void *fts_clientptr;            /* thunk for sort function */
     
    97100        void *fts_pointer;              /* local address value */
    98101        char *fts_accpath;              /* access path */
     102        wchar_t *fts_wcsaccpath;        /* NT: UTF-16 access path */
    99103        char *fts_path;                 /* root path */
     104        wchar_t *fts_wcspath;           /* NT: UTF-16 root path */
    100105        int fts_errno;                  /* errno for this node */
    101106        fts_fd_t fts_symfd;             /* NT: Normally -1; -2 we followed this symlinked dir */
    102107        fts_fd_t fts_dirfd;             /* NT: Handle to the directory (NT_FTS_)INVALID_HANDLE_VALUE if not valid */
    103108        size_t fts_pathlen;             /* strlen(fts_path) */
     109        size_t fts_cwcpath;             /* NT: length of fts_wcspath. */
    104110        size_t fts_namelen;             /* strlen(fts_name) */
     111        size_t fts_cwcname;             /* NT: length of fts_wcsname. */
    105112
     113        fts_nlink_t fts_nlink;          /* link count */
    106114        fts_ino_t fts_ino;              /* inode */
    107115        fts_dev_t fts_dev;              /* device */
    108         fts_nlink_t fts_nlink;          /* link count */
    109116
    110117#define FTS_ROOTPARENTLEVEL     -1
     
    141148        struct stat *fts_statp;         /* stat(2) information */
    142149        char *fts_name;                 /* file name */
     150        wchar_t *fts_wcsname;           /* NT: UTF-16 file name. */
    143151        FTS *fts_fts;                   /* back pointer to main FTS */
    144152        BirdStat_T fts_stat;            /* NT: We always got stat info. */
     
    156164FTS     *FTSCALL nt_fts_get_stream(FTSENT *);
    157165#define  fts_get_stream(ftsent) ((ftsent)->fts_fts)
    158 FTS     *FTSCALL nt_fts_open(char * const *, int,
    159             int (FTSCALL*)(const FTSENT * const *, const FTSENT * const *));
     166FTS     *FTSCALL nt_fts_open(char * const *, int, int (FTSCALL*)(const FTSENT * const *, const FTSENT * const *));
     167FTS     *FTSCALL nt_fts_openw(wchar_t * const *, int, int (FTSCALL*)(const FTSENT * const *, const FTSENT * const *));
    160168FTSENT  *FTSCALL nt_fts_read(FTS *);
    161169int      FTSCALL nt_fts_set(FTS *, FTSENT *, int);
  • trunk/src/lib/nt/nthlpcore.c

    r2985 r2998  
    6161BOOLEAN     (WINAPI *g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *);
    6262MY_NTSTATUS (WINAPI *g_pfnRtlAnsiStringToUnicodeString)(MY_UNICODE_STRING *, MY_ANSI_STRING const *, BOOLEAN);
     63MY_NTSTATUS (WINAPI *g_pfnRtlUnicodeStringToAnsiString)(MY_ANSI_STRING *, MY_UNICODE_STRING *, BOOLEAN);
    6364BOOLEAN     (WINAPI *g_pfnRtlEqualUnicodeString)(MY_UNICODE_STRING const *, MY_UNICODE_STRING const *, BOOLEAN);
    6465BOOLEAN     (WINAPI *g_pfnRtlEqualString)(MY_ANSI_STRING const *, MY_ANSI_STRING const *, BOOLEAN);
     
    6768VOID        (WINAPI *g_pfnRtlAcquirePebLock)(VOID);
    6869VOID        (WINAPI *g_pfnRtlReleasePebLock)(VOID);
    69 
    7070
    7171static struct
     
    8888    { (FARPROC *)&g_pfnRtlDosPathNameToNtPathName_U,    "RtlDosPathNameToNtPathName_U" },
    8989    { (FARPROC *)&g_pfnRtlAnsiStringToUnicodeString,    "RtlAnsiStringToUnicodeString" },
     90    { (FARPROC *)&g_pfnRtlUnicodeStringToAnsiString,    "RtlUnicodeStringToAnsiString" },
    9091    { (FARPROC *)&g_pfnRtlEqualUnicodeString,           "RtlEqualUnicodeString" },
    9192    { (FARPROC *)&g_pfnRtlEqualString,                  "RtlEqualString" },
  • trunk/src/lib/nt/ntstuff.h

    r2985 r2998  
    556556extern BOOLEAN     (WINAPI * g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *);
    557557extern MY_NTSTATUS (WINAPI * g_pfnRtlAnsiStringToUnicodeString)(MY_UNICODE_STRING *, MY_ANSI_STRING const *, BOOLEAN);
     558extern MY_NTSTATUS (WINAPI * g_pfnRtlUnicodeStringToAnsiString)(MY_ANSI_STRING *, MY_UNICODE_STRING *, BOOLEAN);
    558559extern BOOLEAN     (WINAPI * g_pfnRtlEqualUnicodeString)(MY_UNICODE_STRING const *pUniStr1, MY_UNICODE_STRING const *pUniStr2,
    559560                                                         BOOLEAN fCaseInsensitive);
Note: See TracChangeset for help on using the changeset viewer.