--- a/Win32OperatingSystem.st Sat Jun 20 11:16:54 2009 +0200
+++ b/Win32OperatingSystem.st Mon Jun 22 16:52:12 2009 +0200
@@ -5279,69 +5279,72 @@
isWritable:aPathName
"return true, if the given file is writable.
- For symbolic links, the pointed-to-file is checked."
+ For symbolic links, the pointed-to-file is checked.
+
+ In Windows, files can possibly be created in and deleted from directories marked as
+ read only. See http://support.microsoft.com/kb/326549. So we always return true
+ for directories."
%{
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( "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;
+ 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
+ } else if (__isUnicode16String(aPathName)) {
+ /*
+ * 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);
- }
+ 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
+ } else {
+ goto fail;
+ }
+
+ if (ret < 0) {
+ @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+ RETURN (false);
+ }
+ RETURN ( (ret & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) ? false : true);
+
+fail:;
%}.
^ self primitiveFailed
"
+ self isWritable:'c:\windows'
+ self isWritable:'c:\Dokumente und Einstellungen\stefan\Eigene Dateien'
self isWritable:'.'
self isWritable:'.' asUnicode16String
"
@@ -5351,16 +5354,16 @@
"return some object filled with info for the file 'aPathName';
the info (for which corresponding access methods are understood by
the returned object) is:
- type - a symbol giving the files type
- mode - numeric access mode
- uid - owners user id
- gid - owners group id
- size - files size
- id - files number (i.e. inode number)
- accessed - last access time (as Timestamp)
- modified - last modification time (as Timestamp)
- statusChanged - last status change time (as Timestamp)
- alternativeName - (windows only:) the MSDOS name of the file
+ type - a symbol giving the files type
+ mode - numeric access mode
+ uid - owners user id
+ gid - owners group id
+ size - files size
+ id - files number (i.e. inode number)
+ accessed - last access time (as Timestamp)
+ modified - last modification time (as Timestamp)
+ statusChanged - last status change time (as Timestamp)
+ alternativeName - (windows only:) the MSDOS name of the file
Some of the fields may be returned as nil on systems which do not provide
all of the information.
@@ -5392,165 +5395,165 @@
wchar_t _aPathName[MAX_PATH+1];
if (__isString(aPathName)) {
- 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;
+ 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;
+ 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;
+ goto badArgument;
#ifdef DO_WRAP_CALLS
{
- do {
- __threadErrno = 0;
- hFile = STX_API_CALL2( "FindFirstFileW", FindFirstFileW, _aPathName, &findStructW);
- } 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());
+ __threadErrno = __WIN32_ERR(GetLastError());
}
#endif
if (! hFile || (hFile == (HANDLE)(-1)) || (hFile == INVALID_HANDLE_VALUE)) {
- @global(LastErrorNumber) = __mkSmallInteger(__threadErrno);
+ @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 */
- }
-
- if (findStructW.cAlternateFileName[0] != '\0') {
- bcopy(findStructW.cAlternateFileName, alternativeFileNameBuffer, 14*sizeof(wchar_t));
- alternativeFileNameBuffer[14] = '\0';
- alternativeName = __MKU16STRING(alternativeFileNameBuffer); /* DOS name */
- }
-
- /*
- * simulate access bits
- */
- if (findStructW.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
- modeBits = 0444;
- } else {
- 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);
+ 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 */
+ }
+
+ if (findStructW.cAlternateFileName[0] != '\0') {
+ bcopy(findStructW.cAlternateFileName, alternativeFileNameBuffer, 14*sizeof(wchar_t));
+ alternativeFileNameBuffer[14] = '\0';
+ alternativeName = __MKU16STRING(alternativeFileNameBuffer); /* DOS name */
+ }
+
+ /*
+ * simulate access bits
+ */
+ if (findStructW.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+ modeBits = 0444;
+ } else {
+ modeBits = 0666;
+ }
+
+ if (findStructW.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ type = @symbol(directory);
+ modeBits = 0777; /* executable and WRITABLE - why? please refer to #isWritable: */
+ } 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.
- "/ now done lazyly in FileStatusInfo, when the path is accessed
- "/ path := self getLinkTarget:aPathName.
+ type := #symbolicLink.
+ "/ now done lazyly in FileStatusInfo, when the path is accessed
+ "/ path := self getLinkTarget:aPathName.
].
mode isNil ifTrue:[
- (self isDirectory:aPathName) ifTrue:[
- "/ the code above fails for root directories (these do not exist).
- "/ simulate here
- mode := 8r777.
- type := #directory.
- uid := gid := 0.
- size := 0.
- id := 0.
- atime := mtime := ctime := Timestamp now.
- ].
+ (self isDirectory:aPathName) ifTrue:[
+ "/ the code above fails for root directories (these do not exist).
+ "/ simulate here
+ mode := 8r777.
+ type := #directory.
+ uid := gid := 0.
+ size := 0.
+ id := 0.
+ atime := mtime := ctime := Timestamp now.
+ ].
].
mode notNil ifTrue:[
- atime isNil ifTrue:[
- atime := Timestamp day:aDay month:aMon year:aYr hour:aHr minutes:aMin seconds:aSec milliseconds:aMS.
- ].
- mtime isNil ifTrue:[
- mtime := Timestamp day:mDay month:mMon year:mYr hour:mHr minutes:mMin seconds:mSec milliseconds:mMS.
- ].
- 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
- uid:uid
- gid:gid
- size:size
- id:id
- accessed:atime
- modified:mtime
- created:ctime
- sourcePath:aPathName
- fullName:fileName
- alternativeName:alternativeName.
- ^ info
+ atime isNil ifTrue:[
+ atime := Timestamp day:aDay month:aMon year:aYr hour:aHr minutes:aMin seconds:aSec milliseconds:aMS.
+ ].
+ mtime isNil ifTrue:[
+ mtime := Timestamp day:mDay month:mMon year:mYr hour:mHr minutes:mMin seconds:mSec milliseconds:mMS.
+ ].
+ 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
+ uid:uid
+ gid:gid
+ size:size
+ id:id
+ accessed:atime
+ modified:mtime
+ created:ctime
+ sourcePath:aPathName
+ fullName:fileName
+ alternativeName:alternativeName.
+ ^ info
].
^ nil
@@ -5563,27 +5566,6 @@
"
"Modified: / 07-02-2007 / 10:30:14 / cg"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
!
mimeTypeForSuffix:aFileSuffix
@@ -16132,7 +16114,7 @@
!Win32OperatingSystem class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.368 2009-06-12 16:27:00 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.369 2009-06-22 14:52:12 stefan Exp $'
! !
Win32OperatingSystem initialize!