summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apr.dsp4
-rw-r--r--file_io/win32/filepath.c233
-rw-r--r--file_io/win32/filesys.c261
-rw-r--r--include/arch/win32/fileio.h32
-rw-r--r--libapr.dsp4
5 files changed, 321 insertions, 213 deletions
diff --git a/apr.dsp b/apr.dsp
index 0a9969714..54097a78f 100644
--- a/apr.dsp
+++ b/apr.dsp
@@ -117,6 +117,10 @@ SOURCE=.\file_io\win32\filestat.c
# 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
diff --git a/file_io/win32/filepath.c b/file_io/win32/filepath.c
index 0f4a386d4..3e3096d33 100644
--- a/file_io/win32/filepath.c
+++ b/file_io/win32/filepath.c
@@ -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 @@ APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
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 @@ APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
*/
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 @@ APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
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 @@ APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
}
/* 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 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
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 @@ APR_DECLARE(apr_status_t) apr_filepath_merge(char **newpath,
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'?
diff --git a/file_io/win32/filesys.c b/file_io/win32/filesys.c
new file mode 100644
index 000000000..1e94b0624
--- /dev/null
+++ b/file_io/win32/filesys.c
@@ -0,0 +1,261 @@
+/* ====================================================================
+ * 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;
+}
+
+
diff --git a/include/arch/win32/fileio.h b/include/arch/win32/fileio.h
index 164651fd7..afb4ab905 100644
--- a/include/arch/win32/fileio.h
+++ b/include/arch/win32/fileio.h
@@ -212,6 +212,38 @@ struct apr_dir_t {
};
};
+/* 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 *);
/**
diff --git a/libapr.dsp b/libapr.dsp
index ab30ce46c..b3aa21db9 100644
--- a/libapr.dsp
+++ b/libapr.dsp
@@ -123,6 +123,10 @@ SOURCE=.\file_io\win32\filestat.c
# 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