00001 /* 00002 * Copyright 2003, 2004 Martin Fuchs 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 00020 // 00021 // Explorer clone 00022 // 00023 // unixfs.cpp 00024 // 00025 // Martin Fuchs, 23.07.2003 00026 // 00027 00028 00029 #ifdef __WINE__ 00030 00031 #include <precomp.h> 00032 00033 //#include "unixfs.h" 00034 00035 // for UnixDirectory::read_directory() 00036 #include <dirent.h> 00037 #include <sys/stat.h> 00038 #include <time.h> 00039 00040 00041 void UnixDirectory::read_directory() 00042 { 00043 Entry* first_entry = NULL; 00044 Entry* last = NULL; 00045 Entry* entry; 00046 00047 int level = _level + 1; 00048 00049 LPCTSTR path = (LPCTSTR)_path; 00050 DIR* pdir = opendir(path); 00051 00052 if (pdir) { 00053 struct stat st; 00054 struct dirent* ent; 00055 TCHAR buffer[MAX_PATH], *p; 00056 00057 for(p=buffer; *path; ) 00058 *p++ = *path++; 00059 00060 if (p==buffer || p[-1]!='/') 00061 *p++ = '/'; 00062 00063 while((ent=readdir(pdir))) { 00064 int statres = stat(buffer, &st); 00065 00066 if (!statres && S_ISDIR(st.st_mode)) 00067 entry = new UnixDirectory(this, buffer); 00068 else 00069 entry = new UnixEntry(this); 00070 00071 if (!first_entry) 00072 first_entry = entry; 00073 00074 if (last) 00075 last->_next = entry; 00076 00077 lstrcpy(entry->_data.cFileName, ent->d_name); 00078 entry->_data.dwFileAttributes = ent->d_name[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0; 00079 00080 strcpy(p, ent->d_name); 00081 00082 if (!statres) { 00083 if (S_ISDIR(st.st_mode)) 00084 entry->_data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 00085 00086 entry->_data.nFileSizeLow = st.st_size & 0xFFFFFFFF; 00087 entry->_data.nFileSizeHigh = st.st_size >> 32; 00088 00089 memset(&entry->_data.ftCreationTime, 0, sizeof(FILETIME)); 00090 time_to_filetime(&st.st_atime, &entry->_data.ftLastAccessTime); 00091 time_to_filetime(&st.st_mtime, &entry->_data.ftLastWriteTime); 00092 00093 entry->_bhfi.nFileIndexLow = ent->d_ino; 00094 entry->_bhfi.nFileIndexHigh = 0; 00095 00096 entry->_bhfi.nNumberOfLinks = st.st_nlink; 00097 00098 entry->_bhfi_valid = TRUE; 00099 } else { 00100 entry->_data.nFileSizeLow = 0; 00101 entry->_data.nFileSizeHigh = 0; 00102 entry->_bhfi_valid = FALSE; 00103 } 00104 00105 entry->_up = this; 00106 entry->_expanded = FALSE; 00107 entry->_scanned = FALSE; 00108 entry->_level = level; 00109 00110 last = entry; 00111 } 00112 00113 last->_next = NULL; 00114 00115 closedir(pdir); 00116 } 00117 00118 _down = first_entry; 00119 _scanned = true; 00120 } 00121 00122 00123 const void* UnixDirectory::get_next_path_component(const void* p) 00124 { 00125 LPCTSTR s = (LPCTSTR) p; 00126 00127 while(*s && *s!=TEXT('/')) 00128 ++s; 00129 00130 while(*s == TEXT('/')) 00131 ++s; 00132 00133 if (!*s) 00134 return NULL; 00135 00136 return s; 00137 } 00138 00139 00140 Entry* UnixDirectory::find_entry(const void* p) 00141 { 00142 LPCTSTR name = (LPCTSTR)p; 00143 00144 for(Entry*entry=_down; entry; entry=entry->_next) { 00145 LPCTSTR p = name; 00146 LPCTSTR q = entry->_data.cFileName; 00147 00148 do { 00149 if (!*p || *p==TEXT('/')) 00150 return entry; 00151 } while(*p++ == *q++); 00152 } 00153 00154 return NULL; 00155 } 00156 00157 00158 // get full path of specified directory entry 00159 bool UnixEntry::get_path(PTSTR path, size_t path_count) const 00160 { 00161 int level = 0; 00162 size_t len = 0; 00163 00164 if (!path || path_count==0) 00165 return false; 00166 00167 if ( path_count > 1 ) 00168 { 00169 for(const Entry* entry=this; entry; level++) { 00170 LPCTSTR name = entry->_data.cFileName; 00171 size_t l = 0; 00172 00173 for(LPCTSTR s=name; *s && *s!=TEXT('/'); s++) 00174 ++l; 00175 00176 if (entry->_up) { 00177 if (l > 0) { 00178 if ( len+l+1 >= path_count ) 00179 { 00180 /* compare to 2 here because of terminator plus the '\\' we prepend */ 00181 if ( l + 2 > path_count ) 00182 len = 0; 00183 else 00184 len = path_count - l - 2; 00185 } 00186 memmove(path+l+1, path, len*sizeof(TCHAR)); 00187 /* compare to 2 here because of terminator plus the '\\' we prepend */ 00188 if ( l+2 >= path_count ) 00189 l = path_count - 2; 00190 memcpy(path+1, name, l*sizeof(TCHAR)); 00191 len += l+1; 00192 00193 path[0] = TEXT('/'); 00194 } 00195 00196 entry = entry->_up; 00197 } else { 00198 if ( len+l >= path_count ) 00199 { 00200 if ( l + 1 > path_count ) 00201 len = 0; 00202 else 00203 len = path_count - l - 1; 00204 } 00205 memmove(path+l, path, len*sizeof(TCHAR)); 00206 if ( l+1 >= path_count ) 00207 l = path_count - 1; 00208 memcpy(path, name, l*sizeof(TCHAR)); 00209 len += l; 00210 break; 00211 } 00212 } 00213 00214 if ( !level && (len+1 < path_count) ) 00215 path[len++] = TEXT('/'); 00216 } 00217 00218 path[len] = TEXT('\0'); 00219 00220 return true; 00221 } 00222 00223 #endif // __WINE__
ROS Explorer Source Code Documentation
generated on 02.01.2013 by ![]() |