reading of FAT image files (work in progress)
authorMartin Fuchs <fuchs.martin@gmail.com>
Mon, 2 Feb 2004 23:18:07 +0000 (23:18 +0000)
committerMartin Fuchs <fuchs.martin@gmail.com>
Mon, 2 Feb 2004 23:18:07 +0000 (23:18 +0000)
svn path=/trunk/; revision=8005

23 files changed:
reactos/subsys/system/explorer/Jamfile
reactos/subsys/system/explorer/Makefile
reactos/subsys/system/explorer/Makefile.MinGW
reactos/subsys/system/explorer/Makefile.Wine
reactos/subsys/system/explorer/doc/changes.txt
reactos/subsys/system/explorer/doxy-footer.html
reactos/subsys/system/explorer/explorer.dsp
reactos/subsys/system/explorer/explorer_intres.h
reactos/subsys/system/explorer/explorer_intres.rc
reactos/subsys/system/explorer/shell/entries.h
reactos/subsys/system/explorer/shell/fatfs.cpp [new file with mode: 0644]
reactos/subsys/system/explorer/shell/fatfs.h [new file with mode: 0644]
reactos/subsys/system/explorer/shell/filechild.cpp
reactos/subsys/system/explorer/shell/filechild.h
reactos/subsys/system/explorer/shell/mainframe.cpp
reactos/subsys/system/explorer/shell/ntobjfs.cpp
reactos/subsys/system/explorer/shell/pane.cpp
reactos/subsys/system/explorer/shell/regfs.cpp
reactos/subsys/system/explorer/shell/shellbrowser.cpp
reactos/subsys/system/explorer/shell/shellfs.cpp
reactos/subsys/system/explorer/shell/unixfs.cpp
reactos/subsys/system/explorer/shell/winfs.cpp
reactos/subsys/system/explorer/utility/utility.cpp

index 1899540..e8f2fcf 100644 (file)
@@ -23,6 +23,7 @@ exe explorer :
        shell/winfs.cpp
        shell/ntobjfs.cpp
        shell/regfs.cpp
+       shell/fatfs.cpp
        shell/startup.c
        taskbar/desktopbar.cpp
        taskbar/quicklaunch.cpp
index 21d1a9d..990cf3a 100644 (file)
@@ -82,6 +82,7 @@ OBJECTS = \
        shellfs.o \
        ntobjfs.o \
        regfs.o \
+       fatfs.o \
        mainframe.o \
        filechild.o \
        pane.o \
index b0d61af..5d35b4e 100644 (file)
@@ -56,6 +56,7 @@ OBJECTS = \
        shellfs.o \
        ntobjfs.o \
        regfs.o \
+       fatfs.o \
        mainframe.o \
        filechild.o \
        pane.o \
index 6a73833..f84158f 100644 (file)
@@ -30,6 +30,7 @@ CPP_SRCS = \
        shell/pane.cpp \
        shell/shellbrowser.cpp \
        shell/ntobjfs.cpp \
+       shell/fatfs.cpp \
        shell/regfs.cpp \
        taskbar/desktopbar.cpp \
        taskbar/taskbar.cpp \
index 9c1aae5..c8573e4 100644 (file)
@@ -59,3 +59,4 @@ If you search for more information, look into the CVS repository.
 18.01.2004     m. fuchs        explorer/desktop settings property sheet
 31.01.2004     m. fuchs        included NT Object namespace as virtual file system
 31.01.2004     m. fuchs        included Registry as virtual file system
+02.02.2004     m. fuchs        reading of FAT image files
index 32c0449..a64ab65 100644 (file)
@@ -3,7 +3,7 @@
   <tr>
     <td><address style="align: right;"><small>
 ROS Explorer Source Code Documentation
-<br>generated on 01.02.2004 by <a href="http://www.doxygen.org/index.html">
+<br>generated on 03.02.2004 by <a href="http://www.doxygen.org/index.html">
 <img src="doxygen.png" alt="doxygen" align="middle" border=0>
        </small></address>
        </td>
index b50ba70..a33392f 100644 (file)
@@ -728,6 +728,14 @@ SOURCE=.\shell\entries.h
 # End Source File
 # Begin Source File
 
+SOURCE=.\shell\fatfs.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\shell\fatfs.h
+# End Source File
+# Begin Source File
+
 SOURCE=.\shell\filechild.cpp
 # End Source File
 # Begin Source File
index 0d70dc0..b049da1 100644 (file)
 #define ID_DRIVE_UNIX_FS                0x9002
 #define ID_DRIVE_NTOBJ_NS               0x9003
 #define ID_DRIVE_REGISTRY               0x9004
-#define ID_DRIVE_FIRST                  0x9005
+#define ID_DRIVE_FAT                    0x9005
+#define ID_DRIVE_FIRST                  0x9006
 #define ID_ABOUT_WINDOWS                40002
 #define ID_ABOUT_EXPLORER               40003
 #define ID_DESKTOPBAR_SETTINGS          40005
index 7a1fcab..dda2bd8 100644 (file)
@@ -353,7 +353,7 @@ CAPTION "About ReactOS Explorer"
 FONT 10, "MS Sans Serif"
 BEGIN
     LTEXT           "ReactOS Explorer",IDC_ROS_EXPLORER,91,29,90,11
-    LTEXT           "(c) 2003 Martin Fuchs",IDC_STATIC,90,50,70,8
+    LTEXT           "(c) 2003/2004 Martin Fuchs",IDC_STATIC,90,50,79,8
     LTEXT           "http://www.sky.franken.de/explorer/",IDC_WWW,21,84,104,
                     8
     CONTROL         "&OK",IDOK,"Button",BS_OWNERDRAW | BS_FLAT | WS_GROUP,
