diff --git a/include/dos_system.h b/include/dos_system.h index 631c5cbf..1c3289b3 100644 --- a/include/dos_system.h +++ b/include/dos_system.h @@ -162,6 +162,8 @@ public: void CacheOut (const char* path, bool ignoreLastDir = false); void AddEntry (const char* path, bool checkExist = false); + void AddEntryDirOverlay (const char* path, bool checkExist = false); + void DeleteEntry (const char* path, bool ignoreLastDir = false); void EmptyCache (void); @@ -172,7 +174,7 @@ public: public: CFileInfo(void) { orgname[0] = shortname[0] = 0; - isDir = false; + isOverlayDir = isDir = false; id = MAX_OPENDIRS; nextEntry = shortNr = 0; } @@ -183,6 +185,7 @@ public: }; char orgname [CROSS_LEN]; char shortname [DOS_NAMELENGTH_ASCII]; + bool isOverlayDir; bool isDir; Bit16u id; Bitu nextEntry; @@ -206,7 +209,7 @@ private: CFileInfo* FindDirInfo (const char* path, char* expandedPath); bool RemoveSpaces (char* str); bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id); - void CreateEntry (CFileInfo* dir, const char* name, bool query_directory); + void CreateEntry (CFileInfo* dir, const char* name, bool is_directory); void CopyEntry (CFileInfo* dir, CFileInfo* from); Bit16u GetFreeID (CFileInfo* dir); void Clear (void); diff --git a/src/dos/drive_cache.cpp b/src/dos/drive_cache.cpp index d3c50ce5..e0500d30 100644 --- a/src/dos/drive_cache.cpp +++ b/src/dos/drive_cache.cpp @@ -187,6 +187,7 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) { if (*work) { size_t len = strlen(work); #if defined (WIN32) + //What about OS/2 if((work[len-1] == CROSS_FILESPLIT ) && (len >= 2) && (work[len-2] != ':')) { #else if((len > 1) && (work[len-1] == CROSS_FILESPLIT )) { @@ -228,6 +229,72 @@ void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists) { // LOG_DEBUG("DIR: Error: Failed to add %s",path); } } +void DOS_Drive_Cache::AddEntryDirOverlay(const char* path, bool checkExists) { + // Get Last part... + char file [CROSS_LEN]; + char expand [CROSS_LEN]; + char dironly[CROSS_LEN + 1]; + + //When adding a directory, the directory we want to operate inside in is the above it. (which can go wrong if the directory already exists.) + strcpy(dironly,path); + char* post = strrchr(dironly,CROSS_FILESPLIT); + + if (post) { +#if defined (WIN32) + //OS2 ? + if (post > dironly && *(post - 1) == ':' && (post - dironly) == 2) + post++; //move away from X: as need to end up with x:\ +#else + //Lets hope this is not really used.. (root folder specified as overlay) + if (post == dironly) + post++; //move away from / +#endif + *post = 0; //TODO take care of AddEntryDIR D:\\piet) (so mount d d:\ as base) + *(post + 1) = 0; //As FindDirInfo is skipping over the base directory + } + CFileInfo* dir = FindDirInfo(dironly,expand); + const char* pos = strrchr(path,CROSS_FILESPLIT); + + if (pos) { + strcpy(file,pos + 1); + // Check if directory already exists, then don't add new entry... + if (checkExists) { + Bits index = GetLongName(dir,file); + if (index >= 0) { + //directory already exists, but most likely empty. + dir = dir->fileList[index]; + if (dir->isOverlayDir && dir->fileList.empty()) { + //maybe care about searches ? but this function should only run on cache inits/refreshes. + //add dot entries + CreateEntry(dir,".",true); + CreateEntry(dir,"..",true); + } + return; + } + } + + CreateEntry(dir,file,true); + + + Bits index = GetLongName(dir,file); + if (index>=0) { + Bit32u i; + // Check if there are any open search dir that are affected by this... + if (dir) for (i=0; inextEntry)) + dirSearch[i]->nextEntry++; + } + + dir = dir->fileList[index]; + dir->isOverlayDir = true; + CreateEntry(dir,".",true); + CreateEntry(dir,"..",true); + } + // LOG_DEBUG("DIR: Added Entry %s",path); + } else { + // LOG_DEBUG("DIR: Error: Failed to add %s",path); + } +} void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir) { CacheOut(path,ignoreLastDir); @@ -278,7 +345,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) { } bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir) { - return (curDir->fileList.size()>0); + return (curDir->isOverlayDir || curDir->fileList.size()>0); } @@ -676,9 +743,9 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) { if (dirSearch[id]) { // open dir dir_information* dirp = open_directory(expandcopy); - if (dirp) { + if (dirp || dir->isOverlayDir) { // Reset it.. - close_directory(dirp); + if (dirp) close_directory(dirp); strcpy(dirPath,expandcopy); return true; }