You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by wr...@apache.org on 2001/08/28 23:45:04 UTC

cvs commit: apr/include/arch/win32 fileio.h

wrowe       01/08/28 14:45:04

  Modified:    .        apr.dsp libapr.dsp
               file_io/win32 filepath.c
               include/arch/win32 fileio.h
  Added:       file_io/win32 filesys.c
  Log:
    Split all win32 specific system calls from filepath.c into filesys.c
  
    I don't care whether filepath.c remains in file_io/win32 or moves to
    file_io/os2.  This is now generic enough for both ports to build upon.
  
  Revision  Changes    Path
  1.81      +4 -0      apr/apr.dsp
  
  Index: apr.dsp
  ===================================================================
  RCS file: /home/cvs/apr/apr.dsp,v
  retrieving revision 1.80
  retrieving revision 1.81
  diff -u -r1.80 -r1.81
  --- apr.dsp	2001/08/26 05:21:49	1.80
  +++ apr.dsp	2001/08/28 21:45:04	1.81
  @@ -117,6 +117,10 @@
   # End Source File
   # Begin Source File
   
  +SOURCE=.\file_io\win32\filesys.c
  +# End Source File
  +# Begin Source File
  +
   SOURCE=.\file_io\win32\flock.c
   # End Source File
   # Begin Source File
  
  
  
  1.43      +4 -0      apr/libapr.dsp
  
  Index: libapr.dsp
  ===================================================================
  RCS file: /home/cvs/apr/libapr.dsp,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- libapr.dsp	2001/08/26 05:21:49	1.42
  +++ libapr.dsp	2001/08/28 21:45:04	1.43
  @@ -123,6 +123,10 @@
   # End Source File
   # Begin Source File
   
  +SOURCE=.\file_io\win32\filesys.c
  +# End Source File
  +# Begin Source File
  +
   SOURCE=.\file_io\win32\flock.c
   # End Source File
   # Begin Source File
  
  
  
  1.9       +20 -213   apr/file_io/win32/filepath.c
  
  Index: filepath.c
  ===================================================================
  RCS file: /home/cvs/apr/file_io/win32/filepath.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- filepath.c	2001/08/27 20:02:31	1.8
  +++ filepath.c	2001/08/28 21:45:04	1.9
  @@ -54,222 +54,17 @@
   
   #include "apr.h"
   #include "fileio.h"
  -#include "apr_file_io.h"
   #include "apr_strings.h"
   
   
  -/* Win32 Exceptions:
  - *
  - * Note that trailing spaces and trailing periods are never recorded
  - * in the file system, except by a very obscure bug where any file
  - * that is created with a trailing space or period, followed by the 
  - * ':' stream designator on an NTFS volume can never be accessed again.
  - * In other words, don't ever accept them when designating a stream!
  - *
  - * An interesting side effect is that two or three periods are both 
  - * treated as the parent directory, although the fourth and on are
  - * not [strongly suggest all trailing periods are trimmed off, or
  - * down to two if there are no other characters.]
  - *
  - * Leading spaces and periods are accepted, however.
  - */
  -static int is_fnchar(char ch) 
  -{
  -    /* No control code between 0 and 31 is allowed
  -     * The * ? < > codes all have wildcard effects
  -     * The " / \ : are exlusively separator tokens 
  -     * The system doesn't accept | for any purpose.
  -     * Oddly, \x7f _is_ acceptable.
  -     */
  -    if (ch >= 0 && ch < 32)
  -        return 0;
  -
  -    if (ch == '\"' || ch ==  '*' || ch == '/' 
  -     || ch ==  ':' || ch ==  '<' || ch == '>' 
  -     || ch ==  '?' || ch == '\\' || ch == '|')
  -        return 0;
  -
  -    return 1;
  -}
  -
  -
  -static apr_status_t filepath_root_test(char *path,
  -                                       apr_pool_t *p)
  -{
  -    apr_status_t rv;
  -#if APR_HAS_UNICODE_FS
  -    apr_oslevel_e os_level;
  -    if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
  -    {
  -        apr_wchar_t wpath[APR_PATH_MAX];
  -        if (rv = utf8_to_unicode_path(wpath, sizeof(wpath) 
  -                                           / sizeof(apr_wchar_t), path))
  -            return rv;
  -        rv = GetDriveTypeW(wpath);
  -    }
  -    else
  -#endif
  -        rv = GetDriveType(path);
  -
  -    if (rv == DRIVE_UNKNOWN || rv == DRIVE_NO_ROOT_DIR)
  -        return APR_EBADPATH;
  -    return APR_SUCCESS;
  -}
  -
  -
  -APR_DECLARE(apr_status_t) apr_filepath_get(char **rootpath,
  -                                           apr_pool_t *p)
  -{
  -    char path[APR_PATH_MAX];
  -#if APR_HAS_UNICODE_FS
  -    apr_oslevel_e os_level;
  -    if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
  -    {
  -        apr_wchar_t wpath[APR_PATH_MAX];
  -        apr_status_t rv;
  -        if (!GetCurrentDirectoryW(sizeof(wpath) / sizeof(apr_wchar_t), wpath))
  -            return apr_get_os_error();
  -        if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
  -            return rv;
  -    }
  -    else
  -#endif
  -    {
  -        if (!GetCurrentDirectory(sizeof(path), path))
  -            return apr_get_os_error();
  -    }
  -    /* ###: We really should consider adding a flag to allow the user
  -     * to have the APR_FILEPATH_NATIVE result
  -     */
  -    for (*rootpath = path; **rootpath; ++*rootpath) {
  -        if (**rootpath == '\\')
  -            **rootpath = '/';
  -    }
  -    *rootpath = apr_pstrdup(p, path);
  -    return APR_SUCCESS;
  -}
  -
  -
  -static apr_status_t filepath_drive_get(char **rootpath,
  -                                       char drive,
  -                                       apr_pool_t *p)
  -{
  -    char path[APR_PATH_MAX];
  -#if APR_HAS_UNICODE_FS
  -    apr_oslevel_e os_level;
  -    if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
  -    {
  -        apr_wchar_t *ignored;
  -        apr_wchar_t wdrive[8];
  -        apr_wchar_t wpath[APR_PATH_MAX];
  -        apr_status_t rv;
  -        /* ???: This needs review, apparently "\\?\d:." returns "\\?\d:" 
  -         * as if that is useful for anything.
  -         */
  -        wcscpy(wdrive, L"D:.");
  -        wdrive[0] = (apr_wchar_t)(unsigned char)drive;
  -        if (!GetFullPathNameW(wdrive, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
  -            return apr_get_os_error();
  -        if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
  -            return rv;
  -    }
  -    else
  -#endif
  -    {
  -        char *ignored;
  -        char drivestr[4];
  -        drivestr[0] = drive;
  -        drivestr[1] = ':';
  -        drivestr[2] = '.';;
  -        drivestr[3] = '\0';
  -        if (!GetFullPathName(drivestr, sizeof(path), path, &ignored))
  -            return apr_get_os_error();
  -    }
  -    /* ###: We really should consider adding a flag to allow the user
  -     * to have the APR_FILEPATH_NATIVE result
  -     */
  -    for (*rootpath = path; **rootpath; ++*rootpath) {
  -        if (**rootpath == '\\')
  -            **rootpath = '/';
  -    }
  -    *rootpath = apr_pstrdup(p, path);
  -    return APR_SUCCESS;
  -}
  -
  -
  -static apr_status_t filepath_root_case(char **rootpath,
  -                                           char *root,
  -                                           apr_pool_t *p)
  -{
  -#if APR_HAS_UNICODE_FS
  -    apr_oslevel_e os_level;
  -    if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
  -    {
  -        apr_wchar_t *ignored;
  -        apr_wchar_t wpath[APR_PATH_MAX];
  -        apr_status_t rv;
  -        /* ???: This needs review, apparently "\\?\d:." returns "\\?\d:" 
  -         * as if that is useful for anything.
  -         */
  -        {
  -            apr_wchar_t wroot[APR_PATH_MAX];
  -            if (rv = utf8_to_unicode_path(wroot, sizeof(wroot) 
  -                                               / sizeof(apr_wchar_t), root))
  -                return rv;
  -            if (!GetFullPathNameW(wroot, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
  -                return apr_get_os_error();
  -        }
  -        {
  -            char path[APR_PATH_MAX];
  -            if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
  -                return rv;
  -            *rootpath = apr_pstrdup(p, path);
  -        }
  -    }
  -    else
  -#endif
  -    {
  -        char path[APR_PATH_MAX];
  -        char *ignored;
  -        if (!GetFullPathName(root, sizeof(path), path, &ignored))
  -            return apr_get_os_error();
  -        *rootpath = apr_pstrdup(p, path);
  -    }
  -    return APR_SUCCESS;
  -}
  -
  -
  -APR_DECLARE(apr_status_t) apr_filepath_set(const char *rootpath,
  -                                           apr_pool_t *p)
  -{
  -#if APR_HAS_UNICODE_FS
  -    apr_oslevel_e os_level;
  -    if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
  -    {
  -        apr_wchar_t wpath[APR_PATH_MAX];
  -        apr_status_t rv;
  -        if (rv = utf8_to_unicode_path(wpath, sizeof(wpath) 
  -                                           / sizeof(apr_wchar_t), rootpath))
  -            return rv;
  -        if (!SetCurrentDirectoryW(wpath))
  -            return apr_get_os_error();
  -    }
  -    else
  -#endif
  -    {
  -        if (!SetCurrentDirectory(rootpath))
  -            return apr_get_os_error();
  -    }
  -    return APR_SUCCESS;
  -}
  -
  -
  -/* WinNT accepts several odd forms of a 'root' path.  Under Unicode
  + /* WinNT accepts several odd forms of a 'root' path.  Under Unicode
    * calls (ApiFunctionW) the //?/C:/foo or //?/UNC/mach/share/foo forms
    * are accepted.  Ansi and Unicode functions both accept the //./C:/foo 
    * form under WinNT/2K.  Since these forms are handled in the utf-8 to 
    * unicode translation phase, we don't want the user confused by them, so 
    * we will accept them but always return the canonical C:/ or //mach/share/
  + *
  + * OS2 appears immune from the nonsense :)
    */
   
   APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath, 
  @@ -284,10 +79,11 @@
   
       if (testpath[0] == '/' || testpath[0] == '\\') {
           if (testpath[1] == '/' || testpath[1] == '\\') {
  -            /* //server/share isn't the only // delimited syntax */
  +
  +#ifdef WIN32 /* //server/share isn't the only // delimited syntax */
               if ((testpath[2] == '?' || testpath[2] == '.')
                       && (testpath[3] == '/' || testpath[3] == '\\')) {
  -                if (is_fnchar(testpath[4]) && testpath[5] == ':') 
  +                if (IS_FNCHAR(testpath[4]) && testpath[5] == ':') 
                   {
                       apr_status_t rv;
                       testpath += 4;
  @@ -315,12 +111,13 @@
                        */
                       return APR_EBADPATH;
               }
  +#endif /* WIN32 (non - //server/share syntax) */
   
               /* Evaluate path of '//[machine/[share[/]]]' */
               delim1 = testpath + 2;
               do {
                   /* Protect against //X/ where X is illegal */
  -                if (*delim1 && !is_fnchar(*(delim1++)))
  +                if (*delim1 && !IS_FNCHAR(*(delim1++)))
                       return APR_EBADPATH;
               } while (*delim1 && *delim1 != '/' && *delim1 != '\\');
   
  @@ -329,7 +126,7 @@
                   delim2 = delim1 + 1;
                   while (*delim2 && *delim2 != '/' && *delim2 != '\\') {
                       /* Protect against //machine/X/ where X is illegal */
  -                    if (!is_fnchar(*(delim2++)))
  +                    if (!IS_FNCHAR(*(delim2++)))
                           return APR_EBADPATH;
                   } 
   
  @@ -418,7 +215,7 @@
       }
   
       /* Evaluate path of 'd:[/]' */
  -    if (is_fnchar(*testpath) && testpath[1] == ':') 
  +    if (IS_FNCHAR(*testpath) && testpath[1] == ':') 
       {
           apr_status_t rv;
           /* Validate that D:\ drive exists, test must be rooted
  @@ -935,6 +732,14 @@
               if ((rv = apr_stat(&finfo, path, APR_FINFO_TYPE | APR_FINFO_NAME, p))
                       == APR_SUCCESS) {
                   size_t namelen = strlen(finfo.name);
  +
  +#ifdef OS2 /* only has case folding, never aliases that change the length */
  +
  +                if (memcmp(finfo.name, path + keptlen, seglen) != 0) {
  +                    memcpy(path + keptlen, finfo.name, namelen);
  +                }
  +#else /* WIN32; here there be aliases that gire and gimble and change length */
  +
                   if ((namelen != seglen) || 
                       (memcmp(finfo.name, path + keptlen, seglen) != 0)) 
                   {
  @@ -961,6 +766,8 @@
                           seglen = namelen;
                       }
                   }
  +#endif /* !OS2 (Whatever that alias was we're over it) */
  +
                   /* That's it, the rest is path info. 
                    * I don't know how we aught to handle this.  Should
                    * we define a new error to indicate 'more info'?
  
  
  
  1.1                  apr/file_io/win32/filesys.c
  
  Index: filesys.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  #include "apr.h"
  #include "fileio.h"
  #include "apr_strings.h"
  
  /* Win32 Exceptions:
   *
   * Note that trailing spaces and trailing periods are never recorded
   * in the file system, except by a very obscure bug where any file
   * that is created with a trailing space or period, followed by the 
   * ':' stream designator on an NTFS volume can never be accessed again.
   * In other words, don't ever accept them when designating a stream!
   *
   * An interesting side effect is that two or three periods are both 
   * treated as the parent directory, although the fourth and on are
   * not [strongly suggest all trailing periods are trimmed off, or
   * down to two if there are no other characters.]
   *
   * Leading spaces and periods are accepted, however.
   * The * ? < > codes all have wildcard side effects
   * The " / \ : are exclusively component separator tokens 
   * The system doesn't accept | for any (known) purpose 
   * Oddly, \x7f _is_ acceptable ;)
   */
  
  const char c_is_fnchar[256] =
  {/* Reject all ctrl codes...                                         */
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
   /*   "                 *         /                      :   <   > ? */
      1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,
   /*                                                          \       */
      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
   /*                                                      :   |       */
      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
   /* High bit codes are accepted (subject to utf-8->Unicode xlation)  */
      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
  };
  
  
  apr_status_t filepath_root_test(char *path, apr_pool_t *p)
  {
      apr_status_t rv;
  #if APR_HAS_UNICODE_FS
      apr_oslevel_e os_level;
      if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
      {
          apr_wchar_t wpath[APR_PATH_MAX];
          if (rv = utf8_to_unicode_path(wpath, sizeof(wpath) 
                                             / sizeof(apr_wchar_t), path))
              return rv;
          rv = GetDriveTypeW(wpath);
      }
      else
  #endif
          rv = GetDriveType(path);
  
      if (rv == DRIVE_UNKNOWN || rv == DRIVE_NO_ROOT_DIR)
          return APR_EBADPATH;
      return APR_SUCCESS;
  }
  
  
  apr_status_t filepath_drive_get(char **rootpath, char drive, apr_pool_t *p)
  {
      char path[APR_PATH_MAX];
  #if APR_HAS_UNICODE_FS
      apr_oslevel_e os_level;
      if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
      {
          apr_wchar_t *ignored;
          apr_wchar_t wdrive[8];
          apr_wchar_t wpath[APR_PATH_MAX];
          apr_status_t rv;
          /* ???: This needs review, apparently "\\?\d:." returns "\\?\d:" 
           * as if that is useful for anything.
           */
          wcscpy(wdrive, L"D:.");
          wdrive[0] = (apr_wchar_t)(unsigned char)drive;
          if (!GetFullPathNameW(wdrive, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
              return apr_get_os_error();
          if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
              return rv;
      }
      else
  #endif
      {
          char *ignored;
          char drivestr[4];
          drivestr[0] = drive;
          drivestr[1] = ':';
          drivestr[2] = '.';;
          drivestr[3] = '\0';
          if (!GetFullPathName(drivestr, sizeof(path), path, &ignored))
              return apr_get_os_error();
      }
      /* ###: We really should consider adding a flag to allow the user
       * to have the APR_FILEPATH_NATIVE result
       */
      for (*rootpath = path; **rootpath; ++*rootpath) {
          if (**rootpath == '\\')
              **rootpath = '/';
      }
      *rootpath = apr_pstrdup(p, path);
      return APR_SUCCESS;
  }
  
  
  apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p)
  {
  #if APR_HAS_UNICODE_FS
      apr_oslevel_e os_level;
      if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
      {
          apr_wchar_t *ignored;
          apr_wchar_t wpath[APR_PATH_MAX];
          apr_status_t rv;
          /* ???: This needs review, apparently "\\?\d:." returns "\\?\d:" 
           * as if that is useful for anything.
           */
          {
              apr_wchar_t wroot[APR_PATH_MAX];
              if (rv = utf8_to_unicode_path(wroot, sizeof(wroot) 
                                                 / sizeof(apr_wchar_t), root))
                  return rv;
              if (!GetFullPathNameW(wroot, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
                  return apr_get_os_error();
          }
          {
              char path[APR_PATH_MAX];
              if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
                  return rv;
              *rootpath = apr_pstrdup(p, path);
          }
      }
      else
  #endif
      {
          char path[APR_PATH_MAX];
          char *ignored;
          if (!GetFullPathName(root, sizeof(path), path, &ignored))
              return apr_get_os_error();
          *rootpath = apr_pstrdup(p, path);
      }
      return APR_SUCCESS;
  }
  
  
  APR_DECLARE(apr_status_t) apr_filepath_get(char **rootpath,
                                             apr_pool_t *p)
  {
      char path[APR_PATH_MAX];
  #if APR_HAS_UNICODE_FS
      apr_oslevel_e os_level;
      if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
      {
          apr_wchar_t wpath[APR_PATH_MAX];
          apr_status_t rv;
          if (!GetCurrentDirectoryW(sizeof(wpath) / sizeof(apr_wchar_t), wpath))
              return apr_get_os_error();
          if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
              return rv;
      }
      else
  #endif
      {
          if (!GetCurrentDirectory(sizeof(path), path))
              return apr_get_os_error();
      }
      /* ###: We really should consider adding a flag to allow the user
       * to have the APR_FILEPATH_NATIVE result
       */
      for (*rootpath = path; **rootpath; ++*rootpath) {
          if (**rootpath == '\\')
              **rootpath = '/';
      }
      *rootpath = apr_pstrdup(p, path);
      return APR_SUCCESS;
  }
  
  
  APR_DECLARE(apr_status_t) apr_filepath_set(const char *rootpath,
                                             apr_pool_t *p)
  {
  #if APR_HAS_UNICODE_FS
      apr_oslevel_e os_level;
      if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
      {
          apr_wchar_t wpath[APR_PATH_MAX];
          apr_status_t rv;
          if (rv = utf8_to_unicode_path(wpath, sizeof(wpath) 
                                             / sizeof(apr_wchar_t), rootpath))
              return rv;
          if (!SetCurrentDirectoryW(wpath))
              return apr_get_os_error();
      }
      else
  #endif
      {
          if (!SetCurrentDirectory(rootpath))
              return apr_get_os_error();
      }
      return APR_SUCCESS;
  }
  
  
  
  
  
  1.55      +32 -0     apr/include/arch/win32/fileio.h
  
  Index: fileio.h
  ===================================================================
  RCS file: /home/cvs/apr/include/arch/win32/fileio.h,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- fileio.h	2001/06/27 19:40:53	1.54
  +++ fileio.h	2001/08/28 21:45:04	1.55
  @@ -212,6 +212,38 @@
       };
   };
   
  +/* There are many goofy characters we can't accept.  Here's the list.
  + */
  +extern const char c_is_fnchar[256];
  +
  +#define IS_FNCHAR(c) c_is_fnchar[(unsigned char)c]
  +
  +
  +/* If the user passes APR_FILEPATH_TRUENAME to either
  + * apr_filepath_root or apr_filepath_merge, this fn determines
  + * that the root really exists.  It's expensive, wouldn't want
  + * to do this too frequenly.
  + */
  +apr_status_t filepath_root_test(char *path, apr_pool_t *p);
  +
  +
  +/* The apr_filepath_merge wants to canonicalize the cwd to the 
  + * addpath if the user passes NULL as the old root path (this
  + * isn't true of an empty string "", which won't be concatinated.
  + *
  + * But we need to figure out what the cwd of a given volume is,
  + * when the user passes D:foo.  This fn will determine D:'s cwd.
  + */
  +apr_status_t filepath_drive_get(char **rootpath, char drive, apr_pool_t *p);
  +
  +
  +/* If the user passes d: vs. D: (or //mach/share vs. //MACH/SHARE),
  + * we need to fold the case to canonical form.  This function is
  + * supposed to do so.
  + */
  +apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
  +
  +
   apr_status_t file_cleanup(void *);
   
   /**