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:
parent
8f4d5fce90
commit
0438430b24
2 changed files with 58 additions and 16 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue