1
0
Fork 0

Add patch 3011706 by bredbored: remove double weirdness with free and dirsearch being 0. More sensible clearing of the directory cache. Fixes skynet crashes related to corrupted drive cache.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3630
This commit is contained in:
Peter Veenstra 2010-08-07 18:25:24 +00:00
parent 8f4d5fce90
commit 0438430b24
2 changed files with 58 additions and 16 deletions

View file

@ -156,8 +156,9 @@ public:
public:
CFileInfo(void) {
orgname[0] = shortname[0] = 0;
nextEntry = shortNr = 0;
isDir = false;
id = MAX_OPENDIRS;
nextEntry = shortNr = 0;
}
~CFileInfo(void) {
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
@ -167,6 +168,7 @@ public:
char orgname [CROSS_LEN];
char shortname [DOS_NAMELENGTH_ASCII];
bool isDir;
Bit16u id;
Bitu nextEntry;
Bitu shortNr;
// contents
@ -175,6 +177,8 @@ public:
};
private:
void ClearFileInfo(CFileInfo *dir);
void DeleteFileInfo(CFileInfo *dir);
bool RemoveTrailingDot (char* shortname);
Bits GetLongName (CFileInfo* info, char* shortname);
@ -203,7 +207,6 @@ private:
Bit16u srchNr;
CFileInfo* dirSearch [MAX_OPENDIRS];
char dirSearchName [MAX_OPENDIRS];
bool free [MAX_OPENDIRS];
CFileInfo* dirFindFirst [MAX_OPENDIRS];
Bit16u nextFreeFindFirst;

View file

@ -67,7 +67,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) {
srchNr = 0;
label[0] = 0;
nextFreeFindFirst = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; dirFindFirst[i] = 0; };
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; dirFindFirst[i] = 0; };
SetDirSort(DIRALPHABETICAL);
updatelabel = true;
}
@ -78,7 +78,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) {
srchNr = 0;
label[0] = 0;
nextFreeFindFirst = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; dirFindFirst[i] = 0; };
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; dirFindFirst[i] = 0; };
SetDirSort(DIRALPHABETICAL);
SetBaseDir(path);
updatelabel = true;
@ -86,11 +86,11 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) {
DOS_Drive_Cache::~DOS_Drive_Cache(void) {
Clear();
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { delete dirFindFirst[i]; dirFindFirst[i]=0; };
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { DeleteFileInfo(dirFindFirst[i]); dirFindFirst[i]=0; };
}
void DOS_Drive_Cache::Clear(void) {
delete dirBase; dirBase = 0;
DeleteFileInfo(dirBase); dirBase = 0;
nextFreeFindFirst = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) dirSearch[i] = 0;
}
@ -101,7 +101,6 @@ void DOS_Drive_Cache::EmptyCache(void) {
dirBase = new CFileInfo;
save_dir = 0;
srchNr = 0;
for (Bit32u i=0; i<MAX_OPENDIRS; i++) free[i] = true;
SetBaseDir(basePath);
}
@ -117,8 +116,16 @@ void DOS_Drive_Cache::SetLabel(const char* vname,bool cdrom,bool allowupdate) {
}
Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) {
for (Bit16u i=0; i<MAX_OPENDIRS; i++) if (free[i] || (dir==dirSearch[i])) return i;
if (dir->id != MAX_OPENDIRS)
return dir->id;
for (Bit16u i=0; i<MAX_OPENDIRS; i++) {
if (!dirSearch[i]) {
dir->id = i;
return i;
}
}
LOG(LOG_FILES,LOG_NORMAL)("DIRCACHE: Too many open directories!");
dir->id=0;
return 0;
}
@ -262,7 +269,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) {
// delete file objects...
for(Bit32u i=0; i<dir->fileList.size(); i++) {
if (dirSearch[srchNr]==dir->fileList[i]) dirSearch[srchNr] = 0;
delete dir->fileList[i]; dir->fileList[i] = 0;
DeleteFileInfo(dir->fileList[i]); dir->fileList[i] = 0;
}
// clear lists
dir->fileList.clear();
@ -524,7 +531,10 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
strcpy(buffer,dirPath);
ReadDir(id,result);
strcpy(dirPath,buffer);
free[id] = true;
if (dirSearch[id]) {
dirSearch[id]->id = MAX_OPENDIRS;
dirSearch[id] = 0;
}
};
};
@ -554,7 +564,10 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
strcpy(buffer,dirPath);
ReadDir(id,result);
strcpy(dirPath,buffer);
free[id] = true;
if (dirSearch[id]) {
dirSearch[id]->id = MAX_OPENDIRS;
dirSearch[id] = 0;
}
};
}
};
@ -598,9 +611,12 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) {
// Reset it..
close_directory(dirp);
strcpy(dirPath,expandcopy);
free[id] = false;
return true;
}
if (dirSearch[id]) {
dirSearch[id]->id = MAX_OPENDIRS;
dirSearch[id] = 0;
}
};
return false;
}
@ -659,7 +675,10 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) {
// Try to open directory
dir_information* dirp = open_directory(dirPath);
if (!dirp) {
free[id] = true;
if (dirSearch[id]) {
dirSearch[id]->id = MAX_OPENDIRS;
dirSearch[id] = 0;
}
return false;
}
// Read complete directory
@ -686,7 +705,10 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) {
};*/
};
if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true;
free[id] = true;
if (dirSearch[id]) {
dirSearch[id]->id = MAX_OPENDIRS;
dirSearch[id] = 0;
}
return false;
}
@ -730,7 +752,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) {
this->nextFreeFindFirst = 1; //the next free one after this search
for(Bitu n=0; n<MAX_OPENDIRS;n++) {
// Clear and reuse slot
delete dirFindFirst[n];
DeleteFileInfo(dirFindFirst[n]);
dirFindFirst[n]=0;
}
@ -765,8 +787,25 @@ bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result) {
}
if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) {
// free slot
delete dirFindFirst[id]; dirFindFirst[id] = 0;
DeleteFileInfo(dirFindFirst[id]); dirFindFirst[id] = 0;
return false;
}
return true;
}
void DOS_Drive_Cache::ClearFileInfo(CFileInfo *dir) {
for(Bit32u i=0; i<dir->fileList.size(); i++) {
if (CFileInfo *info = dir->fileList[i])
ClearFileInfo(info);
}
if (dir->id != MAX_OPENDIRS) {
dirSearch[dir->id] = 0;
dir->id = MAX_OPENDIRS;
}
}
void DOS_Drive_Cache::DeleteFileInfo(CFileInfo *dir) {
if (dir)
ClearFileInfo(dir);
delete dir;
}