unicode filenames
authorClaus Gittinger <cg@exept.de>
Thu, 30 Oct 2008 16:30:33 +0100
changeset 11289 11c2bb7debc4
parent 11288 c71a04b0e26c
child 11290 4226ed9c9a94
unicode filenames
Win32OperatingSystem.st
--- a/Win32OperatingSystem.st	Thu Oct 30 14:18:13 2008 +0100
+++ b/Win32OperatingSystem.st	Thu Oct 30 16:30:33 2008 +0100
@@ -4519,16 +4519,15 @@
 !
 
 getCurrentDirectory
-
     |s size|
 
-    s := String new:200.
-    size := self primGetCurrentDirectory:200 string: s.
+    s := Unicode16String new:1024.
+    size := self primGetCurrentDirectoryW:1024 string: s.
     (size isNil or:[size == 0]) ifTrue:[^ ''].
-    ^ s copyFrom:1 to: size
-
-    "
-	self getCurrentDirectory
+    ^ (s copyFrom:1 to: size) asSingleByteStringIfPossible
+
+    "
+     self getCurrentDirectory 
     "
 !
 
@@ -4668,31 +4667,44 @@
 !
 
 getDriveType:aPathName
-    "return true, if the given file is writable.
-     For symbolic links, the pointed-to-file is checked."
+    "returns:
+        0 -> Unknown
+        1 -> Invalid
+        2 -> removable
+        3 -> fixed
+        4 -> remote
+        5 -> cdrom
+        6 -> ramdisk.
+    This is a stupid interface - do not use."
 
 %{
     int ret;
 
     if (__isString(aPathName)) {
 #ifdef DO_WRAP_CALLS
-	char _aPathName[MAXPATHLEN];
-
-	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetDriveType", GetDriveType, _aPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributes((char *) __stringVal(aPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	RETURN (ret);
+        char _aPathName[MAXPATHLEN];
+
+        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetDriveType", GetDriveType, _aPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributes((char *) __stringVal(aPathName));
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        RETURN (__MKSMALLINT(ret));
     }
 %}.
     ^ self primitiveFailed
+
+    "
+     self getDriveType:'x:\'  
+     self getDriveType:'C:\'  
+     self getDriveType:'D:\'
+    "
 !
 
 getFileVersionInfoOf:aPathName
@@ -4803,68 +4815,66 @@
      if you need to check for this, use #linkInfo:."
 
 %{
+    int ret;
+
     if (__isString(aPathName)) {
-	int ret;
-
-#ifdef DO_WRAP_CALLS
-	char _aPathName[MAXPATHLEN];
-
-	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributesA((char *) __stringVal(aPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN ( false );
-	}
-	RETURN ( (ret & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
-    }
-
-#ifdef SUPPORT_WIDE_CHAR_FILENAMES
-    if (__isUnicode16String(aPathName)) {
-	int ret;
-
 #ifdef DO_WRAP_CALLS
-	unsigned char _wPathName[MAXPATHLEN];
-	int i;
-
-# if 1
-	for (i=0; i<MAXPATHLEN; i++) {
-	    _wPathName[i] = __unicode16StringVal(aPathName)[i];
-	    if (_wPathName[i] == 0) break;
-	}
-# else
-	wstrncpy(_wPathName, __unicode16StringVal(aPathName), MAXPATHLEN-1); _wPathName[MAXPATHLEN-1] = '\0';
-# endif
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributesW(__unicode16StringVal(wPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN ( false );
-	}
-	RETURN ( (ret & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
-    }
-#endif /* SUPPORT_WIDE_CHAR_FILENAMES */
+        char _aPathName[MAXPATHLEN];
+
+        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesA((char *) __stringVal(aPathName));
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN ( false );
+        }
+        RETURN ( (ret & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
+    }
+
+    if (__isUnicode16String(aPathName)) {
+        wchar_t _wPathName[MAXPATHLEN+1];
+        int i, l;
+
+        l = __unicode16StringSize(aPathName);
+        if (l > MAXPATHLEN) l = MAXPATHLEN;
+        for (i=0; i<l; i++) {
+            _wPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _wPathName[i] = 0;
+#ifdef DO_WRAP_CALLS
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesW(_wPathName);
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN ( false );
+        }
+        RETURN ( (ret & FILE_ATTRIBUTE_DIRECTORY) ? true : false);
+    }
 %}.
     ^ self primitiveFailed
 
     "an alternative implementation would be:
-	^ (self infoOf:aPathName) type == #directory
+        ^ (self infoOf:aPathName) type == #directory
+    "
+    "
+     self isDirectory:'.'  
+     self isDirectory:'.' asUnicode16String
     "
 
     "Modified: / 05-07-2006 / 17:23:42 / cg"
@@ -4891,27 +4901,60 @@
 
     if (__isString(aPathName)) {
 #ifdef DO_WRAP_CALLS
-	char _aPathName[MAXPATHLEN];
-
-	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributes", GetFileAttributes, _aPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributes((char *) __stringVal(aPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN ( false );
-	}
-	RETURN ( (ret & FILE_ATTRIBUTE_HIDDEN) ? true : false);
+        char _aPathName[MAXPATHLEN];
+
+        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributes", GetFileAttributes, _aPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributes((char *) __stringVal(aPathName));
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN ( false );
+        }
+        RETURN ( (ret & FILE_ATTRIBUTE_HIDDEN) ? true : false);
+    }
+
+    if (__isUnicode16String(aPathName)) {
+        wchar_t _wPathName[MAXPATHLEN+1];
+        int i, l;
+
+        l = __unicode16StringSize(aPathName);
+        if (l > MAXPATHLEN) l = MAXPATHLEN;
+        for (i=0; i<l; i++) {
+            _wPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _wPathName[i] = 0;
+#ifdef DO_WRAP_CALLS
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesW(_wPathName);
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN ( false );
+        }
+        RETURN ( (ret & FILE_ATTRIBUTE_HIDDEN) ? true : false);
     }
 %}.
     ^ self primitiveFailed
+
+    "
+     self isHidden:'.'      
+     self isHidden:'.' asUnicode16String  
+    "
 !
 
 isReadable:aPathName
@@ -4920,74 +4963,73 @@
 
 %{
     if (__isString(aPathName)) {
-	int ret;
-
-	/*
-	 * under windows, all files are readable ...
-	 * so, only check for the files existence here.
-	 */
+        int ret;
+
+        /*
+         * under windows, all files are readable ...
+         * so, only check for the files existence here.
+         */
 #ifdef DO_WRAP_CALLS
-	char _aPathName[MAXPATHLEN];
-
-	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributesA((char *) __stringVal(aPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN (false);
-	}
-	RETURN (true);
-    }
-
-#ifdef SUPPORT_WIDE_CHAR_FILENAMES
+        char _aPathName[MAXPATHLEN];
+
+        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesA((char *) __stringVal(aPathName));
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN (false);
+        }
+        RETURN (true);
+    }
+
     if (__isUnicode16String(aPathName)) {
-	int ret;
-
-	/*
-	 * under windows, all files are readable ...
-	 * so, only check for the files existence here.
-	 */
+        int ret;
+
+        /*
+         * under windows, all files are readable ...
+         * so, only check for the files existence here.
+         */
+        wchar_t _wPathName[MAXPATHLEN+1];
+        int i, l;
+
+        l = __unicode16StringSize(aPathName);
+        if (l > MAXPATHLEN) l = MAXPATHLEN;
+        for (i=0; i<l; i++) {
+            _wPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _wPathName[i] = 0;
 #ifdef DO_WRAP_CALLS
-	unsigned short _wPathName[MAXPATHLEN];
-
-# if 1
-	int i;
-	for (i=0; i<MAXPATHLEN; i++) {
-	    _wPathName[i] = __unicode16StringVal(aPathName)[i];
-	    if (_wPathName[i] == 0) break;
-	}
-# else
-	wstrncpy(_wPathName, __unicode16StringVal(aPathName), MAXPATHLEN-1); _wPathName[MAXPATHLEN-1] = '\0';
-# endif
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributesW(__unicode16StringVal(aPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN (false);
-	}
-	RETURN (true);
-    }
-#endif /* SUPPORT_WIDE_CHAR_FILENAMES */
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesW(_wPathName);
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN (false);
+        }
+        RETURN (true);
+    }
 %}.
     ^ self primitiveFailed
 
-    "Modified: / 05-07-2006 / 17:23:39 / cg"
+    "
+     self isReadable:'.'  
+     self isReadable:'.' asUnicode16String 
+    "
 !
 
 isValidPath:aPathName
@@ -4999,56 +5041,53 @@
 
     if (__isString(aPathName) || __isSymbol(aPathName)) {
 #ifdef DO_WRAP_CALLS
-	char _aPathName[MAXPATHLEN];
-
-	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributesA((char *) __stringVal(aPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN ( false );
-	}
-	RETURN (true);
-    }
-
-#ifdef SUPPORT_WIDE_CHAR_FILENAMES
+        char _aPathName[MAXPATHLEN];
+
+        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesA", GetFileAttributesA, _aPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesA((char *) __stringVal(aPathName));
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN ( false );
+        }
+        RETURN (true);
+    }
+
     if (__isUnicode16String(aPathName)) {
+        wchar_t _wPathName[MAXPATHLEN+1];
+        int i, l;
+
+        l = __unicode16StringSize(aPathName);
+        if (l > MAXPATHLEN) l = MAXPATHLEN;
+        for (i=0; i<l; i++) {
+            _wPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _wPathName[i] = 0;
 #ifdef DO_WRAP_CALLS
-	unsigned short _wPathName[MAXPATHLEN];
-# if 1
-	int i;
-	for (i=0; i<MAXPATHLEN; i++) {
-	    _wPathName[i] = __unicode16StringVal(aPathName)[i];
-	    if (_wPathName[i] == 0) break;
-	}
-# else
-	wstrncpy(_wPathName, __unicode16StringVal(aPathName), MAXPATHLEN-1); _wPathName[MAXPATHLEN-1] = '\0';
-# endif
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributesW(__unicode16StringVal(wPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN ( false );
-	}
-	RETURN (true);
-    }
-#endif /* SUPPORT_WIDE_CHAR_FILENAMES */
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesW(_wPathName);
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN ( false );
+        }
+        RETURN (true);
+    }
 %}.
     ^ self primitiveFailed
 