index acf146e..7050c55 100644 (file)
@@ -33,7 +33,8 @@ enum ENTRY_TYPE {
 #endif
        ET_SHELL,
        ET_NTOBJS,
-       ET_REGISTRY
+       ET_REGISTRY,
+       ET_FAT
 };
 
 enum SORT_ORDER {
@@ -54,6 +55,9 @@ enum SCAN_FLAGS {
 };
 
 #ifndef ATTRIBUTE_SYMBOLIC_LINK
+#define        ATTRIBUTE_LONGNAME                      0x08000000
+#define        ATTRIBUTE_VOLNAME                       0x10000000
+#define        ATTRIBUTE_ERASED                        0x20000000
 #define ATTRIBUTE_SYMBOLIC_LINK                0x40000000
 #define        ATTRIBUTE_EXECUTABLE            0x80000000
 #endif
diff --git a/reactos/subsys/system/explorer/shell/fatfs.cpp b/reactos/subsys/system/explorer/shell/fatfs.cpp
new file mode 100644 (file)
index 0000000..1dbe4c8
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+ * Copyright 2003 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+ //
+ // Explorer clone
+ //
+ // fatfs.cpp
+ //
+ // Martin Fuchs, 01.02.2004
+ //
+
+
+#include "../utility/utility.h"
+#include "../utility/shellclasses.h"
+#include "../globals.h"
+
+#include "entries.h"
+#include "fatfs.h"
+
+
+static union DEntry* link_dir_entries(struct dirent* dir, struct Kette* K, int cnt)
+{
+       union DEntry* Ent = (union DEntry*) dir;
+       struct Kette* L = NULL;
+
+       for(; cnt; cnt--) {
+               K->Rueck = L;
+               (L=K)->Ent = Ent;
+               AddP(K, sizeof(struct Kette));
+               L->Vorw = K;
+               AddP(Ent, sizeof(union DEntry));
+       }
+
+       L->Vorw = NULL;
+
+       return Ent;
+}
+
+void FATDirectory::read_directory(int scan_flags)
+{
+       CONTEXT("FATDirectory::read_directory()");
+
+       read_dir();
+
+       union DEntry* p = (union DEntry*) _dir;
+       int i = 0;
+
+       do {
+/*             if (!IS_LNAME(p->E.attr) && p->E.name[0]!=FAT_DEL_CHAR)
+                       gesBytes += p->E.size;
+*/
+
+               AddP(p, sizeof(union DEntry));
+       } while(++i<_ents && p->E.name[0]);
+
+       _alloc = (struct Kette*) malloc((size_t)((_ents=i)+8)*sizeof(struct Kette));
+       if (!_alloc)
+               return;
+
+       link_dir_entries(_dir, _alloc, i);
+
+       Entry* first_entry = NULL;
+       int level = _level + 1;
+
+       Entry* last = NULL;
+
+       WIN32_FIND_DATA w32fd;
+       FAT_attribute attr;
+       String long_name;
+
+       TCHAR buffer[MAX_PATH];
+
+       _tcscpy(buffer, (LPCTSTR)_path);
+       LPTSTR pname = buffer + _tcslen(buffer);
+
+       *pname++ = '\\';
+
+       for(Kette*p=_alloc; p; p=p->Vorw) {
+               memset(&w32fd, 0, sizeof(WIN32_FIND_DATA));
+
+               DEntry_E& e = p->Ent->E;
+
+                // get file/directory attributes
+               attr.b = e.attr;
+
+               if (attr.b & (_A_DELETED | _A_ILLEGAL))
+                       attr.b |= _A_ILLEGAL;
+
+               const char* s = e.name;
+               LPTSTR d = w32fd.cFileName;
+
+               if (!IS_LNAME(attr.b) || e.name[0]==FAT_DEL_CHAR) {
+                       if (e.name[0] == FAT_DEL_CHAR)
+                               w32fd.dwFileAttributes |= ATTRIBUTE_ERASED;
+                       else if (IS_LNAME(attr.b))
+                               w32fd.dwFileAttributes |= ATTRIBUTE_LONGNAME;
+                       else if (attr.a.directory)
+                               w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
+                       else if (attr.a.volume)
+                               w32fd.dwFileAttributes |= ATTRIBUTE_VOLNAME;    //@@ -> in Volume-Name der Root kopieren
+
+                        // get file name
+                       *d++ = *s==FAT_DEL_CHAR? '?': *s;
+                       ++s;
+
+                       for(i=0; i<7; ++i)
+                               *d++ = *s++;
+
+                       while(d>w32fd.cFileName && d[-1]==' ')
+                               --d;
+
+                       *d++ = '.';
+
+                       for(; i<10; ++i)
+                               *d++ = *s++;
+
+                       while(d>w32fd.cFileName && d[-1]==' ')
+                               --d;
+
+                       if (d>w32fd.cFileName && d[-1]=='.')
+                               --d;
+
+                       *d = '\0';
+               } else {
+                        // read long file name
+                       TCHAR lname[] = {s[1], s[3], s[5], s[7], s[9], s[14], s[16], s[18], s[20], s[22], s[24], s[28], s[30]};
+
+                       long_name = String(lname, 13) + long_name;
+               }
+
+               if (!IS_LNAME(attr.b) && !attr.a.volume) {
+                        // get file size
+                       w32fd.nFileSizeLow = e.size;
+
+                        // convert date/time attribute into FILETIME
+                       const fdate& date = e.date;
+                       const ftime& time = e.time;
+                       SYSTEMTIME stime;
+                       FILETIME ftime;
+
+                       stime.wYear = date.year + 1980;
+                       stime.wMonth = date.month;
+                       stime.wDayOfWeek = (WORD)-1;
+                       stime.wDay = date.day;
+                       stime.wHour = time.hour;
+                       stime.wMinute = time.min;
+                       stime.wSecond = time.sec2 * 2;
+                       stime.wMilliseconds = 0;
+
+                       if (SystemTimeToFileTime(&stime, &ftime))
+                               LocalFileTimeToFileTime(&ftime, &w32fd.ftLastWriteTime);
+
+                       if (!(w32fd.dwFileAttributes & ATTRIBUTE_ERASED)) { //@@
+                               Entry* entry;
+
+                               if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+                                       _tcscpy(pname, w32fd.cFileName);
+                                       entry = new FATDirectory(_drive, this, buffer, e.fclus);
+                               } else
+                                       entry = new FATEntry(this, e.fclus);
+
+                               memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
+
+                               if (!long_name.empty()) {
+                                       entry->_content = _tcsdup(long_name);
+                                       long_name.erase();
+                               }
+
+                               if (!first_entry)
+                                       first_entry = entry;
+
+                               if (last)
+                                       last->_next = entry;
+
+                               entry->_level = level;
+
+                               last = entry;
+                       }
+               }
+       }
+
+       if (last)
+               last->_next = NULL;
+
+       _down = first_entry;
+       _scanned = true;
+}
+
+
+Entry* FATDirectory::find_entry(const void* p)
+{
+       LPCTSTR name = (LPCTSTR)p;
+
+       for(Entry*entry=_down; entry; entry=entry->_next) {
+               LPCTSTR p = name;
+               LPCTSTR q = entry->_data.cFileName;
+
+               do {
+                       if (!*p || *p==TEXT('\\') || *p==TEXT('/'))
+                               return entry;
+               } while(tolower(*p++) == tolower(*q++));
+
+               p = name;
+               q = entry->_data.cAlternateFileName;
+
+               do {
+                       if (!*p || *p==TEXT('\\') || *p==TEXT('/'))
+                               return entry;
+               } while(tolower(*p++) == tolower(*q++));
+       }
+
+       return NULL;
+}
+
+
+ // get full path of specified directory entry
+bool FATEntry::get_path(PTSTR path) const
+{
+       int level = 0;
+       int len = 0;
+       int l = 0;
+       LPCTSTR name = NULL;
+       TCHAR buffer[MAX_PATH];
+
+       const Entry* entry;
+       for(entry=this; entry; level++) {
+               l = 0;
+
+               if (entry->_etype == ET_FAT) {
+                       name = entry->_data.cFileName;
+
+                       for(LPCTSTR s=name; *s && *s!=TEXT('/') && *s!=TEXT('\\'); s++)
+                               ++l;
+
+                       if (!entry->_up)
+                               break;
+               } else {
+                       if (entry->get_path(buffer)) {
+                               l = _tcslen(buffer);
+                               name = buffer;
+
+                               /* special handling of drive names */
+                               if (l>0 && buffer[l-1]=='\\' && path[0]=='\\')
+                                       --l;
+
+                               memmove(path+l, path, len*sizeof(TCHAR));
+                               memcpy(path, name, l*sizeof(TCHAR));
+                               len += l;
+                       }
+
+                       entry = NULL;
+                       break;
+               }
+
+               if (l > 0) {
+                       memmove(path+l+1, path, len*sizeof(TCHAR));
+                       memcpy(path+1, name, l*sizeof(TCHAR));
+                       len += l+1;
+
+                       path[0] = TEXT('\\');
+               }
+
+               entry = entry->_up;
+       }
+
+       if (entry) {
+               memmove(path+l, path, len*sizeof(TCHAR));
+               memcpy(path, name, l*sizeof(TCHAR));
+               len += l;
+       }
+
+       if (!level)
+               path[len++] = TEXT('\\');
+
+       path[len] = TEXT('\0');
+
+       return true;
+}
+
+
+FATDirectory::FATDirectory(FATDrive& drive, LPCTSTR root_path)
+ :     FATEntry(),
+       _drive(drive)
+{
+       _path = _tcsdup(root_path);
+
+       _secarr         = NULL;
+       _cur_bufs       = 0;
+       _ents           = 0;
+       _dir            = NULL;
+       _cluster        = 0;
+}
+
+FATDirectory::FATDirectory(FATDrive& drive, Entry* parent, LPCTSTR path, unsigned cluster)
+ :     FATEntry(parent, cluster),
+       _drive(drive)
+{
+       _path = _tcsdup(path);
+
+       _secarr         = NULL;
+       _cur_bufs       = 0;
+       _ents           = 0;
+       _dir            = NULL;
+}
+
+FATDirectory::~FATDirectory()
+{
+       free(_path);
+       _path = NULL;
+}
+
+bool FATDirectory::read_dir()
+{
+       int i;
+
+       if (_cluster == 0) {
+               if (!_drive._boot_sector.SectorsPerFAT) {       // FAT32? [boot_sector32->reserved0==0]
+                       BootSector32* boot_sector32 = (BootSector32*) &_drive._boot_sector;
+                       DWORD sect = _drive._boot_sector.ReservedSectors + _drive._boot_sector.NumberFATs*boot_sector32->SectorsPerFAT32;  // lese Root-Directory ein
+                       int RootEntries = boot_sector32->RootSectors * 32;      //@@
+
+                       _secarr = (struct dirsecz*)malloc(sizeof(DWORD) * (_cur_bufs = (int)((_ents=RootEntries)/_drive._bufents)));
+
+                       for(i=0; i<_cur_bufs; i++)
+                               _secarr->s[i] = sect+i;
+
+                       _dir = (struct dirent*)malloc((size_t)(_ents+16)*sizeof(union DEntry));
+                       if (!_dir)
+                               return false;
+
+                       if (!(_drive.read_sector(*_secarr->s,(Buffer*)_dir,_cur_bufs)))
+                               return false;
+               } else {
+                       DWORD sect = _drive._boot_sector.ReservedSectors + _drive._boot_sector.NumberFATs*_drive._boot_sector.SectorsPerFAT;  // read in root directory
+
+                       _secarr = (struct dirsecz*)malloc(sizeof(DWORD) * (_cur_bufs = (int)((_ents=_drive._boot_sector.RootEntries)/_drive._bufents)));
+
+                       for(i=0; i<_cur_bufs; i++)
+                               _secarr->s[i] = sect+i;
+
+                       _dir = (struct dirent*)malloc((size_t)(_ents+16)*sizeof(union DEntry));
+                       if (!_dir)
+                               return false;
+
+                       if (!_drive.read_sector(*_secarr->s,(Buffer*)_dir,_cur_bufs))
+                               return false;
+               }
+       } else {
+               Buffer* buf;
+               bool ok;
+
+               DWORD h = _cluster;
+
+               _cur_bufs = 0;
+
+               do {
+                       h = _drive.read_FAT(h, ok);
+
+                       if (!ok)
+                               return false;
+
+                       _cur_bufs++;
+               } while (h<0x0ffffff0 && h);
+
+               _secarr = (struct dirsecz*) malloc(sizeof(DWORD) * _cur_bufs);
+
+               if (!_secarr)
+                       return false;
+
+               _ents = _drive._bufents * (size_t)_cur_bufs * _drive._SClus;
+
+               if ((buf=(Buffer*)(_dir=(struct dirent*)malloc((size_t) (_ents+16)*sizeof(union DEntry)))) == NULL)
+                       return false;
+
+               h = _cluster;
+
+               DWORD fdatsec;
+
+               if (!_drive._boot_sector.SectorsPerFAT) {       // FAT32 ?
+                       BootSector32* boot_sector32 = (BootSector32*) &_drive._boot_sector;
+                       //int RootEntries = boot_sector32->RootSectors * 32;    //@@
+                       //fdatsec = _drive._boot_sector.ReservedSectors + _drive._boot_sector.NumberFATs*boot_sector32->SectorsPerFAT32 + RootEntries*sizeof(DEntry)/_drive._boot_sector.BytesPerSector;        // dpb.fdirsec
+                       fdatsec = _drive._boot_sector.ReservedSectors +
+                                               _drive._boot_sector.NumberFATs*boot_sector32->SectorsPerFAT32 + boot_sector32->RootSectors;
+               } else
+                       fdatsec = _drive._boot_sector.ReservedSectors +
+                                               _drive._boot_sector.NumberFATs*_drive._boot_sector.SectorsPerFAT +
+                                               _drive._boot_sector.RootEntries*sizeof(DEntry)/_drive._boot_sector.BytesPerSector;      // dpb.fdirsec
+
+                       for(i=0; i<_cur_bufs; i++) {
+                               _secarr->s[i] = fdatsec + (DWORD)_drive._SClus*(h-2);
+
+                               h = _drive.read_FAT(h, ok);
+
+                               if (!ok)
+                                       return false;
+                       }
+
+                       for(i=0; i<_cur_bufs; i++) {
+                               if ((ok = (_drive.read_sector(_secarr->s[i], buf, _drive._SClus))) == true)
+                                       AddP(buf, _drive._bufl*_drive._SClus)
+                               else {
+                                       //@@FPara = _secarr->s[i];
+                                       return false;
+                               }
+                       }
+
+               buf->dat[0] = 0;         // Endekennzeichen für Rekurs setzen
+       }
+
+       return true;
+}
+
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4355)
+#endif
+
+FATDrive::FATDrive(LPCTSTR path)
+ :     FATDirectory(*this, TEXT("\\"))
+{
+       _bufl = 0;
+       _bufents = 0;
+       _SClus = 0;
+       _FATCache = NULL;
+       _CacheCount = 0;
+       _CacheSec = NULL;
+       _CacheCnt = NULL;
+       _CacheDty = NULL;
+       _Caches = 0;
+
+       _hDrive = CreateFile(path, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
+
+       if (_hDrive != INVALID_HANDLE_VALUE) {
+               _boot_sector.BytesPerSector = 512;
+
+               if (read_sector(0, (Buffer*)&_boot_sector, 1)) {
+                       _bufl = _boot_sector.BytesPerSector;
+                       _SClus = _boot_sector.SectorsPerCluster;
+                       _bufents = _bufl / sizeof(union DEntry);
+               }
+
+               small_cache();
+       }
+}
+
+FATDrive::~FATDrive()
+{
+       if (_hDrive != INVALID_HANDLE_VALUE)
+               CloseHandle(_hDrive);
+
+       free(_path);
+       _path = NULL;
+}
+
+void FATDrive::small_cache()
+{
+       if (_FATCache)
+               free(_FATCache);
+
+       if (_CacheSec) {
+               free(_CacheSec), _CacheSec = NULL;
+               free(_CacheCnt);
+               free(_CacheDty);
+       }
+
+       _Caches = CACHE_SIZE_LOW;
+       _FATCache = (struct Cache *) malloc((_Caches+1) * _drive._bufl);
+
+       reset_cache();
+}
+
+void FATDrive::reset_cache()   // mark cache as empty
+{
+       int i;
+
+       if (!_CacheSec) {
+               _CacheSec = (DWORD*) malloc(_Caches * sizeof(DWORD));
+               _CacheCnt = (int*) malloc(_Caches * sizeof(int));
+               _CacheDty = (bool*) malloc(_Caches * sizeof(bool));
+       } else {
+               _CacheSec = (DWORD*) realloc(_CacheSec, _Caches * sizeof(DWORD));
+               _CacheCnt = (int*) realloc(_CacheCnt, _Caches * sizeof(int));
+               _CacheDty = (bool*) realloc(_CacheDty, _Caches * sizeof(bool));
+       }
+
+       for(i=0; i<_Caches; i++)
+               _CacheSec[i] = 0;
+
+       _read_ahead = (_Caches+1) / 2;
+}
+
+bool FATDrive::read_sector(DWORD sec, Buffer* buf, int len)
+{
+       sec += 63;      //@@ jump to first partition
+
+       if (SetFilePointer(_hDrive, sec*_drive._boot_sector.BytesPerSector, 0, 0) == INVALID_SET_FILE_POINTER)
+               return false;
+
+       DWORD read;
+
+       if (!ReadFile(_hDrive, buf, len*_drive._boot_sector.BytesPerSector, &read, 0))
+               return false;
+
+       return true;
+}
+
+DWORD FATDrive::read_FAT(DWORD cluster, bool& ok)      //@@ use exception handling
+{
+       DWORD nClus;
+       Buffer* FATBuf;
+
+       DWORD nclus = (_boot_sector.Sectors32? _boot_sector.Sectors32: _boot_sector.Sectors16) / _boot_sector.SectorsPerCluster;        ///@todo cache result
+
+       if (cluster > nclus) {
+               ok = false;
+               return (DWORD)-1;
+       }
+
+       if (nclus >= 65536) {           // FAT32
+               DWORD FATsec = cluster / (_boot_sector.BytesPerSector/4);
+               DWORD z = (cluster - _boot_sector.BytesPerSector/4 * FATsec)*4;
+               FATsec += _boot_sector.ReservedSectors;
+               if (!read_cache(FATsec, &FATBuf))
+                       ok = false;
+               nClus = dpeek(&FATBuf->dat[z]);
+       } else if (nclus >= 4096) {     // 16 Bit-FAT
+               DWORD FATsec = cluster / (_boot_sector.BytesPerSector/2);
+               DWORD z = (cluster - _boot_sector.BytesPerSector/2 * FATsec)*2;
+               FATsec += _boot_sector.ReservedSectors;
+               if (!read_cache(FATsec, &FATBuf))
+                       ok = false;
+               nClus = wpeek(&FATBuf->dat[z]);
+
+               if (nClus >= 0xfff0)
+                       nClus |= 0x0fff0000;
+       } else {                                                // 12 Bit-FAT
+               DWORD FATsec = cluster*3 / (_boot_sector.BytesPerSector*2);
+               DWORD z = (cluster*3 - _boot_sector.BytesPerSector*2*FATsec)/2;
+               FATsec += _boot_sector.ReservedSectors;
+               if (!read_cache(FATsec,&FATBuf))
+                       ok = false;
+               BYTE a = FATBuf->dat[z++];
+
+               if (z >= _boot_sector.BytesPerSector)
+                       if (!read_cache(FATsec+1,&FATBuf))
+                               ok = false;
+               z = 0;
+
+               BYTE b = FATBuf->dat[z];
+
+               if (cluster & 1)
+                       nClus = (a>>4) | (b<<4);
+               else
+                       nClus = a | ((b & 0xf)<<8);
+
+               if (nClus >= 0xff0)
+                       nClus |= 0x0ffff000;
+       }
+
+       return nClus;
+}
+
+bool FATDrive::read_cache(DWORD sec, Buffer** bufptr)
+{
+ int i, C, anz;
+
+ if (_boot_sector.BytesPerSector != BufLen)  // no standard sector size?
+  return read_sector(sec, *bufptr=(Buffer*)&_FATCache[0], 1);
+
+ _CacheCount++;
+
+ for(i=0; _CacheSec[i]!=sec && i<_Caches; )
+  ++i;
+
+ if (i < _Caches)
+  {
+   *bufptr = (Buffer*) &_FATCache[i];   // FAT-Sektor schon gepuffert
+   _CacheCnt[i]++;
+   return true;
+  }
+
+ i = get_cache_buffer();
+
+ if (_cache_empty)             // von get_cache_buffer() gesetzt
+  {
+   C = _CacheCount-1;
+   anz = _boot_sector.SectorsPerFAT*_boot_sector.NumberFATs - sec;
+
+   if (anz > _read_ahead)
+       anz = _read_ahead;
+
+   for(i=0; i<anz; i++) {
+       _CacheSec[i] = sec++;
+       _CacheCnt[i] = C;
+       _CacheDty[i] = 0;
+   }
+
+   _CacheCnt[0] = _CacheCount;
+
+   return read_sector(_CacheSec[0], *bufptr=(Buffer*) &_FATCache[0], anz);
+  }
+ else
+  {
+   _CacheDty[i] = 0;
+   _CacheCnt[i] = _CacheCount;
+
+   return read_sector(_CacheSec[i]=sec, *bufptr=(Buffer*) &_FATCache[i], 1);
+  }
+}
+
+int FATDrive::get_cache_buffer()       // search for free cache buffer
+{
+ int i, j, minCnt;
+
+ for(i=0; i<_Caches; i++)
+  if (_CacheSec[i])
+   break;
+
+ _cache_empty = i==_Caches? true: false;
+
+ for(i=0; _CacheSec[i] && i<_Caches; )
+  ++i;
+
+ if (i < _Caches)
+  j = i;
+ else
+  {
+   minCnt = 0;                 // search for least used buffer
+
+   for(j=i=0; i<_Caches; i++)
+       if (minCnt < _CacheCnt[i]) {
+        minCnt = _CacheCnt[i];
+        j = i;
+       }
+
+/**@todo enable write back
+   if (CacheDty[j])    // Dirty-Flag gesetzt?
+       if (writesec(_CacheSec[j], (Buffer*) &_FATCache[j], 1))
+        FPara = _CacheSec[j], Frag(SecWriteErr);
+*/
+  }
+
+ return j;
+}
diff --git a/reactos/subsys/system/explorer/shell/fatfs.h b/reactos/subsys/system/explorer/shell/fatfs.h
new file mode 100644 (file)
index 0000000..ea9fac6
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2003 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+ //
+ // Explorer clone
+ //
+ // fatfs.h
+ //
+ // Martin Fuchs, 01.02.2004
+ //
+
+
+ /// FAT file system file-entry
+struct FATEntry : public Entry
+{
+       FATEntry(Entry* parent, unsigned cluster) : Entry(parent, ET_FAT), _cluster(cluster) {}
+
+protected:
+       FATEntry() : Entry(ET_FAT) {}
+
+       virtual bool get_path(PTSTR path) const;
+
+       DWORD   _cluster;
+};
+
+
+struct FATDrive;
+
+ /// FAT file system directory-entry
+struct FATDirectory : public FATEntry, public Directory
+{
+       FATDirectory(FATDrive& drive, LPCTSTR root_path);
+       FATDirectory(FATDrive& drive, Entry* parent, LPCTSTR path, unsigned cluster);
+       ~FATDirectory();
+
+       virtual void read_directory(int scan_flags=SCAN_ALL);
+       virtual Entry* find_entry(const void*);
+
+protected:
+       FATDrive&       _drive;
+
+       struct dirsecz* _secarr;
+       int     _cur_bufs;
+       int     _ents;
+       struct dirent* _dir;
+       struct Kette* _alloc;
+
+       bool    read_dir();
+};
+
+
+#pragma pack(push, 1)
+
+struct BootSector {
+       BYTE    jmp[3];
+       char    OEM[8];
+       WORD    BytesPerSector;         // dpb.bsec
+       BYTE    SectorsPerCluster;      // dpb.sclus + 1
+       WORD    ReservedSectors;        // dpb.ffatsec
+       BYTE    NumberFATs;
+       WORD    RootEntries;            // dpb.ndir
+       WORD    Sectors16;
+       BYTE    MediaDescr;
+       WORD    SectorsPerFAT;
+       WORD    SectorsPerTrack;
+       WORD    Heads;
+       DWORD   HiddenSectors;
+       DWORD   Sectors32;
+       BYTE    DriveUnit;
+       WORD    ExtBootFlag;
+       DWORD   SerialNr;
+       char    Label[11];
+       char    FileSystem[8];
+       BYTE    BootCode[448];
+       BYTE    BootSignature[2];
+};
+
+struct BootSector32 {
+       BYTE    jmp[3];
+       char    OEM[8];
+       WORD    BytesPerSector;
+       BYTE    SectorsPerCluster;
+       WORD    ReservedSectors;
+       BYTE    NumberFATs;
+       WORD    reserved1;      // immer 0 für FAT32
+       WORD    Sectors16;
+       BYTE    MediaDescr;
+       WORD    reserved2;      // immer 0 für FAT32
+       WORD    SectorsPerTrack;
+       WORD    Heads;
+       DWORD   HiddenSectors;
+       DWORD   Sectors32;
+       DWORD   SectorsPerFAT32;
+       DWORD   unknown1;
+       DWORD   RootSectors; // correct?
+       char    unknown2[6];
+       char    FileSystem[8];
+       BYTE    BootCode[448];
+       BYTE    BootSignature[2];
+};
+
+
+struct ftime {
+       WORD    sec2    : 5;
+       WORD    min     : 6;
+       WORD    hour    : 5;
+};
+
+struct fdate {
+       WORD    day     : 5;
+       WORD    month   : 4;
+       WORD    year    : 7;
+};
+
+typedef struct {
+       unsigned readonly       : 1;
+       unsigned hidden         : 1;
+       unsigned system         : 1;
+       unsigned volume         : 1;
+       unsigned directory      : 1;
+       unsigned archived       : 1;
+       unsigned deleted        : 1;
+} fattr;
+
+typedef union {
+       char    b;
+       fattr  a;
+} FAT_attribute;
+
+struct DEntry_E {
+       char                    name[8];
+       char                    ext[3];
+       char                    attr;
+       char                    rsrvd[10];
+       struct ftime    time;
+       struct fdate    date;
+       WORD                    fclus;
+       DWORD                   size;
+};
+
+union DEntry {
+       DEntry_E E;
+       BYTE B[8+3+1+10+sizeof(struct ftime)+sizeof(struct fdate)+sizeof(WORD)+sizeof(DWORD)];
+};
+
+#pragma pack(pop)
+
+
+#define BufLen 512
+
+struct Buffer {
+ BYTE  dat[BufLen];
+};
+
+struct Cache {
+ BYTE  dat[BufLen];
+};
+
+struct dskrwblk {
+ DWORD                 sec;
+ WORD                  anz;
+ struct buffer far *buf;
+};
+
+#define RONLY                  0x01
+#define HIDDEN                 0x02
+#define SYSTEM                 0x04
+#define VOLUME                 0x08
+#define DIRENT                 0x10
+#define ARCHIVE                0x20
+
+#define _A_DELETED             0x40
+#define _A_ILLEGAL             0x80
+#define IS_LNAME(a) ((a&0xFF)==0x0F)   // "& 0xFF" correct?
+
+#define FAT_DEL_CHAR   (char)0xe5
+
+#define AddP(p,s)  {(int&)p += s;}
+
+struct dirent {
+       union DEntry  ent[1];
+};
+
+struct dirsecz {
+       DWORD  s[32];  // 32 only as placeholder
+};
+
+struct Kette {
+ struct Kette* Vorw;
+ struct Kette* Rueck;
+ union DEntry* Ent;
+};
+
+
+#define        MK_P(ofs)               ((void*) ((size_t)(ofs)))
+#define        MK_LONG(l,h)    ((DWORD)WORD(l)|((DWORD)WORD(h)<<16))
+
+#define        spoke(ofs,w)    (*((BYTE*)MK_P(ofs)) = (BYTE)(w))
+#define        wpoke(ofs,w)    (*((WORD*)MK_P(ofs)) = (WORD)(w))
+#define        dpoke(ofs,w)    (*((DWORD*)MK_P(ofs)) = (DWORD)(w))
+#define        speek(ofs)              (*((BYTE*)MK_P(ofs)))
+#define        wpeek(ofs)              (*((WORD*)MK_P(ofs)))
+#define        dpeek(p)                (*((DWORD*)MK_P(p)))
+
+
+ /// FAT drive root entry
+struct FATDrive : public FATDirectory
+{
+       FATDrive(LPCTSTR path);
+/*
+       FATDrive(Entry* parent, LPCTSTR path)
+        :      FATEntry(parent)
+       {
+               _path = _tcsdup(path);
+       }
+*/
+       ~FATDrive();
+
+       HANDLE  _hDrive;
+       BootSector      _boot_sector;
+       int     _bufl;
+       int     _bufents;
+       int     _SClus;
+
+#define        CACHE_SIZE_LOW  32
+       Cache*  _FATCache;
+       int             _CacheCount;
+       DWORD*  _CacheSec;      // numbers of buffered cache sectors
+       int*    _CacheCnt;      // counters for cache usage
+       bool*   _CacheDty;      // dirty flags for cache
+       int             _Caches;
+       bool    _cache_empty;
+       int             _read_ahead;
+
+       bool    read_sector(DWORD sec, Buffer* buf, int len);
+       DWORD   read_FAT(DWORD Clus, bool& ok);
+
+       void    small_cache();
+       void    reset_cache();
+       bool    read_cache(DWORD sec, Buffer** bufptr);
+       int             get_cache_buffer();
+};
index a010b94..15a7714 100644 (file)
@@ -32,6 +32,7 @@
 #include "../globals.h"
 #include "ntobjfs.h"
 #include "regfs.h"
+#include "fatfs.h"
 
 #include "../explorer_intres.h"
 
@@ -82,6 +83,13 @@ RegistryChildWndInfo::RegistryChildWndInfo(LPCTSTR path)
 }
 
 
