diff --git a/include/dos_system.h b/include/dos_system.h index e530cded..6a3fe97e 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -141,8 +141,8 @@ public: char* GetExpandName (const char* path); bool GetShortName (const char* fullname, char* shortname); - bool FindFirst (char* path, Bitu& id); - bool FindNext (Bitu id, char* &result); + bool FindFirst (char* path, Bit16u& id); + bool FindNext (Bit16u id, char* &result); void CacheOut (const char* path, bool ignoreLastDir = false); void AddEntry (const char* path, bool checkExist = false); @@ -205,7 +205,7 @@ private: char dirSearchName [MAX_OPENDIRS]; bool free [MAX_OPENDIRS]; CFileInfo* dirFindFirst [MAX_OPENDIRS]; - Bitu nextFreeFindFirst; + Bit16u nextFreeFindFirst; char label [CROSS_LEN]; bool updatelabel; diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index 75f2a2b2..d6800564 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -705,16 +705,24 @@ bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr) } // FindFirst / FindNext -bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { +bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) { Bit16u dirID; - Bitu dirFindFirstID = this->nextFreeFindFirst; - // Cache directory in if (!OpenDir(path,dirID)) return false; - this->nextFreeFindFirst++; //increase it for the next search + //Find a free slot. + //If the next one isn't free, move on to the next, if none is free => reset and assume the worst + Bit16u local_findcounter = 0; + while ( local_findcounter < MAX_OPENDIRS ) { + if (dirFindFirst[this->nextFreeFindFirst] == 0) break; + if (++this->nextFreeFindFirst >= MAX_OPENDIRS) this->nextFreeFindFirst = 0; //Wrap around + local_findcounter++; + } - if (dirFindFirstID == MAX_OPENDIRS) { + Bit16u dirFindFirstID = this->nextFreeFindFirst++; + if (this->nextFreeFindFirst >= MAX_OPENDIRS) this->nextFreeFindFirst = 0; //Increase and wrap around for the next search. + + if (local_findcounter == MAX_OPENDIRS) { //Here is the reset from above. // no free slot found... LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next: All slots full. Resetting"); // Clear the internal list then. @@ -749,7 +757,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bitu& id) { return true; } -bool DOS_Drive_Cache::FindNext(Bitu id, char* &result) { +bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result) { // out of range ? if ((id>=MAX_OPENDIRS) || !dirFindFirst[id]) { LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : ID out of range: %04X",id); diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index 15dee47f..dc4fc28b 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -188,7 +188,7 @@ bool localDrive::FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst) { char end[2]={CROSS_FILESPLIT,0}; if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end); - Bitu id; + Bit16u id; if (!dirCache.FindFirst(tempDir,id)) { DOS_SetError(DOSERR_PATH_NOT_FOUND); return false; @@ -239,7 +239,7 @@ bool localDrive::FindNext(DOS_DTA & dta) { Bit8u find_attr; dta.GetSearchParams(srch_attr,srch_pattern); - Bitu id = dta.GetDirID(); + Bit16u id = dta.GetDirID(); again: if (!dirCache.FindNext(id,dir_ent)) {