1
0
Fork 0

added directory cache

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@630
This commit is contained in:
Ulf Wohlers 2003-01-15 20:07:57 +00:00
parent a1f52fbd1d
commit fb2896a653
3 changed files with 578 additions and 31 deletions

462
src/dos/drive_cache.cpp Normal file
View file

@ -0,0 +1,462 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "drives.h"
#include "dos_inc.h"
#include "dirent.h"
#include "support.h"
// STL stuff
#include <vector>
#include <iterator>
#include <algorithm>
bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
{
return strcmp(a->shortname,b->shortname)<0;
};
bool SortByNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
{
return strcmp(a->shortname,b->shortname)>0;
};
bool SortByDirName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
{
// Directories first...
if (a->isDir!=b->isDir) return (a->isDir>b->isDir);
return strcmp(a->shortname,b->shortname)<0;
};
bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
{
// Directories first...
if (a->isDir!=b->isDir) return (a->isDir>b->isDir);
return strcmp(a->shortname,b->shortname)>0;
};
DOS_Drive_Cache::DOS_Drive_Cache(void)
{
dirBase = new CFileInfo;
dirSearch = 0;
save_dir = 0;
SetDirSort(DIRALPHABETICAL);
};
DOS_Drive_Cache::DOS_Drive_Cache(const char* path)
{
dirBase = new CFileInfo;
dirSearch = 0;
save_dir = 0;
SetDirSort(DIRALPHABETICAL);
SetBaseDir(path);
};
DOS_Drive_Cache::~DOS_Drive_Cache(void)
{
delete dirBase; dirBase = 0;
};
void DOS_Drive_Cache::SetBaseDir(const char* baseDir)
{
strcpy(dirBase->fullname,baseDir);
if (OpenDir(baseDir)) {
struct dirent result;
struct stat status;
ReadDir(&result,&status);
};
};
void DOS_Drive_Cache::ExpandName(char* path)
{
strcpy(path,GetExpandName(path));
};
char* DOS_Drive_Cache::GetExpandName(const char* path)
{
static char work [CROSS_LEN];
char dir [CROSS_LEN];
work[0] = 0;
strcpy (dir,path);
char* pos = strrchr(path,CROSS_FILESPLIT);
if (pos) dir[pos-path+1] = 0;
CFileInfo* dirInfo = FindDirInfo(dir, work);
if (pos) {
// Last Entry = File
strcpy(dir,pos+1);
if (strchr(dir,'~')) GetLongName(dirInfo, dir);
strcat(work,dir);
}
return work;
};
void DOS_Drive_Cache::AddEntry(const char* path)
{
// Get Last part...
char file [CROSS_LEN];
char expand [CROSS_LEN];
CFileInfo* dir = FindDirInfo(path,expand);
char* pos = strrchr(path,CROSS_FILESPLIT);
if (pos) {
strcpy(file,pos+1);
CreateEntry(dir,file);
// Sort Lists - filelist has to be alphabetically sorted
std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName);
// Output list - user defined
switch (sortDirType) {
case ALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByName); break;
case DIRALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirName); break;
case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break;
case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break;
};
}
};
void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir)
{
char expand[CROSS_LEN] = { 0 };
CFileInfo* dir;
if (ignoreLastDir) {
char tmp[CROSS_LEN] = { 0 };
Bit32s len = strrchr(path,CROSS_FILESPLIT) - path;
if (len>0) {
strncpy(tmp,path,len);
tmp[len] = 0;
} else {
strcpy(tmp,path);
}
dir = FindDirInfo(tmp,expand);
} else {
dir = FindDirInfo(path,expand);
}
// LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->fullname);
// delete file objects...
for(Bit32u i=0; i<dir->fileList.size(); i++) delete dir->fileList[i];
// clear lists
dir->fileList.clear();
dir->longNameList.clear();
dir->outputList.clear();
dir->shortNr = 0;
save_dir = 0;
nextEntry = 0;
};
bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir)
{
return (curDir->fileList.size()>0);
};
Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name)
{
Bit16s foundNr = 0;
Bit16s low = 0;
Bit16s high = curDir->longNameList.size()-1;
Bit16s mid, res;
CFileInfo* test;
while (low<=high) {
mid = (low+high)/2;
test = curDir->longNameList[mid];
res = strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount);
if (res>0) low = mid+1; else
if (res<0) high = mid-1;
else {
// any more same x chars in next entries ?
do {
foundNr = curDir->longNameList[mid]->shortNr;
mid++;
} while(mid<curDir->longNameList.size() && (strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount)==0));
break;
};
}
return foundNr+1;
};
Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName)
{
// Search long name and return array number of element
Bit16s low = 0;
Bit16s high = curDir->fileList.size()-1;
Bit16s mid,res;
while (low<=high) {
mid = (low+high)/2;
CFileInfo* test = curDir->fileList[mid];
res = strcmp(shortName,curDir->fileList[mid]->shortname);
if (res>0) low = mid+1; else
if (res<0) high = mid-1; else
{ // Found
// strcpy(shortName,curDir->fileList[mid]->fullname);
strcpy(shortName,curDir->fileList[mid]->orgname);
return mid;
};
}
// not available
return -1;
};
Bit16s DOS_Drive_Cache::RemoveSpaces(char* str)
// Removes all spaces
// return length of string upto first '.'
{
char* curpos = str;
char* chkpos = str;
Bit16s len = -1;
while (*chkpos!=0) {
if (*chkpos=='.') { if (len<0) len = curpos - str; };
if (*chkpos==' ') chkpos++; else *curpos++ = *chkpos++;
}
*curpos = 0;
if (len<0) len = curpos - str;
return len;
};
void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info)
{
Bit16s len = 0;
Bit16s lenExt = 0;
char tmpName[CROSS_LEN];
// Remove Spaces
strcpy(tmpName,info->fullname);
len = RemoveSpaces(tmpName);
// Get Length of filename
char* pos = strchr(tmpName,'.');
if (pos) {
len = (Bit16u)(pos - tmpName);
// Get Length of extension
lenExt = strlen(pos)-1;
} else
len = strlen(tmpName);
// Should shortname version be created ?
bool createShort = (len>8) || (lenExt>3);
// if (!createShort) {
// char buffer[CROSS_LEN];
// strcpy(buffer,tmpName);
// createShort = (GetLongName(curDir,buffer)>=0);
// }
if (createShort) {
// Create number
char buffer[8];
info->shortNr = CreateShortNameID(curDir,tmpName);
sprintf(buffer,"%d",info->shortNr);
// Copy first letters
Bit16u tocopy;
if (len+strlen(buffer)>8) tocopy = 8 - strlen(buffer) - 1;
else tocopy = len;
strncpy(info->shortname,tmpName,tocopy);
info->shortname[tocopy] = 0;
// Copy number
strcat(info->shortname,"~");
strcat(info->shortname,buffer);
// Create compare Count
info->compareCount = tocopy;
// Add (and cut) Extension, if available
if (pos) {
// Step to last extension...
pos = strrchr(tmpName, '.');
// add extension
strncat(info->shortname,pos,4);
info->shortname[DOS_NAMELENGTH] = 0;
};
// Put it in longname list...
curDir->longNameList.push_back(info);
std::sort(curDir->longNameList.begin(), curDir->longNameList.end(), SortByName);
} else {
strcpy(info->shortname,tmpName);
}
};
DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* expandedPath)
{
// statics
static char split[2] = { CROSS_FILESPLIT,0 };
char dir [CROSS_LEN];
char work [CROSS_LEN];
char* start = (char*)path;
char* pos;
CFileInfo* curDir = dirBase;
if (save_dir && (strcmp(path,save_path)==0)) {
strcpy(expandedPath,save_expanded);
return save_dir;
};
// LOG_DEBUG("DIR: Find %s",path);
// Remove base dir path
start += strlen(dirBase->fullname);
strcpy(expandedPath,dirBase->fullname);
do {
// bool errorcheck = false;
pos = strchr(start,CROSS_FILESPLIT);
if (pos) { strncpy(dir,start,pos-start); dir[pos-start] = 0; /*errorcheck = true;*/ }
else { strcpy(dir,start); };
// Path found
Bit16s nextDir = GetLongName(curDir,dir);
strcat(expandedPath,dir);
// Error check
// if ((errorcheck) && (nextDir<0)) {
// LOG_DEBUG("DIR: Error: %s not found.",expandedPath);
// };
// Follow Directory
if ((nextDir>=0) && curDir->fileList[nextDir]->isDir) {
curDir = curDir->fileList[nextDir];
strcpy (curDir->fullname,dir);
strcpy (work,path);
// Cut Directory, if its only part of whole path
if (pos) work[(Bit32u)pos-(Bit32u)path] = 0;
if (!IsCachedIn(curDir)) {
if (OpenDir(curDir,work)) {
struct dirent result;
struct stat status;
ReadDir(&result,&status);
};
}
};
if (pos) {
strcat(expandedPath,split);
start = pos+1;
}
} while (pos);
// Save last result for faster access next time
strcpy(save_path,path);
strcpy(save_expanded,expandedPath);
save_dir = curDir;
return curDir;
};
bool DOS_Drive_Cache::OpenDir(const char* path)
{
char expand[CROSS_LEN] = {0};
CFileInfo* dir = FindDirInfo(path,expand);
return OpenDir(dir,expand);
};
bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand)
{
dirSearch = dir;
// Add "/"
char end[2]={CROSS_FILESPLIT,0};
if (expand[strlen(expand)-1]!=CROSS_FILESPLIT) strcat(expand,end);
// open dir
if (dirSearch) {
// open dir
DIR* dirp = opendir(expand);
if (dirp) {
dirFirstTime = true;
closedir(dirp);
strcpy(dirPath,expand);
return true;
}
};
return false;
};
void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name)
{
struct stat status;
CFileInfo* info = new CFileInfo;
strcpy(info->fullname,name);
strcpy(info->orgname ,name);
// always upcase
upcase(info->fullname);
info->shortNr = 0;
// Read and copy file stats
char buffer[CROSS_LEN];
strcpy(buffer,dirPath);
strcat(buffer,info->fullname);
stat (buffer,&status);
memcpy(&info->status,&status,sizeof(status));
info->isDir = (S_ISDIR(status.st_mode)>0);
// Check for long filenames...
CreateShortName(dir, info);
// Put file in lists
dir->fileList.push_back(info);
dir->outputList.push_back(info);
};
bool DOS_Drive_Cache::ReadDir(struct dirent* result, struct stat *status)
{
if (dirFirstTime) {
if (!IsCachedIn(dirSearch)) {
// Try to open directory
DIR* dirp = opendir(dirPath);
if (!dirp) {
// LOG_DEBUG("DIR: Error Caching in %s",dirPath);
return false;
} else {
// LOG_DEBUG("DIR: Caching in %s",dirPath);
};
// Read complete directory
struct dirent* tmpres;
while (tmpres = readdir(dirp)) {
CreateEntry(dirSearch,tmpres->d_name);
}
// close dir
closedir(dirp);
// Sort Lists - filelist has to be alphabetically sorted
std::sort(dirSearch->fileList.begin(), dirSearch->fileList.end(), SortByName);
// Output list - user defined
switch (sortDirType) {
case ALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByName); break;
case DIRALPHABETICAL : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirName); break;
case ALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByNameRev); break;
case DIRALPHABETICALREV : std::sort(dirSearch->outputList.begin(), dirSearch->outputList.end(), SortByDirNameRev); break;
};
} else {
dirFirstTime=false;
}
// Reset it..
nextEntry = 0;
};
return SetResult(dirSearch, result, status, nextEntry);
};
bool DOS_Drive_Cache::SetResult(CFileInfo* dir, struct dirent* result, struct stat* status, Bit16u entryNr)
{
if (entryNr>=dir->outputList.size()) return false;
CFileInfo* info = dir->outputList[entryNr];
// copy filename, short version
strcpy(result->d_name,info->shortname);
// copy file status
memcpy(status,&info->status,sizeof(info->status));
// Set to next Entry
nextEntry = entryNr+1;
return true;
};

