mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
reading of FAT image files (work in progress)
svn path=/trunk/; revision=8005
This commit is contained in:
parent
2f3d748c1d
commit
51612d040b
23 changed files with 1019 additions and 52 deletions
|
@ -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
|
||||
|
|
|
@ -82,6 +82,7 @@ OBJECTS = \
|
|||
shellfs.o \
|
||||
ntobjfs.o \
|
||||
regfs.o \
|
||||
fatfs.o \
|
||||
mainframe.o \
|
||||
filechild.o \
|
||||
pane.o \
|
||||
|
|
|
@ -56,6 +56,7 @@ OBJECTS = \
|
|||
shellfs.o \
|
||||
ntobjfs.o \
|
||||
regfs.o \
|
||||
fatfs.o \
|
||||
mainframe.o \
|
||||
filechild.o \
|
||||
pane.o \
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -120,7 +120,8 @@
|
|||
#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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
661
reactos/subsys/system/explorer/shell/fatfs.cpp
Normal file
661
reactos/subsys/system/explorer/shell/fatfs.cpp
Normal file
|
@ -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;
|
||||
}
|
258
reactos/subsys/system/explorer/shell/fatfs.h
Normal file
258
reactos/subsys/system/explorer/shell/fatfs.h
Normal file
|
@ -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();
|
||||
};
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -104,7 +104,6 @@ void UnixDirectory::read_directory()
|
|||
entry->_bhfi_valid = FALSE;
|
||||
}
|
||||
|
||||
entry->_down = NULL;
|
||||
entry->_up = this;
|
||||
entry->_expanded = FALSE;
|
||||
entry->_scanned = FALSE;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue