--- xmlIO.c.orig	2006-05-02 16:25:00.000000000 +0200
+++ xmlIO.c	2006-08-16 12:38:26.000000000 +0200
@@ -589,7 +589,7 @@
 int
 xmlCheckFilename (const char *path)
 {
-#ifdef HAVE_STAT
+#if defined(HAVE_STAT) && !defined(WIN32)
 	struct stat stat_buffer;
 #endif
 	if (path == NULL)
@@ -598,23 +598,62 @@
 #if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
 	{
 		int retval = 0;
-	
-		wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
-		if (wPath)
+
+		// One-time autodetect presence of _wstat. Not available for Win9x
+		static char inited = 0;
+		static int (*winwstat)(const wchar_t *path,struct _stat *buffer) = NULL;
+
+		if (inited == 0)
 		{
-			struct _stat stat_buffer;
-			
-			if (_wstat(wPath,&stat_buffer) == 0)
+			HANDLE msvcrt = NULL;
+			unsigned int oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+
+			msvcrt = LoadLibraryA("msvcrt.dll");
+			SetErrorMode(oldErrorMode);
+
+			if (msvcrt)
 			{
-				retval = 1;
+				winwstat = (int (*)(const wchar_t *,struct _stat *))GetProcAddress(msvcrt,"_wstat");
+				if (winwstat == NULL)
+					FreeLibrary(msvcrt);
+			}
+			inited = 1;
+		}
+
+		// Try utf-8 path first on systems capable
+		if (winwstat)
+		{
+			wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
+			if (wPath)
+			{
+				struct _stat stat_buffer;
 				
-				if (((stat_buffer.st_mode & S_IFDIR) == S_IFDIR))
-					retval = 2;
+				if (winwstat(wPath,&stat_buffer) == 0)
+				{
+					retval = 1;
+					
+					if (((stat_buffer.st_mode & S_IFDIR) == S_IFDIR))
+						retval = 2;
+				}
+		
+				free(wPath);
 			}
-	
-			free(wPath);
 		}
 
+		// Fallback: Path in utf-8 representation not present or win9x		
+		if ((winwstat == NULL) || (retval == 0))
+		{
+				struct _stat stat_buffer;
+				
+				if (_stat(path,&stat_buffer) == 0)
+				{
+					retval = 1;
+					
+					if (((stat_buffer.st_mode & S_IFDIR) == S_IFDIR))
+						retval = 2;
+				}
+		}
+		
 		return retval;
 	}
 #else
@@ -720,7 +759,7 @@
 static void *
 xmlFileOpen_real (const char *filename) {
     const char *path = NULL;
-    FILE *fd;
+    FILE *fd = NULL;
 
     if (filename == NULL)
         return(NULL);
@@ -752,21 +791,43 @@
 
 #if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
 	{
-		wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
-		if (wPath)
+		// One-time autodetect presence of _wfopen. Not available for Win9x
+		static char inited = 0;
+		static FILE *(*winwfopen)(const wchar_t *path,const wchar_t *mode) = NULL;
+
+		if (inited == 0)
 		{
-			fd = _wfopen(wPath, L"rb");
-			free(wPath);
+			HANDLE msvcrt = NULL;
+			unsigned int oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+
+			msvcrt = LoadLibraryA("msvcrt.dll");
+			SetErrorMode(oldErrorMode);
+
+			if (msvcrt)
+			{
+				winwfopen = (FILE *(*)(const wchar_t *,const wchar_t *))GetProcAddress(msvcrt,"_wfopen");
+				if (winwfopen == NULL)
+					FreeLibrary(msvcrt);
+			}
+			inited = 1;
+		}
+
+		// Try to open file unicode path safe. If not available or win9x fall thru to non-unicode safe fopen()
+		if (winwfopen)
+		{
+			wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
+			if (wPath)
+			{
+				fd = winwfopen(wPath, L"rb");
+				free(wPath);
+	   	}
    	}
-   	else
-   	{
-   	   fd = fopen(path, "rb");
-	   }
 	}	
-#else
-    fd = fopen(path, "r");
 #endif /* WIN32 */
-    if (fd == NULL) xmlIOErr(0, path);
+
+	if (fd == NULL)
+    	fd = fopen(path, "r");
+   if (fd == NULL) xmlIOErr(0, path);
     return((void *) fd);
 }
 
@@ -807,7 +868,7 @@
 static void *
 xmlFileOpenW (const char *filename) {
     const char *path = NULL;
-    FILE *fd;
+    FILE *fd = NULL;
 
     if (!strcmp(filename, "-")) {
 	fd = stdout;
@@ -834,21 +895,43 @@
 
 #if defined(WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
 	{
-		wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
-		if (wPath)
+		// One-time autodetect presence of _wfopen. Not available for Win9x
+		static char inited = 0;
+		static FILE *(*winwfopen)(const wchar_t *path,const wchar_t *mode) = NULL;
+
+		if (inited == 0)
 		{
-			fd = _wfopen(wPath, L"wb");
-			free(wPath);
-   	}
-   	else
-   	{
-	  	   fd = fopen(path, "wb");
-	  	}
+			HANDLE msvcrt = NULL;
+			unsigned int oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
+
+			msvcrt = LoadLibraryA("msvcrt.dll");
+			SetErrorMode(oldErrorMode);
+
+			if (msvcrt)
+			{
+				winwfopen = (FILE *(*)(const wchar_t *,const wchar_t *))GetProcAddress(msvcrt,"_wfopen");
+				if (winwfopen == NULL)
+					FreeLibrary(msvcrt);
+			}
+			inited = 1;
+		}
+
+		// Try to open file unicode path safe. If not available or win9x fall thru to non-unicode safe fopen()
+		if (winwfopen)
+		{
+			wchar_t *wPath = __xmlIOWin32UTF8ToWChar(path);
+			if (wPath)
+			{
+				fd = winwfopen(wPath, L"wb");
+				free(wPath);
+	   	}
+	   }
 	}
-#else
-  	   fd = fopen(path, "wb");
 #endif /* WIN32 */
 
+	if (fd == NULL)
+  	   fd = fopen(path, "wb");
+
 	 if (fd == NULL) xmlIOErr(0, path);
     return((void *) fd);
 }
@@ -3499,10 +3582,7 @@
     return(ret);
 }
 