@@ -5064,27 +5103,65 @@
 
     if (__isString(aPathName)) {
 #ifdef DO_WRAP_CALLS
-	char _aPathName[MAXPATHLEN];
-
-	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-	do {
-	    __threadErrno = 0;
-	    ret = STX_API_CALL1( "GetFileAttributes", GetFileAttributes, _aPathName);
-	} while ((ret < 0) && (__threadErrno == EINTR));
-#else
-	ret = GetFileAttributes((char *) __stringVal(aPathName));
-	if (ret < 0) {
-	    __threadErrno = __WIN32_ERR(GetLastError());
-	}
-#endif
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
-	    RETURN ( false );
-	}
-	RETURN ( (ret & FILE_ATTRIBUTE_READONLY) ? false : true);
+        char _aPathName[MAXPATHLEN];
+
+        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributes", GetFileAttributes, _aPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributes((char *) __stringVal(aPathName));
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN ( false );
+        }
+        RETURN ( (ret & FILE_ATTRIBUTE_READONLY) ? false : true);
+    }
+    if (__isUnicode16String(aPathName)) {
+        int ret;
+
+        /*
+         * under windows, all files are readable ...
+         * so, only check for the files existence here.
+         */
+        wchar_t _wPathName[MAXPATHLEN+1];
+        int i, l;
+
+        l = __unicode16StringSize(aPathName);
+        if (l > MAXPATHLEN) l = MAXPATHLEN;
+        for (i=0; i<l; i++) {
+            _wPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _wPathName[i] = 0;
+#ifdef DO_WRAP_CALLS
+        do {
+            __threadErrno = 0;
+            ret = STX_API_CALL1( "GetFileAttributesW", GetFileAttributesW, _wPathName);
+        } while ((ret < 0) && (__threadErrno == EINTR));
+#else
+        ret = GetFileAttributesW(_wPathName);
+        if (ret < 0) {
+            __threadErrno = __WIN32_ERR(GetLastError());
+        }
+#endif
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+            RETURN (false);
+        }
+        RETURN ( (ret & FILE_ATTRIBUTE_READONLY) ? false : true);
     }
 %}.
     ^ self primitiveFailed
