3620 WIN32_FIND_DATA wfd; |
3620 WIN32_FIND_DATA wfd; |
3621 char szGotPath[MAX_PATH]; |
3621 char szGotPath[MAX_PATH]; |
3622 IPersistFile *ppf; |
3622 IPersistFile *ppf; |
3623 |
3623 |
3624 if (! __isString(aPathName)) { |
3624 if (! __isString(aPathName)) { |
3625 console_fprintf(stderr, "invalid argument\n"); |
3625 console_fprintf(stderr, "invalid argument\n"); |
3626 goto error; |
3626 goto error; |
3627 } |
3627 } |
3628 |
3628 |
3629 hres = CoInitialize(NULL); |
3629 hres = CoInitialize(NULL); |
3630 if (! SUCCEEDED(hres)) { |
3630 if (! SUCCEEDED(hres)) { |
3631 console_fprintf(stderr, "Could not open the COM library\n"); |
3631 console_fprintf(stderr, "Could not open the COM library\n"); |
3632 goto error; |
3632 goto error; |
3633 } |
3633 } |
3634 |
3634 |
3635 hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, |
3635 hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, |
3636 &IID_IShellLink, (LPVOID *)&psl); |
3636 &IID_IShellLink, (LPVOID *)&psl); |
3637 if (SUCCEEDED(hres)) { |
3637 if (SUCCEEDED(hres)) { |
3638 hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf); |
3638 hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf); |
3639 |
3639 |
3640 if (SUCCEEDED(hres)) { |
3640 if (SUCCEEDED(hres)) { |
3641 WORD wsz[MAX_PATH]; |
3641 WORD wsz[MAX_PATH]; |
3642 |
3642 |
3643 MultiByteToWideChar(CP_ACP, 0, __stringVal(aPathName), -1, wsz, MAX_PATH); |
3643 MultiByteToWideChar(CP_ACP, 0, __stringVal(aPathName), -1, wsz, MAX_PATH); |
3644 |
3644 |
3645 hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); |
3645 hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); |
3646 if (SUCCEEDED(hres)) { |
3646 if (SUCCEEDED(hres)) { |
3647 #if 0 |
3647 #if 0 |
3648 hres = psl->lpVtbl->Resolve(psl, 0, SLR_ANY_MATCH|SLR_NO_UI); |
3648 hres = psl->lpVtbl->Resolve(psl, 0, SLR_ANY_MATCH|SLR_NO_UI); |
3649 #endif |
3649 #endif |
3650 if (SUCCEEDED(hres)) { |
3650 if (SUCCEEDED(hres)) { |
3651 hres = psl->lpVtbl->GetPath(psl, szGotPath, MAX_PATH, |
3651 hres = psl->lpVtbl->GetPath(psl, szGotPath, MAX_PATH, |
3652 (WIN32_FIND_DATA *)&wfd, 0 /* SLGP_SHORTPATH */ ); |
3652 (WIN32_FIND_DATA *)&wfd, 0 /* SLGP_SHORTPATH */ ); |
3653 if (!SUCCEEDED(hres)) { |
3653 if (!SUCCEEDED(hres)) { |
3654 console_fprintf(stderr, "GetPath failed!\n"); |
3654 console_fprintf(stderr, "GetPath failed!\n"); |
3655 } else { |
3655 } else { |
3656 #if 0 |
3656 #if 0 |
3657 console_printf("This points to %s\n", wfd.cFileName); console_fflush(stdout); |
3657 console_printf("This points to %s\n", wfd.cFileName); console_fflush(stdout); |
3658 console_printf("Path is %s\n", szGotPath); console_fflush(stdout); |
3658 console_printf("Path is %s\n", szGotPath); console_fflush(stdout); |
3659 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { |
3659 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { |
3660 console_printf("This is a directory\n"); console_fflush(stdout); |
3660 console_printf("This is a directory\n"); console_fflush(stdout); |
3661 } |
3661 } |
3662 #endif |
3662 #endif |
3663 resolvedPath = __MKSTRING(szGotPath); |
3663 resolvedPath = __MKSTRING(szGotPath); |
3664 #if 0 |
3664 #if 0 |
3665 hres = psl->lpVtbl->GetWorkingDirectory(psl, szGotPath, MAX_PATH); |
3665 hres = psl->lpVtbl->GetWorkingDirectory(psl, szGotPath, MAX_PATH); |
3666 if (!SUCCEEDED(hres)) { |
3666 if (!SUCCEEDED(hres)) { |
3667 console_fprintf(stderr, "GetWorkingDirectory failed!\n"); |
3667 console_fprintf(stderr, "GetWorkingDirectory failed!\n"); |
3668 } else { |
3668 } else { |
3669 console_printf("In Directory %s\n", szGotPath); |
3669 console_printf("In Directory %s\n", szGotPath); |
3670 } |
3670 } |
3671 #endif |
3671 #endif |
3672 } |
3672 } |
3673 } |
3673 } |
3674 } else { |
3674 } else { |
3675 console_fprintf(stderr, "IPersistFile Load Error\n"); |
3675 console_fprintf(stderr, "IPersistFile Load Error\n"); |
3676 } |
3676 } |
3677 ppf->lpVtbl->Release(ppf); |
3677 ppf->lpVtbl->Release(ppf); |
3678 } else { |
3678 } else { |
3679 console_fprintf(stderr, "QueryInterface Error\n"); |
3679 console_fprintf(stderr, "QueryInterface Error\n"); |
3680 } |
3680 } |
3681 psl->lpVtbl->Release(psl); |
3681 psl->lpVtbl->Release(psl); |
3682 } else { |
3682 } else { |
3683 console_fprintf(stderr, "CoCreateInstance Error - hres = %08x\n", hres); |
3683 console_fprintf(stderr, "CoCreateInstance Error - hres = %08x\n", hres); |
3684 } |
3684 } |
3685 error: ; |
3685 error: ; |
3686 %}. |
3686 %}. |
3687 resolvedPath notNil ifTrue:[^ resolvedPath ]. |
3687 resolvedPath notNil ifTrue:[^ resolvedPath ]. |
3688 |
3688 |
3689 self primitiveFailed. |
3689 "/ self primitiveFailed. |
|
3690 ^ nil. |
3690 |
3691 |
3691 " |
3692 " |
3692 OperatingSystem getLinkTarget:'C:\Dokumente und Einstellungen\cg\Favoriten\Incoming.lnk' |
3693 OperatingSystem getLinkTarget:'C:\Dokumente und Einstellungen\cg\Favoriten\Incoming.lnk' |
3693 OperatingSystem getLinkTarget:'C:\Dokumente und Einstellungen\cg\Favoriten\cg auf G5.lnk' |
3694 OperatingSystem getLinkTarget:'C:\Dokumente und Einstellungen\cg\Favoriten\cg auf G5.lnk' |
3694 " |
3695 " |
3695 |
3696 |
3696 "Created: / 07-11-2006 / 10:52:44 / cg" |
3697 "Created: / 07-11-2006 / 10:52:44 / cg" |
3697 "Modified: / 08-11-2006 / 12:20:33 / cg" |
3698 "Modified: / 07-02-2007 / 10:37:48 / cg" |
3698 ! |
3699 ! |
3699 |
3700 |
3700 linkFile:oldPath to:newPath |
3701 linkFile:oldPath to:newPath |
3701 "link the file 'oldPath' to 'newPath'. The link will be a hard link. |
3702 "link the file 'oldPath' to 'newPath'. The link will be a hard link. |
3702 Return true if successful, false if not." |
3703 Return true if successful, false if not." |
4717 |
4720 |
4718 linkInfoOf:aPathName |
4721 linkInfoOf:aPathName |
4719 "return some object filled with info for the file 'aPathName'; |
4722 "return some object filled with info for the file 'aPathName'; |
4720 the info (for which corresponding access methods are understood by |
4723 the info (for which corresponding access methods are understood by |
4721 the returned object) is: |
4724 the returned object) is: |
4722 type - a symbol giving the files type |
4725 type - a symbol giving the files type |
4723 mode - numeric access mode |
4726 mode - numeric access mode |
4724 uid - owners user id |
4727 uid - owners user id |
4725 gid - owners group id |
4728 gid - owners group id |
4726 size - files size |
4729 size - files size |
4727 id - files number (i.e. inode number) |
4730 id - files number (i.e. inode number) |
4728 accessed - last access time (as Timestamp) |
4731 accessed - last access time (as Timestamp) |
4729 modified - last modification time (as Timestamp) |
4732 modified - last modification time (as Timestamp) |
4730 statusChanged - last status change time (as Timestamp) |
4733 statusChanged - last status change time (as Timestamp) |
4731 alternativeName - (windows only:) the MSDOS name of the file |
4734 alternativeName - (windows only:) the MSDOS name of the file |
4732 |
4735 |
4733 Some of the fields may be returned as nil on systems which do not provide |
4736 Some of the fields may be returned as nil on systems which do not provide |
4734 all of the information. |
4737 all of the information. |
4735 Return nil if such a file does not exist. |
4738 Return nil if such a file does not exist. |
4736 For symbolic links (if supported by the OS), |
4739 For symbolic links (if supported by the OS), |
4752 char fileNameBuffer[MAX_PATH+1]; |
4755 char fileNameBuffer[MAX_PATH+1]; |
4753 |
4756 |
4754 unsigned INT ino; |
4757 unsigned INT ino; |
4755 |
4758 |
4756 if (__isString(aPathName)) { |
4759 if (__isString(aPathName)) { |
4757 HANDLE hFile; |
4760 HANDLE hFile; |
4758 FILETIME tempFileTime; |
4761 FILETIME tempFileTime; |
4759 SYSTEMTIME creationTime; |
4762 SYSTEMTIME creationTime; |
4760 SYSTEMTIME accessTime; |
4763 SYSTEMTIME accessTime; |
4761 SYSTEMTIME modificationTime; |
4764 SYSTEMTIME modificationTime; |
4762 int modeBits = 0; |
4765 int modeBits = 0; |
4763 WIN32_FIND_DATA findStruct; |
4766 WIN32_FIND_DATA findStruct; |
4764 |
4767 |
4765 #ifdef DO_WRAP_CALLS |
4768 #ifdef DO_WRAP_CALLS |
4766 { |
4769 { |
4767 char _aPathName[MAXPATHLEN]; |
4770 char _aPathName[MAXPATHLEN]; |
4768 |
4771 |
4769 strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
4772 strncpy(_aPathName, __stringVal(aPathName), MAXPATHLEN-1); _aPathName[MAXPATHLEN-1] = '\0'; |
4770 do { |
4773 do { |
4771 __threadErrno = 0; |
4774 __threadErrno = 0; |
4772 hFile = STX_API_CALL2( "FindFirstFile", FindFirstFile, _aPathName, &findStruct); |
4775 hFile = STX_API_CALL2( "FindFirstFile", FindFirstFile, _aPathName, &findStruct); |
4773 } while ((hFile < 0) && (__threadErrno == EINTR)); |
4776 } while ((hFile < 0) && (__threadErrno == EINTR)); |
4774 } |
4777 } |
4775 #else |
4778 #else |
4776 hFile = FindFirstFile(__stringVal(aPathName), &findStruct); |
4779 hFile = FindFirstFile(__stringVal(aPathName), &findStruct); |
4777 if (hFile < 0) { |
4780 if (hFile < 0) { |
4778 __threadErrno = __WIN32_ERR(GetLastError()); |
4781 __threadErrno = __WIN32_ERR(GetLastError()); |
4779 } |
4782 } |
4780 #endif |
4783 #endif |
4781 if (! hFile || (hFile == (HANDLE)(-1)) || (hFile == INVALID_HANDLE_VALUE)) { |
4784 if (! hFile || (hFile == (HANDLE)(-1)) || (hFile == INVALID_HANDLE_VALUE)) { |
4782 @global(LastErrorNumber) = __mkSmallInteger(__threadErrno); |
4785 @global(LastErrorNumber) = __mkSmallInteger(__threadErrno); |
4783 } else { |
4786 } else { |
4784 FindClose(hFile); |
4787 FindClose(hFile); |
4785 |
4788 |
4786 id = __mkSmallInteger(0); /* could get it by opening ... */ |
4789 id = __mkSmallInteger(0); /* could get it by opening ... */ |
4787 size = __MKLARGEINT64(1, findStruct.nFileSizeLow, findStruct.nFileSizeHigh); |
4790 size = __MKLARGEINT64(1, findStruct.nFileSizeLow, findStruct.nFileSizeHigh); |
4788 |
4791 |
4789 if (findStruct.cFileName[0] != '\0') { |
4792 if (findStruct.cFileName[0] != '\0') { |
4790 bcopy(findStruct.cFileName, fileNameBuffer, MAX_PATH); |
4793 bcopy(findStruct.cFileName, fileNameBuffer, MAX_PATH); |
4791 fileNameBuffer[MAX_PATH] = '\0'; |
4794 fileNameBuffer[MAX_PATH] = '\0'; |
4792 fileName = __MKSTRING(fileNameBuffer); /* FULL name */ |
4795 fileName = __MKSTRING(fileNameBuffer); /* FULL name */ |
4793 } |
4796 } |
4794 |
4797 |
4795 if (findStruct.cAlternateFileName[0] != '\0') { |
4798 if (findStruct.cAlternateFileName[0] != '\0') { |
4796 bcopy(findStruct.cAlternateFileName, alternativeFileNameBuffer, 14); |
4799 bcopy(findStruct.cAlternateFileName, alternativeFileNameBuffer, 14); |
4797 alternativeFileNameBuffer[14] = '\0'; |
4800 alternativeFileNameBuffer[14] = '\0'; |
4798 alternativeName = __MKSTRING(alternativeFileNameBuffer); /* DOS name */ |
4801 alternativeName = __MKSTRING(alternativeFileNameBuffer); /* DOS name */ |
4799 } |
4802 } |
4800 |
4803 |
4801 /* |
4804 /* |
4802 * simulate access bits |
4805 * simulate access bits |
4803 */ |
4806 */ |
4804 if (findStruct.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { |
4807 if (findStruct.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { |
4805 modeBits = 0444; |
4808 modeBits = 0444; |
4806 } else { |
4809 } else { |
4807 modeBits = 0666; |
4810 modeBits = 0666; |
4808 } |
4811 } |
4809 |
4812 |
4810 if (findStruct.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { |
4813 if (findStruct.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { |
4811 type = @symbol(directory); |
4814 type = @symbol(directory); |
4812 modeBits |= 0111; /* executable */ |
4815 modeBits |= 0111; /* executable */ |
4813 } else { |
4816 } else { |
4814 type = @symbol(regular); |
4817 type = @symbol(regular); |
4815 } |
4818 } |
4816 |
4819 |
4817 mode = __mkSmallInteger(modeBits); |
4820 mode = __mkSmallInteger(modeBits); |
4818 |
4821 |
4819 /* |
4822 /* |
4820 * sigh - convert from stupid time to useful time |
4823 * sigh - convert from stupid time to useful time |
4821 */ |
4824 */ |
4822 FileTimeToLocalFileTime(&findStruct.ftCreationTime, &tempFileTime); |
4825 FileTimeToLocalFileTime(&findStruct.ftCreationTime, &tempFileTime); |
4823 FileTimeToSystemTime(&tempFileTime, &creationTime); |
4826 FileTimeToSystemTime(&tempFileTime, &creationTime); |
4824 FileTimeToLocalFileTime(&findStruct.ftLastAccessTime, &tempFileTime); |
4827 FileTimeToLocalFileTime(&findStruct.ftLastAccessTime, &tempFileTime); |
4825 FileTimeToSystemTime(&tempFileTime, &accessTime); |
4828 FileTimeToSystemTime(&tempFileTime, &accessTime); |
4826 FileTimeToLocalFileTime(&findStruct.ftLastWriteTime, &tempFileTime); |
4829 FileTimeToLocalFileTime(&findStruct.ftLastWriteTime, &tempFileTime); |
4827 FileTimeToSystemTime(&tempFileTime, &modificationTime); |
4830 FileTimeToSystemTime(&tempFileTime, &modificationTime); |
4828 aYr = __mkSmallInteger(accessTime.wYear); |
4831 aYr = __mkSmallInteger(accessTime.wYear); |
4829 aMon = __mkSmallInteger(accessTime.wMonth); |
4832 aMon = __mkSmallInteger(accessTime.wMonth); |
4830 aDay = __mkSmallInteger(accessTime.wDay); |
4833 aDay = __mkSmallInteger(accessTime.wDay); |
4831 aHr = __mkSmallInteger(accessTime.wHour); |
4834 aHr = __mkSmallInteger(accessTime.wHour); |
4832 aMin = __mkSmallInteger(accessTime.wMinute); |
4835 aMin = __mkSmallInteger(accessTime.wMinute); |
4833 aSec = __mkSmallInteger(accessTime.wSecond); |
4836 aSec = __mkSmallInteger(accessTime.wSecond); |
4834 aMS = __mkSmallInteger(accessTime.wMilliseconds); |
4837 aMS = __mkSmallInteger(accessTime.wMilliseconds); |
4835 |
4838 |
4836 mYr = __mkSmallInteger(modificationTime.wYear); |
4839 mYr = __mkSmallInteger(modificationTime.wYear); |
4837 mMon = __mkSmallInteger(modificationTime.wMonth); |
4840 mMon = __mkSmallInteger(modificationTime.wMonth); |
4838 mDay = __mkSmallInteger(modificationTime.wDay); |
4841 mDay = __mkSmallInteger(modificationTime.wDay); |
4839 mHr = __mkSmallInteger(modificationTime.wHour); |
4842 mHr = __mkSmallInteger(modificationTime.wHour); |
4840 mMin = __mkSmallInteger(modificationTime.wMinute); |
4843 mMin = __mkSmallInteger(modificationTime.wMinute); |
4841 mSec = __mkSmallInteger(modificationTime.wSecond); |
4844 mSec = __mkSmallInteger(modificationTime.wSecond); |
4842 mMS = __mkSmallInteger(modificationTime.wMilliseconds); |
4845 mMS = __mkSmallInteger(modificationTime.wMilliseconds); |
4843 |
4846 |
4844 cYr = __mkSmallInteger(creationTime.wYear); |
4847 cYr = __mkSmallInteger(creationTime.wYear); |
4845 cMon = __mkSmallInteger(creationTime.wMonth); |
4848 cMon = __mkSmallInteger(creationTime.wMonth); |
4846 cDay = __mkSmallInteger(creationTime.wDay); |
4849 cDay = __mkSmallInteger(creationTime.wDay); |
4847 cHr = __mkSmallInteger(creationTime.wHour); |
4850 cHr = __mkSmallInteger(creationTime.wHour); |
4848 cMin = __mkSmallInteger(creationTime.wMinute); |
4851 cMin = __mkSmallInteger(creationTime.wMinute); |
4849 cSec = __mkSmallInteger(creationTime.wSecond); |
4852 cSec = __mkSmallInteger(creationTime.wSecond); |
4850 cMS = __mkSmallInteger(creationTime.wMilliseconds); |
4853 cMS = __mkSmallInteger(creationTime.wMilliseconds); |
4851 } |
4854 } |
4852 } |
4855 } |
4853 %}. |
4856 %}. |
4854 (aPathName endsWith:'.lnk') ifTrue:[ |
4857 (aPathName endsWith:'.lnk') ifTrue:[ |
4855 type := #symbolicLink. |
4858 type := #symbolicLink. |
4856 path := self getLinkTarget:aPathName. |
4859 path := nil. |
|
4860 "/ now done lazyly in FileStatusInfo, when the path is accessed |
|
4861 "/ path := self getLinkTarget:aPathName. |
4857 ]. |
4862 ]. |
4858 |
4863 |
4859 mode isNil ifTrue:[ |
4864 mode isNil ifTrue:[ |
4860 (self isDirectory:aPathName) ifTrue:[ |
4865 (self isDirectory:aPathName) ifTrue:[ |
4861 "/ the code above fails for root directories (these do not exist). |
4866 "/ the code above fails for root directories (these do not exist). |
4862 "/ simulate |
4867 "/ simulate |
4863 mode := 8r777. |
4868 mode := 8r777. |
4864 type := #directory. |
4869 type := #directory. |
4865 uid := gid := 0. |
4870 uid := gid := 0. |
4866 size := 0. |
4871 size := 0. |
4867 id := 0. |
4872 id := 0. |
4868 atime := mtime := ctime := Timestamp now. |
4873 atime := mtime := ctime := Timestamp now. |
4869 ]. |
4874 ]. |
4870 ]. |
4875 ]. |
4871 mode notNil ifTrue:[ |
4876 mode notNil ifTrue:[ |
4872 atime isNil ifTrue:[ |
4877 atime isNil ifTrue:[ |
4873 atime := Timestamp day:aDay month:aMon year:aYr hour:aHr minutes:aMin seconds:aSec milliseconds:aMS. |
4878 atime := Timestamp day:aDay month:aMon year:aYr hour:aHr minutes:aMin seconds:aSec milliseconds:aMS. |
4874 ]. |
4879 ]. |
4875 mtime isNil ifTrue:[ |
4880 mtime isNil ifTrue:[ |
4876 mtime := Timestamp day:mDay month:mMon year:mYr hour:mHr minutes:mMin seconds:mSec milliseconds:mMS. |
4881 mtime := Timestamp day:mDay month:mMon year:mYr hour:mHr minutes:mMin seconds:mSec milliseconds:mMS. |
4877 ]. |
4882 ]. |
4878 ctime isNil ifTrue:[ |
4883 ctime isNil ifTrue:[ |
4879 ctime := Timestamp day:cDay month:cMon year:cYr hour:cHr minutes:cMin seconds:cSec milliseconds:cMS. |
4884 ctime := Timestamp day:cDay month:cMon year:cYr hour:cHr minutes:cMin seconds:cSec milliseconds:cMS. |
4880 ]. |
4885 ]. |
4881 |
4886 |
4882 info := FileStatusInfo |
4887 info := FileStatusInfo |
4883 type:type |
4888 type:type |
4884 mode:mode |
4889 mode:mode |
4885 uid:uid |
4890 uid:uid |
4886 gid:gid |
4891 gid:gid |
4887 size:size |
4892 size:size |
4888 id:id |
4893 id:id |
4889 accessed:atime |
4894 accessed:atime |
4890 modified:mtime |
4895 modified:mtime |
4891 created:ctime |
4896 created:ctime |
4892 path:path |
4897 path:path |
4893 fullName:fileName |
4898 fullName:fileName |
4894 alternativeName:alternativeName. |
4899 alternativeName:alternativeName. |
4895 ^ info |
4900 ^ info |
4896 ]. |
4901 ]. |
4897 ^ nil |
4902 ^ nil |
4898 |
4903 |
4899 " |
4904 " |
4900 OperatingSystem linkInfoOf:'c:\windows' |
4905 OperatingSystem linkInfoOf:'c:\windows' |