wrowe 02/01/08 14:48:25
Modified: file_io/win32 open.c
include/arch/win32 fileio.h
Log:
This helper stub will get us the appropriate Win32 wchar* or char*,
allocated from pool [no big stack vars], no longer than 255 characters,
and with no 'path decoration' so we can turn a filename into a faux
resource name string. This function fixes resource names into the
Global\ or Local\ namespace on Windows 2000 or later, since this is
a requirement on Win2K Terminal Server, where we have multiple VMs.
Oh, we don't fail on long names, we will truncate off the left, so as
much unique info as possible is preserved. We also shorten to 255 or
fewer chars, so we don't have multiple utf8->unicode calls. We aren't
caring that we loose a few more wchars, as long as it's less than 255.
Revision Changes Path
1.89 +83 -0 apr/file_io/win32/open.c
Index: open.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/open.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -r1.88 -r1.89
--- open.c 8 Jan 2002 06:26:09 -0000 1.88
+++ open.c 8 Jan 2002 22:48:24 -0000 1.89
@@ -165,6 +165,89 @@
}
#endif
+void *res_name_from_filename(const char *file, int global, apr_pool_t *pool)
+{
+#if APR_HAS_UNICODE_FS
+ if (apr_os_level >= APR_WIN_NT) {
+ apr_wchar_t *wpre, *wfile, *ch;
+ apr_size_t n = strlen(file) + 1;
+ apr_size_t r, d;
+ apr_status_t rv;
+
+ if (apr_os_level >= APR_WIN_2000) {
+ if (global)
+ wpre = L"Global\\";
+ else
+ wpre = L"Local\\";
+ }
+ else
+ wpre = L"";
+ r = wcslen(wpre);
+
+ if (n > 256 - r) {
+ file += n - 256 - r;
+ n = 256;
+ /* skip utf8 continuation bytes */
+ while ((*file & 0xC0) == 0x80) {
+ ++file;
+ --n;
+ }
+ }
+ wfile = apr_palloc(pool, (r + n) * sizeof(apr_wchar_t));
+ wcscpy(wfile, wpre);
+ d = n;
+ if (rv = conv_utf8_to_ucs2(file, &n, wfile + r, &d)) {
+ return NULL;
+ }
+ for (ch = wfile + r; *ch; ++ch) {
+ if (*ch == ':' || *ch == '/' || *ch == '\\')
+ *ch = '_';
+ }
+ }
+ else
+#endif
+ {
+ char *nfile, *ch;
+ apr_size_t n = strlen(file) + 1;
+
+#if !APR_HAS_UNICODE_FS
+ apr_status_t rv;
+ apr_size_t r, d;
+ char *pre;
+
+ if (apr_os_level >= APR_WIN_2000) {
+ if (global)
+ pre = "Global\\";
+ else
+ pre = "Local\\";
+ }
+ else
+ pre = "";
+ r = strlen(pre);
+
+ if (n > 256 - r) {
+ file += n - 256 - r;
+ n = 256;
+ }
+ nfile = apr_palloc(pool, (r + n) * sizeof(apr_wchar_t));
+ memcpy(nfile, pre, r);
+ memcpy(nfile + r, file, n);
+#else
+ const apr_size_t r = 0;
+ if (n > 256) {
+ file += n - 256;
+ n = 256;
+ }
+ nfile = apr_pmemdup(pool, file, n);
+#endif
+ for (ch = nfile + r; *ch; ++ch) {
+ if (*ch == ':' || *ch == '/' || *ch == '\\')
+ *ch = '_';
+ }
+ }
+}
+
+
apr_status_t file_cleanup(void *thefile)
{
apr_file_t *file = thefile;
1.62 +9 -0 apr/include/arch/win32/fileio.h
Index: fileio.h
===================================================================
RCS file: /home/cvs/apr/include/arch/win32/fileio.h,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- fileio.h 27 Nov 2001 03:08:58 -0000 1.61
+++ fileio.h 8 Jan 2002 22:48:25 -0000 1.62
@@ -110,6 +110,15 @@
#endif /* APR_HAS_UNICODE_FS */
+/* Another Helper functions for the WinNT ApiW() functions. We need to
+ * derive some 'resource' names (max length 255 characters, prefixed with
+ * Global/ or Local/ on WinNT) from something that looks like a filename.
+ * Since 'resource' names never contain slashes, convert these to '_'s
+ * and return the appropriate char* or wchar* for ApiA or ApiW calls.
+ */
+
+void *res_name_from_filename(const char *file, int global, apr_pool_t *pool);
+
#define APR_FILE_MAX MAX_PATH
#define APR_FILE_BUFSIZE 4096