+
+    "
+     self isWritable:'.'  
+     self isWritable:'.' asUnicode16String   
+    "
 !
 
 linkInfoOf:aPathName
@@ -5118,109 +5195,130 @@
      fileName alternativeName|
 
 %{
+    HANDLE hFile = (HANDLE)0;
     int ret;
-    char alternativeFileNameBuffer[15];
-    char fileNameBuffer[MAX_PATH+1];
-
+    wchar_t alternativeFileNameBuffer[15];
+    wchar_t fileNameBuffer[MAX_PATH+1];
+    FILETIME tempFileTime;
+    SYSTEMTIME creationTime;
+    SYSTEMTIME accessTime;
+    SYSTEMTIME modificationTime;
+    int modeBits = 0;
+    WIN32_FIND_DATAW findStructW;
     unsigned INT ino;
+    wchar_t _aPathName[MAX_PATH+1];
 
     if (__isString(aPathName)) {
-        HANDLE hFile;
-        FILETIME tempFileTime;
-        SYSTEMTIME creationTime;
-        SYSTEMTIME accessTime;
-        SYSTEMTIME modificationTime;
-        int modeBits = 0;
-        WIN32_FIND_DATA findStruct;
-
+        int i;
+        int l = __stringSize(aPathName);
+        if (l > MAX_PATH) l = MAX_PATH;
+
+        for (i=0; i<l; i++) {
+            _aPathName[i] = __stringVal(aPathName)[i];
+        }
+        _aPathName[i] = 0;
+    } else if (__isUnicode16String(aPathName)) {
+        int i;
+        int l = __unicode16StringSize(aPathName);
+        if (l > MAX_PATH) l = MAX_PATH;
+
+        for (i=0; i<l; i++) {
+            _aPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _aPathName[i] = 0;
+    } else
+        goto badArgument;
+        
 #ifdef DO_WRAP_CALLS
-        {
-            char _aPathName[MAXPATHLEN];
-
-            strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-            do {
-                __threadErrno = 0;
-                hFile = STX_API_CALL2( "FindFirstFile", FindFirstFile, _aPathName, &findStruct);
-            } while ((hFile < 0) && (__threadErrno == EINTR));
+    {
+        do {
+            __threadErrno = 0;
+            hFile = STX_API_CALL2( "FindFirstFileW", FindFirstFileW, _aPathName, &findStructW);
+        } while ((hFile < 0) && (__threadErrno == EINTR));
+    }
+#else
+    hFile = FindFirstFileW(_aPathName, &findStructW);
+    if (hFile < 0) {
+        __threadErrno = __WIN32_ERR(GetLastError());
+    }
+#endif
+
+    if (! hFile || (hFile == (HANDLE)(-1)) || (hFile == INVALID_HANDLE_VALUE)) {
+        @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+    } else {
+        FindClose(hFile);
+
+        id = __mkSmallInteger(0);   /* could get it by opening ... */
+        size = __MKLARGEINT64(1, findStructW.nFileSizeLow, findStructW.nFileSizeHigh);
+
+        if (findStructW.cFileName[0] != '\0') {
+            bcopy(findStructW.cFileName, fileNameBuffer, MAX_PATH*sizeof(wchar_t));
+            fileNameBuffer[MAX_PATH] = '\0';
+            fileName = __MKU16STRING(fileNameBuffer);             /* FULL name */
         }
-#else
-        hFile = FindFirstFile(__stringVal(aPathName), &findStruct);
-        if (hFile < 0) {
-            __threadErrno = __WIN32_ERR(GetLastError());
+
+        if (findStructW.cAlternateFileName[0] != '\0') {
+            bcopy(findStructW.cAlternateFileName, alternativeFileNameBuffer, 14*sizeof(wchar_t));
+            alternativeFileNameBuffer[14] = '\0';
+            alternativeName = __MKU16STRING(alternativeFileNameBuffer); /* DOS name */
         }
-#endif
-        if (! hFile || (hFile == (HANDLE)(-1)) || (hFile == INVALID_HANDLE_VALUE)) {
-            @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+
+        /*
+         * simulate access bits
+         */
+        if (findStructW.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+            modeBits = 0444;
         } else {
-            FindClose(hFile);
-
-            id = __mkSmallInteger(0);   /* could get it by opening ... */
-            size = __MKLARGEINT64(1, findStruct.nFileSizeLow, findStruct.nFileSizeHigh);
-
-            if (findStruct.cFileName[0] != '\0') {
-                bcopy(findStruct.cFileName, fileNameBuffer, MAX_PATH);
-                fileNameBuffer[MAX_PATH] = '\0';
-                fileName = __MKSTRING(fileNameBuffer);             /* FULL name */
-            }
-
-            if (findStruct.cAlternateFileName[0] != '\0') {
-                bcopy(findStruct.cAlternateFileName, alternativeFileNameBuffer, 14);
-                alternativeFileNameBuffer[14] = '\0';
-                alternativeName = __MKSTRING(alternativeFileNameBuffer); /* DOS name */
-            }
-
-            /*
-             * simulate access bits
-             */
-            if (findStruct.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
-                modeBits = 0444;
-            } else {
-                modeBits = 0666;
-            }
-
-            if (findStruct.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-                type = @symbol(directory);
-                modeBits |= 0111;   /* executable */
-            } else {
-                type = @symbol(regular);
-            }
-
-            mode = __mkSmallInteger(modeBits);
-
-            /*
-             * sigh - convert from stupid time to useful time
-             */
-            FileTimeToLocalFileTime(&findStruct.ftCreationTime, &tempFileTime);
-            FileTimeToSystemTime(&tempFileTime, &creationTime);
-            FileTimeToLocalFileTime(&findStruct.ftLastAccessTime, &tempFileTime);
-            FileTimeToSystemTime(&tempFileTime, &accessTime);
-            FileTimeToLocalFileTime(&findStruct.ftLastWriteTime, &tempFileTime);
-            FileTimeToSystemTime(&tempFileTime, &modificationTime);
-            aYr  = __mkSmallInteger(accessTime.wYear);
-            aMon = __mkSmallInteger(accessTime.wMonth);
-            aDay = __mkSmallInteger(accessTime.wDay);
-            aHr  = __mkSmallInteger(accessTime.wHour);
-            aMin = __mkSmallInteger(accessTime.wMinute);
-            aSec = __mkSmallInteger(accessTime.wSecond);
-            aMS  = __mkSmallInteger(accessTime.wMilliseconds);
-
-            mYr  = __mkSmallInteger(modificationTime.wYear);
-            mMon = __mkSmallInteger(modificationTime.wMonth);
-            mDay = __mkSmallInteger(modificationTime.wDay);
-            mHr  = __mkSmallInteger(modificationTime.wHour);
-            mMin = __mkSmallInteger(modificationTime.wMinute);
-            mSec = __mkSmallInteger(modificationTime.wSecond);
-            mMS  = __mkSmallInteger(modificationTime.wMilliseconds);
-
-            cYr  = __mkSmallInteger(creationTime.wYear);
-            cMon = __mkSmallInteger(creationTime.wMonth);
-            cDay = __mkSmallInteger(creationTime.wDay);
-            cHr  = __mkSmallInteger(creationTime.wHour);
-            cMin = __mkSmallInteger(creationTime.wMinute);
-            cSec = __mkSmallInteger(creationTime.wSecond);
-            cMS  = __mkSmallInteger(creationTime.wMilliseconds);
+            modeBits = 0666;
+        }
+
+        if (findStructW.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+            type = @symbol(directory);
+            modeBits |= 0111;   /* executable */
+        } else {
+            type = @symbol(regular);
         }
-    }
+
+        mode = __mkSmallInteger(modeBits);
+
+        /*
+         * sigh - convert from stupid time to useful time
+         */
+        FileTimeToLocalFileTime(&findStructW.ftCreationTime, &tempFileTime);
+        FileTimeToSystemTime(&tempFileTime, &creationTime);
+
+        FileTimeToLocalFileTime(&findStructW.ftLastAccessTime, &tempFileTime);
+        FileTimeToSystemTime(&tempFileTime, &accessTime);
+
+        FileTimeToLocalFileTime(&findStructW.ftLastWriteTime, &tempFileTime);
+        FileTimeToSystemTime(&tempFileTime, &modificationTime);
+
+        aYr  = __mkSmallInteger(accessTime.wYear);
+        aMon = __mkSmallInteger(accessTime.wMonth);
+        aDay = __mkSmallInteger(accessTime.wDay);
+        aHr  = __mkSmallInteger(accessTime.wHour);
+        aMin = __mkSmallInteger(accessTime.wMinute);
+        aSec = __mkSmallInteger(accessTime.wSecond);
+        aMS  = __mkSmallInteger(accessTime.wMilliseconds);
+
+        mYr  = __mkSmallInteger(modificationTime.wYear);
+        mMon = __mkSmallInteger(modificationTime.wMonth);
+        mDay = __mkSmallInteger(modificationTime.wDay);
+        mHr  = __mkSmallInteger(modificationTime.wHour);
+        mMin = __mkSmallInteger(modificationTime.wMinute);
+        mSec = __mkSmallInteger(modificationTime.wSecond);
+        mMS  = __mkSmallInteger(modificationTime.wMilliseconds);
+
+        cYr  = __mkSmallInteger(creationTime.wYear);
+        cMon = __mkSmallInteger(creationTime.wMonth);
+        cDay = __mkSmallInteger(creationTime.wDay);
+        cHr  = __mkSmallInteger(creationTime.wHour);
+        cMin = __mkSmallInteger(creationTime.wMinute);
+        cSec = __mkSmallInteger(creationTime.wSecond);
+        cMS  = __mkSmallInteger(creationTime.wMilliseconds);
+    }
+
+  badArgument: ;
 %}.
     (aPathName endsWith:'.lnk') ifTrue:[
         type := #symbolicLink.
@@ -5231,7 +5329,7 @@
     mode isNil ifTrue:[
         (self isDirectory:aPathName) ifTrue:[
             "/ the code above fails for root directories (these do not exist).
-            "/ simulate
+            "/ simulate here
             mode := 8r777.
             type := #directory.
             uid := gid := 0.
@@ -5250,7 +5348,12 @@
         ctime isNil ifTrue:[
             ctime := Timestamp day:cDay month:cMon year:cYr hour:cHr minutes:cMin seconds:cSec milliseconds:cMS.
         ].
-
+        fileName notNil ifTrue:[
+            fileName := fileName asSingleByteStringIfPossible
+        ].
+        alternativeName notNil ifTrue:[
+            alternativeName := alternativeName asSingleByteStringIfPossible
+        ].
         info := FileStatusInfo
                     type:type
                     mode:mode
@@ -5277,6 +5380,27 @@
    "
 
     "Modified: / 07-02-2007 / 10:30:14 / cg"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 !
 
 mimeTypeForSuffix:aFileSuffix
@@ -5356,10 +5480,22 @@
     self primitiveFailed.
 
     "
-    |s size|
-    s := String new:200.
-    size := self primGetCurrentDirectory:200 string: s.
-    s copyFrom:1 to: size
+     |s size|
+     s := String new:200.
+     size := self primGetCurrentDirectory:200 string: s.
+     s copyFrom:1 to: size
+    "
+!
+
+primGetCurrentDirectoryW: size string: string
+    <apicall: ulong "GetCurrentDirectoryW" ( ulong pointer ) module: "kernel32.dll" >
+    self primitiveFailed.
+
+    "
+     |s size|
+     s := Unicode16String new:200.
+     size := self primGetCurrentDirectoryW:200 string: s.
+     s copyFrom:1 to: size
     "
 !
 
@@ -5378,58 +5514,112 @@
      from what you expect."
 
 %{  /* xxSTACK: 16000 */
-
+#define NO_NT4_0_COMPATIBILITY
     if (__isStringLike(aPathName)) {
-	char nameBuffer[MAXPATHLEN + 1 + MAXPATHLEN + 1];
-	char *pFinal;
-	int rslt;
+        char nameBuffer[MAXPATHLEN + 1 + MAXPATHLEN + 1];
+        char *pFinal;
+        int rslt;
 
 #ifdef DO_WRAP_CALLS
-	char _aPathName[MAXPATHLEN];
-
-	strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
-	do {
-	    __threadErrno = 0;
-	    rslt = STX_API_CALL4( "GetFullPathName", GetFullPathName, _aPathName, sizeof(nameBuffer), nameBuffer, &pFinal);
-	} while ((rslt < 0) && (__threadErrno == EINTR));
-#else
-	rslt = GetFullPathName(__stringVal(aPathName), sizeof(nameBuffer), nameBuffer, &pFinal);
-#endif
-
-	if (rslt > 0) {
-	    /*
-	     * Attention: GetLongPathName is not available on old NT4.0/W95/W98
-	     */
-	    static FARPROC GetLongPathName_entry = NULL;
+        char _aPathName[MAXPATHLEN];
+
+        strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0';
+        do {
+            __threadErrno = 0;
+            rslt = STX_API_CALL4( "GetFullPathName", GetFullPathName, _aPathName, sizeof(nameBuffer), nameBuffer, &pFinal);
+        } while ((rslt < 0) && (__threadErrno == EINTR));
+#else
+        rslt = GetFullPathName(__stringVal(aPathName), sizeof(nameBuffer), nameBuffer, &pFinal);
+#endif
+
+        if (rslt > 0) {
+            /*
+             * Attention: GetLongPathName is not available on old NT4.0/W95/W98
+             */
+            static FARPROC GetLongPathName_entry = NULL;
 #ifdef NO_NT4_0_COMPATIBILITY
-	    GetLongPathName_entry = (FARPROC) GetLongPathName;
-#else
-	    if (GetLongPathName_entry == NULL) {
-		GetLongPathName_entry = __get_kernel32_functionAddress("GetLongPathNameA");
-	    }
+            GetLongPathName_entry = (FARPROC) GetLongPathName;
+#else
+            if (GetLongPathName_entry == NULL) {
+                GetLongPathName_entry = __get_kernel32_functionAddress("GetLongPathNameA");
+            }
 #endif /* NO_NT4_0_COMPATIBILITY */
 
-	    if (GetLongPathName_entry) {
+            if (GetLongPathName_entry) {
 #ifdef DO_WRAP_CALLS
-		do {
-		    __threadErrno = 0;
-		    rslt = STX_API_CALL3( "GetLongPathName", GetLongPathName_entry, nameBuffer, nameBuffer, sizeof(nameBuffer));
-		} while ((rslt < 0) && (__threadErrno == EINTR));
-#else
-		rslt = (*GetLongPathName_entry)(nameBuffer, nameBuffer, sizeof(nameBuffer));
-#endif
-	    }
-	}
-	if (rslt > 0) {
-	    RETURN ( __MKSTRING(nameBuffer) );
-	}
-	__threadErrno = __WIN32_ERR(GetLastError());
+                do {
+                    __threadErrno = 0;
+                    rslt = STX_API_CALL3( "GetLongPathName", GetLongPathName_entry, nameBuffer, nameBuffer, sizeof(nameBuffer));
+                } while ((rslt < 0) && (__threadErrno == EINTR));
+#else
+                rslt = (*GetLongPathName_entry)(nameBuffer, nameBuffer, sizeof(nameBuffer));
+#endif
+            }
+        }
+        if (rslt > 0) {
+            RETURN ( __MKSTRING(nameBuffer) );
+        }
+        __threadErrno = __WIN32_ERR(GetLastError());
+        RETURN (nil);
+    }
+    if (__isUnicode16String(aPathName)) {
+        wchar_t nameBuffer[MAXPATHLEN + 1 + MAXPATHLEN + 1];
+        char *pFinal;
+        int rslt;
+        wchar_t _aPathName[MAXPATHLEN+1];
+        int i, l;
+
+        l = __unicode16StringSize(aPathName);
+        if (l > MAXPATHLEN) l = MAXPATHLEN;
+        for (i=0; i<l; i++) {
+            _aPathName[i] = __unicode16StringVal(aPathName)[i];
+        }
+        _aPathName[i] = 0;
+
+#ifdef DO_WRAP_CALLS
+        do {
+            __threadErrno = 0;
+            rslt = STX_API_CALL4( "GetFullPathNameW", GetFullPathNameW, _aPathName, MAXPATHLEN, nameBuffer, &pFinal);
+        } while ((rslt < 0) && (__threadErrno == EINTR));
+#else
+        rslt = GetFullPathName(_aPathName, MAXPATHLEN, nameBuffer, &pFinal);
+#endif
+        if (rslt > 0) {
+            /*
+             * Attention: GetLongPathName is not available on old NT4.0/W95/W98
+             */
+            static FARPROC GetLongPathNameW_entry = NULL;
+#ifdef NO_NT4_0_COMPATIBILITY
+            GetLongPathNameW_entry = (FARPROC) GetLongPathNameW;
+#else
+            if (GetLongPathNameW_entry == NULL) {
+                GetLongPathNameW_entry = __get_kernel32_functionAddress("GetLongPathNameW");
+            }
+#endif /* NO_NT4_0_COMPATIBILITY */
+
+            if (GetLongPathNameW_entry) {
+#ifdef DO_WRAP_CALLS
+                do {
+                    __threadErrno = 0;
+                    rslt = STX_API_CALL3( "GetLongPathNameW", GetLongPathNameW_entry, nameBuffer, nameBuffer, MAXPATHLEN);
+                } while ((rslt < 0) && (__threadErrno == EINTR));
+#else
+                rslt = (*GetLongPathNameW_entry)(nameBuffer, nameBuffer, MAXPATHLEN);
+#endif
+            }
+        }
+        if (rslt > 0) {
+            RETURN ( __MKU16STRING(nameBuffer) );
+        }
+        __threadErrno = __WIN32_ERR(GetLastError());
     }
 %}.
     ^ nil
-"
-self primPathNameOf:'.'
-"
+
+    "
+     self primPathNameOf:'.' 
+     self primPathNameOf:'.' asUnicode16String
+    "
 !
 
 primSetCurrentDirectory:pathName
@@ -15646,7 +15836,7 @@
 !Win32OperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.351 2008-10-21 14:08:10 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.352 2008-10-30 15:30:33 cg Exp $'
 ! !
 
 Win32OperatingSystem initialize!