+FATChildWndInfo::FATChildWndInfo(LPCTSTR path)
+ :     FileChildWndInfo(path)
+{
+       _etype = ET_FAT;
+}
+
+
 FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
  :     ChildWindow(hwnd)
 {
@@ -143,6 +151,18 @@ FileChildWindow::FileChildWindow(HWND hwnd, const FileChildWndInfo& info)
                _root._entry = new RegistryRoot();
                entry = _root._entry->read_tree(info._path, SORT_NONE);
        }
+       else if (info._etype == ET_FAT)
+       {
+               _root._drive_type = DRIVE_UNKNOWN;
+
+               _tsplitpath(info._path, drv, NULL, NULL, NULL);
+               lstrcat(drv, TEXT("\\"));
+               lstrcpy(_root._volname, TEXT("FAT XXX"));       //@@
+               lstrcpy(_root._fs, TEXT("FAT"));
+               lstrcpy(_root._path, drv);
+               _root._entry = new FATDrive(TEXT("c:/reactos-bochs/cdrv.img")); //TEXT("\\\\.\\F:"));   //@@
+               entry = _root._entry->read_tree(info._path, SORT_NONE);
+       }
        else //if (info._etype == ET_WINDOWS)
        {
                _root._drive_type = GetDriveType(info._path);
@@ -422,12 +442,15 @@ LRESULT FileChildWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
                         // now create the popup menu using shell namespace and IContextMenu
                        Pane* pane = GetFocus()==_left_hwnd? _left: _right;
                        int idx = ListBox_GetCurSel(*pane);
-                       Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
+                       if (idx != -1) {
+                               Entry* entry = (Entry*) ListBox_GetItemData(*pane, idx);
 
-                       ShellPath shell_path = entry->create_absolute_pidl();
-                       LPCITEMIDLIST pidl = shell_path;
+                               ShellPath shell_path = entry->create_absolute_pidl();
+                               LPCITEMIDLIST pidl = shell_path;
 
-                       CHECKERROR(ShellFolderContextMenu(Desktop(), _hwnd, 1, &pidl, pos.x, pos.y));
+                               ///@todo use parent folder instead of desktop -> correct "Properties" dialog, ...
+                               CHECKERROR(ShellFolderContextMenu(Desktop(), _hwnd, 1, &pidl, pos.x, pos.y));
+                       }
                        break;}
 
                default: def:
index 1b50eaa..9375a23 100644 (file)
@@ -59,6 +59,12 @@ struct RegistryChildWndInfo : public FileChildWndInfo
        RegistryChildWndInfo(LPCTSTR path);
 };
 
+ /// information structure for creation of FileChildWindow for the Registry
+struct FATChildWndInfo : public FileChildWndInfo
+{
+       FATChildWndInfo(LPCTSTR path);
+};
+
 
  /// MDI child window displaying file lists
 struct FileChildWindow : public ChildWindow
index 2954e58..2a99eb5 100644 (file)
@@ -129,6 +129,13 @@ MainFrame::MainFrame(HWND hwnd)
 
        drivebarBtn.idCommand = ID_DRIVE_REGISTRY;
        SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
+       ++drivebarBtn.iString;
+
+        // insert FAT direct file system access button
+       SendMessage(_hdrivebar, TB_ADDSTRING, 0, (LPARAM)TEXT("FAT\0"));
+
+       drivebarBtn.idCommand = ID_DRIVE_FAT;
+       SendMessage(_hdrivebar, TB_INSERTBUTTON, btn++, (LPARAM)&drivebarBtn);
        ++drivebarBtn.iString;
 
         // register windows drive root strings
@@ -551,6 +558,20 @@ int MainFrame::Command(int id, int code)
 #endif
          break;}
 