View file

@ -49,8 +49,9 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) {
strcpy(newname,basedir);
strcat(newname,name);
CROSS_FILENAME(newname);
FILE * hand=fopen(newname,"wb+");
FILE * hand=fopen(dirCache.GetExpandName(newname),"wb+");
if (!hand) return false;
dirCache.AddEntry(newname);
/* Make the 16 bit device information */
*file=new localFile(hand,0x202);
return true;
@ -59,9 +60,9 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) {
bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
char * type;
switch (flags) {
case OPEN_READ:type="rb";break;
case OPEN_WRITE:type="rb+";break;
case OPEN_READWRITE:type="rb+";break;
case OPEN_READ:type="rb"; break;
case OPEN_WRITE:type="rb+"; break;
case OPEN_READWRITE:type="rb+"; break;
default:
//TODO FIX IT
type="rb+";
@ -72,10 +73,13 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
strcpy(newname,basedir);
strcat(newname,name);
CROSS_FILENAME(newname);
dirCache.ExpandName(newname);
FILE * hand=fopen(newname,type);
Bit32u err=errno;
if (!hand) return false;
*file=new localFile(hand,0x202);
// (*file)->SetFileName(newname);
return true;
};
@ -84,54 +88,59 @@ bool localDrive::FileUnlink(char * name) {
strcpy(newname,basedir);
strcat(newname,name);
CROSS_FILENAME(newname);
if (!unlink(newname)) return true;
if (!unlink(dirCache.GetExpandName(newname))) {
dirCache.CacheOut(newname);
return true;
};
return false;
};
bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) {
if (srch_opendir) closedir(srch_opendir);
strcpy(srch_dir,basedir);
strcat(srch_dir,_dir);
CROSS_FILENAME(srch_dir);
char end[2]={CROSS_FILESPLIT,0};
if (srch_dir[strlen(srch_dir)-1]!=CROSS_FILESPLIT) strcat(srch_dir,end);
if((srch_opendir=opendir(srch_dir))==NULL) return false;
if (!dirCache.OpenDir(srch_dir)) return false;
return FindNext(dta);
}
bool localDrive::FindNext(DOS_DTA & dta) {
struct dirent * dir_ent;
struct dirent dir_ent;
struct stat stat_block;
char full_name[CROSS_LEN];
Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII];
Bit8u find_attr;
if(!srch_opendir) return false;
dta.GetSearchParams(srch_attr,srch_pattern);
again:
if((dir_ent=readdir(srch_opendir))==NULL) {
closedir(srch_opendir);
srch_opendir=NULL;
return false;
}
if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again;
strcpy(full_name,srch_dir);
strcat(full_name,dir_ent->d_name);
if(stat(full_name,&stat_block)!=0){
goto again;
}
again:
if (!dirCache.ReadDir(&dir_ent,&stat_block)) return false;
if(!WildFileCmp(dir_ent.d_name,srch_pattern)) goto again;
if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY;
else find_attr=DOS_ATTR_ARCHIVE;
if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again;
if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY;
else find_attr=DOS_ATTR_ARCHIVE;
if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again;
/*file is okay, setup everything to be copied in DTA Block */
char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size;
if(strlen(dir_ent->d_name)<DOS_NAMELENGTH_ASCII){
strcpy(find_name,dir_ent->d_name);
if(strlen(dir_ent.d_name)<DOS_NAMELENGTH_ASCII){
strcpy(find_name,dir_ent.d_name);
upcase(find_name);
} else strcpy(find_name,"LONGNAME.ERR");
}
find_size=(Bit32u) stat_block.st_size;
struct tm *time;
if((time=localtime(&stat_block.st_mtime))!=0){
@ -150,6 +159,7 @@ bool localDrive::GetFileAttr(char * name,Bit16u * attr) {
strcpy(newname,basedir);
strcat(newname,name);
CROSS_FILENAME(newname);
dirCache.ExpandName(newname);
FILE * hand=fopen(newname,"rb");
if (hand) {
fclose(hand);
@ -166,10 +176,11 @@ bool localDrive::MakeDir(char * dir) {
strcat(newdir,dir);
CROSS_FILENAME(newdir);
#if defined (WIN32) /* MS Visual C++ */
int temp=mkdir(newdir);
int temp=mkdir(dirCache.GetExpandName(newdir));
#else
int temp=mkdir(newdir,0700);
int temp=mkdir(dirCache.GetExpandName(newdir),0700);
#endif
if (temp==0) dirCache.CacheOut(newdir,true);
// if dir already exists, return success too.
return (temp==0) || ((temp!=0) && (errno==EEXIST));
}
@ -179,7 +190,8 @@ bool localDrive::RemoveDir(char * dir) {
strcpy(newdir,basedir);
strcat(newdir,dir);
CROSS_FILENAME(newdir);
int temp=rmdir(newdir);
int temp=rmdir(dirCache.GetExpandName(newdir));
if (temp==0) dirCache.CacheOut(newdir,true);
return (temp==0);
}
@ -188,6 +200,7 @@ bool localDrive::TestDir(char * dir) {
strcpy(newdir,basedir);
strcat(newdir,dir);
CROSS_FILENAME(newdir);
dirCache.ExpandName(newdir);
// Skip directory test, if "\"
Bit16u len = strlen(newdir);
if ((len>0) && (newdir[len-1]!='\\')) {
@ -209,7 +222,8 @@ bool localDrive::Rename(char * oldname,char * newname) {
strcpy(newnew,basedir);
strcat(newnew,newname);
CROSS_FILENAME(newnew);
int temp=rename(newold,newnew);
int temp=rename(dirCache.GetExpandName(newold),dirCache.GetExpandName(newnew));
if (temp==0) dirCache.CacheOut(newnew);
return (temp==0);
};
@ -229,6 +243,7 @@ bool localDrive::FileExists(const char* name) {
strcpy(newname,basedir);
strcat(newname,name);
CROSS_FILENAME(newname);
dirCache.ExpandName(newname);
FILE* Temp=fopen(newname,"rb");
if(Temp==NULL) return false;
fclose(Temp);
@ -240,6 +255,7 @@ bool localDrive::FileStat(const char* name, FileStat_Block * const stat_block) {
strcpy(newname,basedir);
strcat(newname,name);
CROSS_FILENAME(newname);
dirCache.ExpandName(newname);
struct stat temp_stat;
if(stat(newname,&temp_stat)!=0) return false;
/* Convert the stat to a FileStat */
@ -268,6 +284,8 @@ localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors
allocation.total_clusters=_total_clusters;
allocation.free_clusters=_free_clusters;
allocation.mediaid=_mediaid;
dirCache.SetBaseDir(basedir);
}
@ -312,6 +330,7 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) {
}
bool localFile::Close() {
fclose(fhandle);
return true;
}
@ -319,7 +338,7 @@ bool localFile::Close() {
Bit16u localFile::GetInformation(void) {
return info;
}
localFile::localFile(FILE * handle,Bit16u devinfo) {
fhandle=handle;

View file

@ -21,12 +21,77 @@
#include <sys/types.h>
#include <dirent.h>
#include <vector>
#include "dos_system.h"
#include "cross.h"
bool WildFileCmp(const char * file, const char * wild);
class DOS_Drive_Cache {
public:
DOS_Drive_Cache (void);
DOS_Drive_Cache (const char* path);
~DOS_Drive_Cache (void);
typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV };
void SetBaseDir (const char* path);
void SetDirSort (TDirSort sort) { sortDirType = sort; };
bool OpenDir (const char* path);
bool ReadDir (struct dirent* result,struct stat* status);
void ExpandName (char* path);
char* GetExpandName (const char* path);
void CacheOut (const char* path, bool ignoreLastDir = false);
void AddEntry (const char* path);
class CFileInfo {
public:
~CFileInfo(void) {
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
fileList.clear();
longNameList.clear();
outputList.clear();
};
char fullname [CROSS_LEN];
char orgname [CROSS_LEN];
char shortname [DOS_NAMELENGTH_ASCII];
bool isDir;
Bit16u shortNr;
Bit16u compareCount;
struct stat status;
// contents
std::vector<CFileInfo*> fileList;
std::vector<CFileInfo*> longNameList;
std::vector<CFileInfo*> outputList;
};
private:
Bit16s GetLongName (CFileInfo* info, char* shortname);
void CreateShortName (CFileInfo* dir, CFileInfo* info);
Bit16u CreateShortNameID (CFileInfo* dir, const char* name);
bool SetResult (CFileInfo* dir, struct dirent* result, struct stat* status, Bit16u entryNr);
bool IsCachedIn (CFileInfo* dir);
CFileInfo* FindDirInfo (const char* path, char* expandedPath);
Bit16s RemoveSpaces (char* str);
bool OpenDir (CFileInfo* dir, char* path);
void CreateEntry (CFileInfo* dir, const char* name);
Bit32u nextEntry;
CFileInfo* dirBase;
CFileInfo* dirSearch;
char dirPath [CROSS_LEN];
bool dirFirstTime;
TDirSort sortDirType;
CFileInfo* save_dir;
char save_path [CROSS_LEN];
char save_expanded [CROSS_LEN];
};
class localDrive : public DOS_Drive {
public:
localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid);
@ -55,6 +120,7 @@ private:
Bit16u free_clusters;
Bit8u mediaid;
} allocation;
DOS_Drive_Cache dirCache;
};
struct VFILE_Block;