/* * Winefile * * Copyright 2000, 2003, 2004, 2005, 2008 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include "winefile.h" #if !defined(_NO_EXTENSIONS) && defined(__WINE__) /* convert a time_t value to a FILETIME structure */ static BOOL time_to_filetime(const time_t* t, FILETIME* ftime) { struct tm* tm = gmtime(t); SYSTEMTIME stime; if (!tm) return FALSE; stime.wYear = tm->tm_year+1900; stime.wMonth = tm->tm_mon+1; /* stime.wDayOfWeek */ stime.wDay = tm->tm_mday; stime.wHour = tm->tm_hour; stime.wMinute = tm->tm_min; stime.wSecond = tm->tm_sec; return SystemTimeToFileTime(&stime, ftime); } /* read a directory entry using the UNIX API */ void read_directory_unix(Entry* dir, LPCTSTR path) { Entry* first_entry = NULL; Entry* last = NULL; Entry* entry; DIR* pdir; int level = dir->level + 1; #ifdef UNICODE char cpath[MAX_PATH]; WideCharToMultiByte(CP_UNIXCP, 0, path, -1, cpath, MAX_PATH, NULL, NULL); #else const char* cpath = path; #endif pdir = opendir(cpath); if (pdir) { struct stat st; struct dirent* ent; char buffer[MAX_PATH], *p; const char* s; for(p=buffer,s=cpath; *s; ) *p++ = *s++; if (p==buffer || p[-1]!='/') *p++ = '/'; while((ent=readdir(pdir))) { entry = alloc_entry(); if (!first_entry) first_entry = entry; if (last) last->next = entry; entry->etype = ET_UNIX; strcpy(p, ent->d_name); #ifdef UNICODE MultiByteToWideChar(CP_UNIXCP, 0, p, -1, entry->data.cFileName, MAX_PATH); #else lstrcpy(entry->data.cFileName, p); #endif if (!stat(buffer, &st)) { entry->data.dwFileAttributes = p[0]=='.'? FILE_ATTRIBUTE_HIDDEN: 0; if (S_ISDIR(st.st_mode)) entry->data.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; entry->data.nFileSizeLow = st.st_size & 0xFFFFFFFF; entry->data.nFileSizeHigh = st.st_size >> 32; memset(&entry->data.ftCreationTime, 0, sizeof(FILETIME)); time_to_filetime(&st.st_atime, &entry->data.ftLastAccessTime); time_to_filetime(&st.st_mtime, &entry->data.ftLastWriteTime); entry->bhfi.nFileIndexLow = ent->d_ino; entry->bhfi.nFileIndexHigh = 0; entry->bhfi.nNumberOfLinks = st.st_nlink; entry->bhfi_valid = TRUE; } else { entry->data.nFileSizeLow = 0; entry->data.nFileSizeHigh = 0; entry->bhfi_valid = FALSE; } entry->down = NULL; entry->up = dir; entry->expanded = FALSE; entry->scanned = FALSE; entry->level = level; last = entry; } if (last) last->next = NULL; closedir(pdir); } dir->down = first_entry; dir->scanned = TRUE; } /* search a UNIX directory entry by name */ static Entry* find_entry_unix(Entry* dir, LPCTSTR name) { Entry* entry; for(entry=dir->down; entry; entry=entry->next) { LPCTSTR p = name; LPCTSTR q = entry->data.cFileName; do { if (!*p || *p=='/') return entry; } while(*p++ == *q++); } return 0; } /* read a directory tree for the given path using the WIN32 Unix API */ Entry* read_tree_unix(Root* root, LPCTSTR path, enum SORT_ORDER sortOrder, HWND hwnd) { TCHAR buffer[MAX_PATH]; Entry* entry = &root->entry; LPCTSTR s = path; PTSTR d = buffer; HCURSOR old_cursor = SetCursor(LoadCursor(0, IDC_WAIT)); entry->etype = ET_UNIX; while(entry) { while(*s && *s!='/') *d++ = *s++; while(*s == '/') s++; *d++ = '/'; *d = '\0'; read_directory(entry, buffer, sortOrder, hwnd); if (entry->down) entry->expanded = TRUE; if (!*s) break; entry = find_entry_unix(entry, s); } SetCursor(old_cursor); return entry; } #endif /* !defined(_NO_EXTENSIONS) && defined(__WINE__) */