+         case ID_DRIVE_FAT: {
+
+               ///@todo prompt for image file
+
+               if (activate_child_window(TEXT("FAT")))
+                       break;
+
+#ifndef _NO_MDI
+               FileChildWindow::create(_hmdiclient, FATChildWndInfo(TEXT("FAT Image")));       //@@
+#else
+               ///@todo SDI implementation
+#endif
+         break;}
+
          case ID_DRIVE_DESKTOP: {
                TCHAR path[MAX_PATH];
 
index 4bc41a0..5b8336c 100644 (file)
@@ -329,9 +329,6 @@ void NtObjDirectory::read_directory(int scan_flags)
                        if (last)
                                last->_next = entry;
 
-                       entry->_down = NULL;
-                       entry->_expanded = false;
-                       entry->_scanned = false;
                        entry->_level = level;
 
                        last = entry;
index 6ccc7f6..68704d0 100644 (file)
@@ -69,7 +69,7 @@ static const int g_pos_align[] = {
        HDF_LEFT,       /* ADate */
        HDF_LEFT,       /* MDate */
        HDF_LEFT,       /* Index */
-       HDF_CENTER,     /* Links */
+       HDF_RIGHT,      /* Links */
        HDF_CENTER,     /* Attributes */
        HDF_LEFT,       /* Security */
        HDF_LEFT        /* Content / Description */
@@ -484,7 +484,6 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
                _out_wrkr.output_text(dis, _positions, col, entry->_display_name, 0);
        else if (calcWidthCol==col || calcWidthCol==COLUMNS)
                calc_width(dis, col, entry->_display_name);
-
        ++col;
 
         // output type/class name
@@ -494,7 +493,6 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
                else if (calcWidthCol==col || calcWidthCol==COLUMNS)
                        calc_width(dis, col, entry->_type_name);
        }
-
        ++col;
 
         // display file size
@@ -507,9 +505,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
                        _out_wrkr.output_number(dis, _positions, col, buffer);
                else if (calcWidthCol==col || calcWidthCol==COLUMNS)
                        calc_width(dis, col, buffer);   ///@todo not in every case time enough
-
-               ++col;
        }
+       ++col;
 
         // display file date
        if (visible_cols & (COL_DATE|COL_TIME)) {
@@ -533,7 +530,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
                else if (calcWidthCol==col || calcWidthCol==COLUMNS)
                        calc_width(dis, col, buffer);
                ++col;
-       }
+       } else
+               col += 3;
 
        if (entry->_bhfi_valid) {
                ULONGLONG index = ((ULONGLONG)entry->_bhfi.nFileIndexHigh << 32) | entry->_bhfi.nFileIndexLow;
@@ -550,7 +548,7 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
                if (visible_cols & COL_LINKS) {
                        wsprintf(buffer, TEXT("%d"), entry->_bhfi.nNumberOfLinks);
                        if (calcWidthCol == -1)
-                               _out_wrkr.output_text(dis, _positions, col, buffer, DT_CENTER);
+                               _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT);
                        else if (calcWidthCol==col || calcWidthCol==COLUMNS)
                                calc_width(dis, col, buffer);
                        ++col;
@@ -584,9 +582,8 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
                        _out_wrkr.output_tabbed_text(dis, _positions, col, buffer);
                else if (calcWidthCol==col || calcWidthCol==COLUMNS)
                        calc_tabbed_width(dis, col, buffer);
-
-               ++col;
        }
+       ++col;
 
 /*TODO
        if (flags.security) {
@@ -615,10 +612,9 @@ void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol)
                output_text(dis, col++, buffer, 0, psize);
        }
 */