-static int xmlSysIDExists(const char *URL) {
-#ifdef HAVE_STAT
-    int ret;
-    struct stat info;
+static int xmlNoNetExists(const char *URL) {
     const char *path;
 
     if (URL == NULL)
@@ -3522,11 +3602,8 @@
 #endif
     } else 
 	path = URL;
-    ret = stat(path, &info);
-    if (ret == 0)
-	return(1);
-#endif
-    return(0);
+	
+    return xmlCheckFilename(path);
 }
 
 /**
@@ -3570,7 +3647,7 @@
      */
     pref = xmlCatalogGetDefaults();
 
-    if ((pref != XML_CATA_ALLOW_NONE) && (!xmlSysIDExists(URL))) {
+    if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
         /*
          * Do a local lookup
          */
@@ -3597,7 +3674,7 @@
          * TODO: do an URI lookup on the reference
          */
         if ((resource != NULL)
-            && (!xmlSysIDExists((const char *) resource))) {
+            && (!xmlNoNetExists((const char *) resource))) {
             xmlChar *tmp = NULL;
 
             if ((ctxt != NULL) && (ctxt->catalogs != NULL) &&
@@ -3674,7 +3751,7 @@
 xmlParserInputPtr
 xmlLoadExternalEntity(const char *URL, const char *ID,
                       xmlParserCtxtPtr ctxt) {
-    if ((URL != NULL) && (xmlSysIDExists(URL) == 0)) {
+    if ((URL != NULL) && (xmlNoNetExists(URL) == 0)) {
 	char *canonicFilename;
 	xmlParserInputPtr ret;
 
@@ -3697,40 +3774,6 @@
  * 									*
  ************************************************************************/
 
-#ifdef LIBXML_CATALOG_ENABLED
-static int
-xmlNoNetExists(const char *URL)
-{
-#ifdef HAVE_STAT
-    int ret;
-    struct stat info;
-    const char *path;
-
-    if (URL == NULL)
-        return (0);
-
-    if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
-	path = &URL[17];
-#else
-	path = &URL[16];
-#endif
-    else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) || defined (__DJGPP__) && !defined(__CYGWIN__)
-        path = &URL[8];
-#else
-        path = &URL[7];
-#endif
-    } else
-        path = URL;
-    ret = stat(path, &info);
-    if (ret == 0)
-        return (1);
-#endif
-    return (0);
-}
-#endif
-
 /**
  * xmlNoNetExternalEntityLoader:
  * @URL:  the URL for the entity to load