-
        ++col;
 
-        // output content / symbolic link target 
+        // output content / symbolic link target / comment
        if (visible_cols & COL_CONTENT) {
                if (calcWidthCol == -1)
                        _out_wrkr.output_text(dis, _positions, col, entry->_content, 0);
index a9eb9fb..aa09ab2 100644 (file)
@@ -43,13 +43,13 @@ void RegDirectory::read_directory(int scan_flags)
        TCHAR buffer[MAX_PATH];
 
        _tcscpy(buffer, (LPCTSTR)_path);
-       LPTSTR p = buffer + _tcslen(buffer);
+       LPTSTR pname = buffer + _tcslen(buffer);
 
        HKEY hKey;
 
        if (!RegOpenKeyEx(_hKeyRoot, *buffer=='\\'?buffer+1:buffer, 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey)) {
-               if (p[-1] != '\\')
-                       *p++ = '\\';
+               if (pname[-1] != '\\')
+                       *pname++ = '\\';
 
                TCHAR name[MAX_PATH], class_name[MAX_PATH];
                WIN32_FIND_DATA w32fd;
@@ -68,7 +68,7 @@ void RegDirectory::read_directory(int scan_flags)
                        w32fd.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
                        lstrcpy(w32fd.cFileName, name);
 
-                       _tcscpy(p, name);
+                       _tcscpy(pname, name);
                        entry = new RegDirectory(this, buffer, _hKeyRoot);
 
                        memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
@@ -82,9 +82,6 @@ void RegDirectory::read_directory(int scan_flags)
                        if (last)
                                last->_next = entry;
 
-                       entry->_down = NULL;
-                       entry->_expanded = false;
-                       entry->_scanned = false;
                        entry->_level = level;
 
                        last = entry;
@@ -110,9 +107,6 @@ void RegDirectory::read_directory(int scan_flags)
                        if (last)
                                last->_next = entry;
 
-                       entry->_down = NULL;
-                       entry->_expanded = false;
-                       entry->_scanned = false;
                        entry->_level = level;
 
                        last = entry;
@@ -171,9 +165,6 @@ void RegDirectory::read_directory(int scan_flags)
                        if (last)
                                last->_next = entry;
 
-                       entry->_down = NULL;
-                       entry->_expanded = false;
-                       entry->_scanned = false;
                        entry->_level = level;
 
                        last = entry;
index 2465d91..2ae6f4e 100644 (file)
@@ -217,6 +217,12 @@ void ShellBrowserChild::Tree_DoItemMenu(HWND hwndTreeView, HTREEITEM hItem, LPPO
                        LPCITEMIDLIST pidl = static_cast<ShellEntry*>(entry)->_pidl;
 
                        CHECKERROR(ShellFolderContextMenu(folder, ::GetParent(hwndTreeView), 1, &pidl, pptScreen->x, pptScreen->y));
+               } else {
+                       ShellPath shell_path = entry->create_absolute_pidl();
+                       LPCITEMIDLIST pidl = shell_path;
+
+                       ///@todo use parent folder instead of desktop
+                       CHECKERROR(ShellFolderContextMenu(Desktop(), _hwnd, 1, &pidl, pptScreen->x, pptScreen->y));
                }
        }
 }
index 719d2da..f3c6c94 100644 (file)
@@ -261,11 +261,7 @@ void ShellDirectory::read_directory(int scan_flags)
 
                                memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
 
-                               entry->_down = NULL;
-                               entry->_expanded = false;
-                               entry->_scanned = false;
                                entry->_level = level;
-                               entry->_bhfi_valid = false;
 
                                if (scan_flags & SCAN_DO_ACCESS) {
                                        HANDLE hFile = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
@@ -400,9 +396,6 @@ void ShellDirectory::read_directory(int scan_flags)
                                        if (attribs & SFGAO_LINK)
                                                w32fd.dwFileAttributes |= ATTRIBUTE_SYMBOLIC_LINK;
 
-                                       entry->_down = NULL;
-                                       entry->_expanded = false;
-                                       entry->_scanned = false;
                                        entry->_level = level;
                                        entry->_shell_attribs = attribs;
                                        entry->_bhfi_valid = bhfi_valid;
index a8e9a65..ee3b47c 100644 (file)
@@ -104,7 +104,6 @@ void UnixDirectory::read_directory()
                                entry->_bhfi_valid = FALSE;
                        }
 
-                       entry->_down = NULL;
                        entry->_up = this;
                        entry->_expanded = FALSE;
                        entry->_scanned = FALSE;
index 4737fcc..7a13156 100644 (file)
@@ -130,18 +130,18 @@ void WinDirectory::read_directory(int scan_flags)
        Entry* entry;
 
        LPCTSTR path = (LPCTSTR)_path;
-       TCHAR buffer[MAX_PATH], *p;
-       for(p=buffer; *path; )
-               *p++ = *path++;
+       TCHAR buffer[MAX_PATH], *pname;
+       for(pname=buffer; *path; )
+               *pname++ = *path++;
 
-       lstrcpy(p, TEXT("\\*"));
+       lstrcpy(pname, TEXT("\\*"));
 
        WIN32_FIND_DATA w32fd;
        HANDLE hFind = FindFirstFile(buffer, &w32fd);
 
        if (hFind != INVALID_HANDLE_VALUE) {
                do {
-                       lstrcpy(p+1, w32fd.cFileName);
+                       lstrcpy(pname+1, w32fd.cFileName);
 
                        if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                                entry = new WinDirectory(this, buffer);
@@ -155,9 +155,6 @@ void WinDirectory::read_directory(int scan_flags)
                                last->_next = entry;
 
                        memcpy(&entry->_data, &w32fd, sizeof(WIN32_FIND_DATA));
-                       entry->_down = NULL;
-                       entry->_expanded = false;
-                       entry->_scanned = false;
                        entry->_level = level;
 
                         // display file type names, but don't hide file extensions
index f1ef438..453de98 100644 (file)
@@ -165,11 +165,12 @@ BOOL time_to_filetime(const time_t* t, FILETIME* ftime)
 
        stime.wYear = tm->tm_year+1900;
        stime.wMonth = tm->tm_mon+1;
-       /*      stime.wDayOfWeek */
+       stime.wDayOfWeek = (WORD)-1;
        stime.wDay = tm->tm_mday;
        stime.wHour = tm->tm_hour;
        stime.wMinute = tm->tm_min;
        stime.wSecond = tm->tm_sec;
+       stime.wMilliseconds = 0;
 
        return SystemTimeToFileTime(&stime, ftime);
 }