mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-05-09 11:51:09 +08:00

It seems to be an issue with case sensitivity in filenames on Linux and opening files with the LFN code.
2162 lines
80 KiB
Diff
2162 lines
80 KiB
Diff
diff -rupN dosbox_BAK/include/cross.h dosbox/include/cross.h
|
|
--- dosbox_BAK/include/cross.h 2015-08-30 01:01:52.584699234 -0700
|
|
+++ dosbox/include/cross.h 2015-08-30 01:03:17.428698771 -0700
|
|
@@ -103,8 +103,10 @@ typedef struct dir_struct {
|
|
#endif
|
|
|
|
dir_information* open_directory(const char* dirname);
|
|
-bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory);
|
|
-bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory);
|
|
+bool read_directory_first(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory);
|
|
+bool read_directory_next(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory);
|
|
+bool read_directory_first2(dir_information* dirp, char* entry_name, bool& is_directory);
|
|
+bool read_directory_next2(dir_information* dirp, char* entry_name, bool& is_directory);
|
|
void close_directory(dir_information* dirp);
|
|
|
|
#endif
|
|
diff -rupN dosbox_BAK/include/dosbox.h dosbox/include/dosbox.h
|
|
--- dosbox_BAK/include/dosbox.h 2015-08-30 01:01:52.608699235 -0700
|
|
+++ dosbox/include/dosbox.h 2015-08-30 01:03:17.432699087 -0700
|
|
@@ -69,7 +69,7 @@ typedef Bitu (LoopHandler)(void);
|
|
extern Config* control;
|
|
extern SVGACards svgaCard;
|
|
extern MachineType machine;
|
|
-extern bool SDLNetInited;
|
|
+extern bool SDLNetInited, uselfn;
|
|
extern bool mono_cga;
|
|
extern bool mainline_compatible_mapping;
|
|
extern bool mainline_compatible_bios_mapping;
|
|
diff -rupN dosbox_BAK/include/dos_inc.h dosbox/include/dos_inc.h
|
|
--- dosbox_BAK/include/dos_inc.h 2015-08-30 01:01:52.604699235 -0700
|
|
+++ dosbox/include/dos_inc.h 2015-08-30 01:03:17.428698771 -0700
|
|
@@ -21,6 +21,7 @@
|
|
#define DOSBOX_DOS_INC_H
|
|
|
|
#include <stddef.h>
|
|
+#define CTBUF 127
|
|
|
|
#ifndef DOSBOX_DOS_SYSTEM_H
|
|
#include "dos_system.h"
|
|
@@ -36,7 +37,7 @@
|
|
#endif
|
|
struct CommandTail{
|
|
Bit8u count; /* number of bytes returned */
|
|
- char buffer[127]; /* the buffer itself */
|
|
+ char buffer[CTBUF]; /* the buffer itself */
|
|
} GCC_ATTRIBUTE(packed);
|
|
#ifdef _MSC_VER
|
|
#pragma pack ()
|
|
@@ -175,6 +176,7 @@ bool DOS_OpenFile(char const * name,Bit8
|
|
bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status);
|
|
bool DOS_CreateFile(char const * name,Bit16u attribute,Bit16u * entry);
|
|
bool DOS_UnlinkFile(char const * const name);
|
|
+bool DOS_GetSFNPath(char const * const path, char *SFNpath, bool LFN);
|
|
bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false);
|
|
bool DOS_FindNext(void);
|
|
bool DOS_Canonicalize(char const * const name,char * const big);
|
|
@@ -187,7 +189,7 @@ bool DOS_MakeName(char const * const nam
|
|
Bit8u DOS_GetDefaultDrive(void);
|
|
void DOS_SetDefaultDrive(Bit8u drive);
|
|
bool DOS_SetDrive(Bit8u drive);
|
|
-bool DOS_GetCurrentDir(Bit8u drive,char * const buffer);
|
|
+bool DOS_GetCurrentDir(Bit8u drive,char * const buffer, bool LFN);
|
|
bool DOS_ChangeDir(char const * const dir);
|
|
bool DOS_MakeDir(char const * const dir);
|
|
bool DOS_RemoveDir(char const * const dir);
|
|
@@ -522,12 +524,14 @@ class DOS_DTA:public MemStruct{
|
|
public:
|
|
DOS_DTA(RealPt addr) { SetPt(addr); }
|
|
|
|
+ int GetFindData(char * finddata);
|
|
+
|
|
void SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * _pattern);
|
|
- void SetResult(const char * _name,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr);
|
|
+ void SetResult(const char * _name,const char * _lname,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr);
|
|
|
|
Bit8u GetSearchDrive(void);
|
|
void GetSearchParams(Bit8u & _sattr,char * _spattern);
|
|
- void GetResult(char * _name,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr);
|
|
+ void GetResult(char * _name,char * _lname,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr);
|
|
|
|
void SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); };
|
|
void SetDirIDCluster(Bit16u entry) { sSave(sDTA,dirCluster,entry); };
|
|
@@ -539,8 +543,8 @@ private:
|
|
#endif
|
|
struct sDTA {
|
|
Bit8u sdrive; /* The Drive the search is taking place */
|
|
- Bit8u sname[8]; /* The Search pattern for the filename */
|
|
- Bit8u sext[3]; /* The Search pattern for the extenstion */
|
|
+ Bit8u spname[8]; /* The Search pattern for the filename */
|
|
+ Bit8u spext[3]; /* The Search pattern for the extension */
|
|
Bit8u sattr; /* The Attributes that need to be found */
|
|
Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */
|
|
Bit16u dirCluster; /* custom (drive_fat only): cluster number for multiple searches at the same time */
|
|
diff -rupN dosbox_BAK/include/dos_system.h dosbox/include/dos_system.h
|
|
--- dosbox_BAK/include/dos_system.h 2015-08-30 01:01:52.580699236 -0700
|
|
+++ dosbox/include/dos_system.h 2015-08-30 01:03:17.432699087 -0700
|
|
@@ -36,9 +36,10 @@
|
|
|
|
#define DOS_NAMELENGTH 12
|
|
#define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1)
|
|
+#define LFN_NAMELENGTH 255
|
|
#define DOS_FCBNAME 15
|
|
#define DOS_DIRDEPTH 8
|
|
-#define DOS_PATHLENGTH 80
|
|
+#define DOS_PATHLENGTH 255
|
|
#define DOS_TEMPSIZE 1024
|
|
|
|
enum {
|
|
@@ -147,14 +148,14 @@ public:
|
|
void SetBaseDir (const char* path, DOS_Drive *drive);
|
|
void SetDirSort (TDirSort sort) { sortDirType = sort; };
|
|
bool OpenDir (const char* path, Bit16u& id);
|
|
- bool ReadDir (Bit16u id, char* &result);
|
|
+ bool ReadDir (Bit16u id, char* &result, char * &lresult);
|
|
|
|
void ExpandName (char* path);
|
|
char* GetExpandName (const char* path);
|
|
bool GetShortName (const char* fullname, char* shortname);
|
|
|
|
bool FindFirst (char* path, Bit16u& id);
|
|
- bool FindNext (Bit16u id, char* &result);
|
|
+ bool FindNext (Bit16u id, char* &result, char* &lresult);
|
|
|
|
void CacheOut (const char* path, bool ignoreLastDir = false);
|
|
void AddEntry (const char* path, bool checkExist = false);
|
|
@@ -198,12 +199,12 @@ private:
|
|
void CreateShortName (CFileInfo* dir, CFileInfo* info);
|
|
Bitu CreateShortNameID (CFileInfo* dir, const char* name);
|
|
int CompareShortname (const char* compareName, const char* shortName);
|
|
- bool SetResult (CFileInfo* dir, char * &result, Bitu entryNr);
|
|
+ bool SetResult (CFileInfo* dir, char * &result, char * &lresult, Bitu entryNr);
|
|
bool IsCachedIn (CFileInfo* dir);
|
|
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, const char* sname, bool query_directory);
|
|
void CopyEntry (CFileInfo* dir, CFileInfo* from);
|
|
Bit16u GetFreeID (CFileInfo* dir);
|
|
void Clear (void);
|
|
diff -rupN dosbox_BAK/include/support.h dosbox/include/support.h
|
|
--- dosbox_BAK/include/support.h 2015-08-30 01:01:52.524699247 -0700
|
|
+++ dosbox/include/support.h 2015-08-30 01:03:17.432699087 -0700
|
|
@@ -45,6 +45,8 @@ char *trim(char * str);
|
|
char * upcase(char * str);
|
|
char * lowcase(char * str);
|
|
|
|
+char * StripArg(char *&cmd);
|
|
+
|
|
bool ScanCMDBool(char * cmd,char const * const check);
|
|
char * ScanCMDRemain(char * cmd);
|
|
char * StripWord(char *&cmd);
|
|
diff -rupN dosbox_BAK/src/dos/dos_classes.cpp dosbox/src/dos/dos_classes.cpp
|
|
--- dosbox_BAK/src/dos/dos_classes.cpp 2015-08-30 01:02:00.692699451 -0700
|
|
+++ dosbox/src/dos/dos_classes.cpp 2015-08-30 01:03:17.432699087 -0700
|
|
@@ -24,6 +24,19 @@
|
|
#include "dos_inc.h"
|
|
#include "support.h"
|
|
|
|
+char sname[LFN_NAMELENGTH+1];
|
|
+struct finddata {
|
|
+ Bit8u attr;
|
|
+ Bit8u fres1[19];
|
|
+ Bit32u mtime;
|
|
+ Bit32u mdate;
|
|
+ Bit32u hsize;
|
|
+ Bit32u size;
|
|
+ Bit8u fres2[8];
|
|
+ char lname[260];
|
|
+ char sname[14];
|
|
+} fd;
|
|
+
|
|
|
|
void DOS_ParamBlock::Clear(void) {
|
|
memset(&exec,0,sizeof(exec));
|
|
@@ -284,7 +297,7 @@ void DOS_PSP::RestoreVectors(void) {
|
|
|
|
void DOS_PSP::SetCommandTail(RealPt src) {
|
|
if (src) { // valid source
|
|
- MEM_BlockCopy(pt+offsetof(sPSP,cmdtail),Real2Phys(src),128);
|
|
+ MEM_BlockCopy(pt+offsetof(sPSP,cmdtail),Real2Phys(src),CTBUF+1);
|
|
} else { // empty
|
|
sSave(sPSP,cmdtail.count,0x00);
|
|
mem_writeb(pt+offsetof(sPSP,cmdtail.buffer),0x0d);
|
|
@@ -323,51 +336,61 @@ bool DOS_PSP::SetNumFiles(Bit16u fileNum
|
|
void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) {
|
|
sSave(sDTA,sdrive,_sdrive);
|
|
sSave(sDTA,sattr,_sattr);
|
|
- /* Fill with spaces */
|
|
- Bitu i;
|
|
- for (i=0;i<11;i++) mem_writeb(pt+offsetof(sDTA,sname)+i,' ');
|
|
- char * find_ext;
|
|
- find_ext=strchr(pattern,'.');
|
|
- if (find_ext) {
|
|
- Bitu size=(Bitu)(find_ext-pattern);
|
|
- if (size>8) size=8;
|
|
- MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,size);
|
|
- find_ext++;
|
|
- MEM_BlockWrite(pt+offsetof(sDTA,sext),find_ext,(strlen(find_ext)>3) ? 3 : (Bitu)strlen(find_ext));
|
|
- } else {
|
|
- MEM_BlockWrite(pt+offsetof(sDTA,sname),pattern,(strlen(pattern) > 8) ? 8 : (Bitu)strlen(pattern));
|
|
+ /* Fill with char 0 */
|
|
+ int i;
|
|
+ for (i=0;i<LFN_NAMELENGTH;i++) {
|
|
+ if (pattern[i]==0) break;
|
|
+ sname[i]=pattern[i];
|
|
}
|
|
+ while (i<=LFN_NAMELENGTH) sname[i++]=0;
|
|
}
|
|
|
|
-void DOS_DTA::SetResult(const char * _name,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr) {
|
|
+void DOS_DTA::SetResult(const char * _name, const char * _lname, Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr) {
|
|
MEM_BlockWrite(pt+offsetof(sDTA,name),(void *)_name,DOS_NAMELENGTH_ASCII);
|
|
sSave(sDTA,size,_size);
|
|
sSave(sDTA,date,_date);
|
|
sSave(sDTA,time,_time);
|
|
sSave(sDTA,attr,_attr);
|
|
+ fd.hsize=0;
|
|
+ fd.size=_size;
|
|
+ fd.mdate=_date;
|
|
+ fd.mtime=_time;
|
|
+ fd.attr=_attr;
|
|
+ strcpy(fd.lname,_lname);
|
|
+ strcpy(fd.sname,_name);
|
|
+ if (!strcmp(fd.lname,fd.sname)) fd.sname[0]=0;
|
|
}
|
|
|
|
|
|
-void DOS_DTA::GetResult(char * _name,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr) {
|
|
+void DOS_DTA::GetResult(char * _name, char * _lname,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr) {
|
|
MEM_BlockRead(pt+offsetof(sDTA,name),_name,DOS_NAMELENGTH_ASCII);
|
|
+ strcpy(_lname,fd.lname);
|
|
_size=sGet(sDTA,size);
|
|
_date=(Bit16u)sGet(sDTA,date);
|
|
_time=(Bit16u)sGet(sDTA,time);
|
|
_attr=(Bit8u)sGet(sDTA,attr);
|
|
}
|
|
|
|
+int DOS_DTA::GetFindData(char * fdstr) {
|
|
+ sprintf(fdstr,"%-1s%-19s%-4s%-4s%-4s%-4s%-8s%-260s%-14s",&fd.attr,&fd.fres1,&fd.mtime,&fd.mdate,&fd.hsize,&fd.size,&fd.fres2,&fd.lname,&fd.sname);
|
|
+ //for (int i=0;i<4;i++) fdstr[28+i]=0;
|
|
+ fdstr[32]=fd.size%256;
|
|
+ fdstr[33]=(char)((fd.size%65536)/256);
|
|
+ fdstr[34]=(char)((fd.size%16777216)/65536);
|
|
+ fdstr[35]=(char)(fd.size/16777216);
|
|
+ fdstr[44+strlen(fd.lname)]=0;
|
|
+ fdstr[304+strlen(fd.sname)]=0;
|
|
+ return (sizeof(fd));
|
|
+}
|
|
+
|
|
Bit8u DOS_DTA::GetSearchDrive(void) {
|
|
return (Bit8u)sGet(sDTA,sdrive);
|
|
}
|
|
|
|
void DOS_DTA::GetSearchParams(Bit8u & attr,char * pattern) {
|
|
attr=(Bit8u)sGet(sDTA,sattr);
|
|
- char temp[11];
|
|
- MEM_BlockRead(pt+offsetof(sDTA,sname),temp,11);
|
|
- memcpy(pattern,temp,8);
|
|
- pattern[8]='.';
|
|
- memcpy(&pattern[9],&temp[8],3);
|
|
- pattern[12]=0;
|
|
+ memcpy(pattern,sname,LFN_NAMELENGTH);
|
|
+ pattern[LFN_NAMELENGTH]=0;
|
|
|
|
}
|
|
|
|
diff -rupN dosbox_BAK/src/dos/dos.cpp dosbox/src/dos/dos.cpp
|
|
--- dosbox_BAK/src/dos/dos.cpp 2015-08-30 01:02:00.744699454 -0700
|
|
+++ dosbox/src/dos/dos.cpp 2015-08-30 01:03:17.432699087 -0700
|
|
@@ -336,6 +336,7 @@ static Bitu DOS_21Handler(void) {
|
|
|
|
char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII];
|
|
char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII];
|
|
+ char *p;
|
|
|
|
static Bitu time_start = 0; //For emulating temporary time changes.
|
|
|
|
@@ -1110,7 +1111,7 @@ static Bitu DOS_21Handler(void) {
|
|
}
|
|
break;
|
|
case 0x47: /* CWD Get current directory */
|
|
- if (DOS_GetCurrentDir(reg_dl,name1)) {
|
|
+ if (DOS_GetCurrentDir(reg_dl,name1,false)) {
|
|
MEM_BlockWrite(SegPhys(ds)+reg_si,name1,(Bitu)(strlen(name1)+1));
|
|
reg_ax=0x0100;
|
|
CALLBACK_SCF(false);
|
|
@@ -1548,9 +1549,291 @@ static Bitu DOS_21Handler(void) {
|
|
break;
|
|
|
|
case 0x71: /* Unknown probably 4dos detection */
|
|
- reg_ax=0x7100;
|
|
- CALLBACK_SCF(true); //Check this! What needs this ? See default case
|
|
- LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al);
|
|
+ LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al);
|
|
+ if (!uselfn) {
|
|
+ reg_ax=0x7100;
|
|
+ CALLBACK_SCF(true); //Check this! What needs this ? See default case
|
|
+ break;
|
|
+ }
|
|
+ switch(reg_al) {
|
|
+ case 0x39: /* LFN MKDIR */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ if (DOS_MakeDir(name1)) {
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0x3a: /* LFN RMDIR */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ if (DOS_RemoveDir(name1)) {
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ LOG(LOG_MISC,LOG_NORMAL)("Remove dir failed on %s with error %X",name1,dos.errorcode);
|
|
+ }
|
|
+ break;
|
|
+ case 0x3b: /* LFN CHDIR */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ if (DOS_ChangeDir(name1)) {
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0x41: /* LFN UNLINK */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ if (DOS_UnlinkFile(name1)) {
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0x43: /* LFN ATTR */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ switch (reg_bl) {
|
|
+ case 0x00: /* Get */
|
|
+ {
|
|
+ Bit16u attr_val=reg_cx;
|
|
+ if (DOS_GetFileAttr(name1,&attr_val)) {
|
|
+ reg_cx=attr_val;
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ CALLBACK_SCF(true);
|
|
+ reg_ax=dos.errorcode;
|
|
+ }
|
|
+ break;
|
|
+ };
|
|
+ case 0x01: /* Set */
|
|
+ if (DOS_SetFileAttr(name1,reg_cx)) {
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ CALLBACK_SCF(true);
|
|
+ reg_ax=dos.errorcode;
|
|
+ }
|
|
+ break;
|
|
+ case 0x02:
|
|
+ case 0x03:
|
|
+ case 0x04:
|
|
+ case 0x05:
|
|
+ case 0x06:
|
|
+ case 0x07:
|
|
+ case 0x08:
|
|
+ LOG(LOG_MISC,LOG_ERROR)("DOS:7143:Unimplemented subfunction %2X",reg_bl);
|
|
+ reg_ax=1;
|
|
+ CALLBACK_SCF(true);
|
|
+ break;
|
|
+ default:
|
|
+ E_Exit("DOS:Illegal LFN Attr call %2X",reg_bl);
|
|
+ }
|
|
+ break;
|
|
+ case 0x47: /* LFN PWD */
|
|
+ if (DOS_GetCurrentDir(reg_dl,name1,true)) {
|
|
+ MEM_BlockWrite(SegPhys(ds)+reg_si,name1,(Bitu)(strlen(name1)+1));
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0x4e: /* LFN FindFirst */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ DOS_GetSFNPath(name1,name2,false);
|
|
+ if (DOS_FindFirst(name2,reg_cx,false)) {
|
|
+ DOS_DTA dta(dos.dta());
|
|
+ char finddata[CROSS_LEN];
|
|
+ int i=dta.GetFindData(finddata);
|
|
+ MEM_BlockWrite(SegPhys(es)+reg_di,finddata,i+1);
|
|
+ CALLBACK_SCF(false);
|
|
+ reg_ax=1; // todo: return filefind handle
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ };
|
|
+ break;
|
|
+ case 0x4f: /* LFN FindNext */
|
|
+ if (DOS_FindNext()) {
|
|
+ DOS_DTA dta(dos.dta());
|
|
+ char finddata[CROSS_LEN];
|
|
+ int i=dta.GetFindData(finddata);
|
|
+ MEM_BlockWrite(SegPhys(es)+reg_di,finddata,i+1);
|
|
+ CALLBACK_SCF(false);
|
|
+ reg_ax=0x4f05;
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ };
|
|
+ break;
|
|
+ case 0x56: /* LFN RENAME */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ MEM_StrCopy(SegPhys(es)+reg_di,name2+1,DOSNAMEBUF);
|
|
+ *name2='\"';
|
|
+ p=name2+strlen(name2);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ if (DOS_Rename(name1,name2)) {
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0x60: /* LFN GetName */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF);
|
|
+ if (DOS_Canonicalize(name1,name2)) {
|
|
+ switch(reg_cl) {
|
|
+ case 0: // Canonoical path name
|
|
+ strcpy(name1,name2);
|
|
+ break;
|
|
+ case 1: /* SFN path name */
|
|
+ DOS_GetSFNPath(name2,name1,false);
|
|
+ break;
|
|
+ case 2: /* LFN path name */
|
|
+ DOS_GetSFNPath(name2,name1,true);
|
|
+ break;
|
|
+ default:
|
|
+ E_Exit("DOS:Illegal LFN GetName call %2X",reg_cl);
|
|
+ }
|
|
+ MEM_BlockWrite(SegPhys(es)+reg_di,name1,(Bitu)(strlen(name1)+1));
|
|
+ reg_ax=5;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0x6c: /* LFN CREATE */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_si,name1+1,DOSNAMEBUF);
|
|
+ *name1='\"';
|
|
+ p=name1+strlen(name1);
|
|
+ while (*p==' '||*p==0) p--;
|
|
+ *(p+1)='\"';
|
|
+ *(p+2)=0;
|
|
+ if (DOS_OpenFileExtended(name1,reg_bx,reg_cx,reg_dx,®_ax,®_cx)) {
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0xa0: /* LFN VolInfo */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
|
+ if (DOS_Canonicalize(name1,name2)) {
|
|
+ if (reg_cx > 3)
|
|
+ MEM_BlockWrite(SegPhys(es)+reg_di,"FAT",4);
|
|
+ reg_ax=0;
|
|
+ reg_bx=0x4006;
|
|
+ reg_cx=0xff;
|
|
+ reg_dx=0x104;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=dos.errorcode;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0xa1: /* LFN FileClose */
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ break;
|
|
+ case 0xa7: /* LFN TimeConv */
|
|
+ switch (reg_bl) {
|
|
+ case 0x00:
|
|
+ reg_cl=mem_readb(SegPhys(ds)+reg_si); //not yet a proper implementation,
|
|
+ reg_ch=mem_readb(SegPhys(ds)+reg_si+1); //but DIR from MS-DOS 7 COMMAND.COM
|
|
+ reg_dl=mem_readb(SegPhys(ds)+reg_si+4); //should show date/time correctly now
|
|
+ reg_dh=mem_readb(SegPhys(ds)+reg_si+5);
|
|
+ reg_bh=0;
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ break;
|
|
+ case 0x01:
|
|
+ reg_ax=1;
|
|
+ CALLBACK_SCF(true); // not implemented yet
|
|
+ break;
|
|
+ default:
|
|
+ E_Exit("DOS:Illegal LFN TimeConv call %2X",reg_bl);
|
|
+ }
|
|
+ break;
|
|
+ case 0xa8: /* LFN GenSFN */
|
|
+ if (reg_dh == 0 || reg_dh == 1) {
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF);
|
|
+ int i,j=0;
|
|
+ char c[13],*s=strrchr(name1,'.');
|
|
+ for (i=0;i<8;j++) {
|
|
+ if (name1[j] == 0 || s-name1 <= j) break;
|
|
+ if (name1[j] == '.') continue;
|
|
+ sprintf(c,"%s%c",c,toupper(name1[j]));
|
|
+ i++;
|
|
+ }
|
|
+ if (s != NULL) {
|
|
+ s++;
|
|
+ if (s != 0 && reg_dh == 1) strcat(c,".");
|
|
+ for (i=0;i<3;i++) {
|
|
+ if (*(s+i) == 0) break;
|
|
+ sprintf(c,"%s%c",c,toupper(*(s+i)));
|
|
+ }
|
|
+ }
|
|
+ MEM_BlockWrite(SegPhys(es)+reg_di,c,strlen(c)+1);
|
|
+ reg_ax=0;
|
|
+ CALLBACK_SCF(false);
|
|
+ } else {
|
|
+ reg_ax=1;
|
|
+ CALLBACK_SCF(true);
|
|
+ }
|
|
+ break;
|
|
+ case 0xaa: /* LFN SUBST */
|
|
+ default:
|
|
+ reg_ax=0x7100;
|
|
+ CALLBACK_SCF(true); //Check this! What needs this ? See default case
|
|
+ }
|
|
break;
|
|
|
|
case 0xE0:
|
|
@@ -1906,7 +2189,6 @@ public:
|
|
|
|
keep_private_area_on_boot = section->Get_bool("keep private area on boot");
|
|
|
|
- dos.version.major=5;
|
|
dos.version.minor=0;
|
|
|
|
std::string ver = section->Get_string("ver");
|
|
diff -rupN dosbox_BAK/src/dos/dos_files.cpp dosbox/src/dos/dos_files.cpp
|
|
--- dosbox_BAK/src/dos/dos_files.cpp 2015-08-30 01:02:00.524699448 -0700
|
|
+++ dosbox/src/dos/dos_files.cpp 2015-08-30 01:03:17.432699087 -0700
|
|
@@ -66,9 +66,13 @@ bool DOS_MakeName(char const * const nam
|
|
const char * name_int = name;
|
|
char tempdir[DOS_PATHLENGTH];
|
|
char upname[DOS_PATHLENGTH];
|
|
- Bitu r,w;
|
|
+ Bitu r,w, q=0;
|
|
*drive = DOS_GetDefaultDrive();
|
|
/* First get the drive */
|
|
+ while (name_int[0]=='"') {
|
|
+ q++;
|
|
+ name_int++;
|
|
+ }
|
|
if (name_int[1]==':') {
|
|
*drive=(name_int[0] | 0x20)-'a';
|
|
name_int+=2;
|
|
@@ -80,15 +84,19 @@ bool DOS_MakeName(char const * const nam
|
|
r=0;w=0;
|
|
while (name_int[r]!=0 && (r<DOS_PATHLENGTH)) {
|
|
Bit8u c=name_int[r++];
|
|
- if ((c>='a') && (c<='z')) {upname[w++]=c-32;continue;}
|
|
+ if ((c>='a') && (c<='z')) {upname[w++]=c;continue;}
|
|
if ((c>='A') && (c<='Z')) {upname[w++]=c;continue;}
|
|
if ((c>='0') && (c<='9')) {upname[w++]=c;continue;}
|
|
switch (c) {
|
|
+ case '"':
|
|
+ q++;
|
|
+ continue;
|
|
case '/':
|
|
upname[w++]='\\';
|
|
break;
|
|
- case ' ': /* should be seperator */
|
|
- break;
|
|
+ case ' ':
|
|
+ if (q/2*2 == q) {break;}
|
|
+ else {upname[w++]=c;continue;}
|
|
default:
|
|
upname[w++]=c;
|
|
break;
|
|
@@ -152,6 +160,7 @@ bool DOS_MakeName(char const * const nam
|
|
lastdir=(Bit32u)strlen(fullname);
|
|
|
|
if (lastdir!=0) strcat(fullname,"\\");
|
|
+ /*
|
|
char * ext=strchr(tempdir,'.');
|
|
if (ext) {
|
|
if(strchr(ext+1,'.')) {
|
|
@@ -168,6 +177,7 @@ bool DOS_MakeName(char const * const nam
|
|
ext[4] = 0;
|
|
if((strlen(tempdir) - strlen(ext)) > 8) memmove(tempdir + 8, ext, 5);
|
|
} else tempdir[8]=0;
|
|
+ */
|
|
|
|
if (strlen(fullname)+strlen(tempdir)>=DOS_PATHLENGTH) {
|
|
DOS_SetError(DOSERR_PATH_NOT_FOUND);return false;
|
|
@@ -183,19 +193,85 @@ bool DOS_MakeName(char const * const nam
|
|
return true;
|
|
}
|
|
|
|
-bool DOS_GetCurrentDir(Bit8u drive,char * const buffer) {
|
|
+bool DOS_GetSFNPath(char const * const path,char * SFNPath,bool LFN) {
|
|
+ char dir_current[DOS_PATHLENGTH + 1], pdir[LFN_NAMELENGTH], *p;
|
|
+ Bit8u drive;char fulldir[DOS_PATHLENGTH],LFNPath[CROSS_LEN];
|
|
+ char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH];
|
|
+ int w=0;
|
|
+ DOS_DTA dta(dos.dta());
|
|
+ Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
|
|
+ if (!DOS_MakeName(path,fulldir,&drive)) return false;
|
|
+ sprintf(SFNPath,"%c:\\",drive+'A');
|
|
+ strcpy(LFNPath,SFNPath);
|
|
+ strcpy(dir_current,Drives[drive]->curdir);
|
|
+ Drives[drive]->curdir,"";
|
|
+ p = fulldir;
|
|
+ if (*p==0) return true;
|
|
+ for (char *s = strchr(p,'\\'); s != NULL; s = strchr(p,'\\')) {
|
|
+ *s = 0;
|
|
+ if (SFNPath[strlen(SFNPath)-1]=='\\')
|
|
+ sprintf(pdir,"\"%s%s\"",SFNPath,p);
|
|
+ else
|
|
+ sprintf(pdir,"\"%s\\%s\"",SFNPath,p);
|
|
+ if (!strrchr(p,'*') && !strrchr(p,'?')) {
|
|
+ *s = '\\';
|
|
+ p = s + 1;
|
|
+ if (DOS_FindFirst(pdir,0xffff & DOS_ATTR_DIRECTORY & ~DOS_ATTR_VOLUME,false)) {
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
+ strcat(SFNPath,name);
|
|
+ strcat(LFNPath,lname);
|
|
+ Drives[drive]->curdir,SFNPath+3;
|
|
+ strcat(SFNPath,"\\");
|
|
+ strcat(LFNPath,"\\");
|
|
+ }
|
|
+ else {
|
|
+ return false;}
|
|
+ } else {
|
|
+ strcat(SFNPath,p);
|
|
+ strcat(LFNPath,p);
|
|
+ strcat(SFNPath,"\\");
|
|
+ strcat(LFNPath,"\\");
|
|
+ *s = '\\';
|
|
+ p = s + 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (p != 0) {
|
|
+ sprintf(pdir,"\"%s%s\"",SFNPath,p);
|
|
+ if (!strrchr(p,'*')&&!strrchr(p,'?')&&DOS_FindFirst(pdir,0xffff & ~DOS_ATTR_VOLUME,false)) {
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
+ strcat(SFNPath,name);
|
|
+ strcat(LFNPath,lname);
|
|
+ } else {
|
|
+ strcat(SFNPath,p);
|
|
+ strcat(LFNPath,p);
|
|
+ }
|
|
+ }
|
|
+ Drives[drive]->curdir,dir_current;
|
|
+ if (LFN) strcpy(SFNPath,LFNPath);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool DOS_GetCurrentDir(Bit8u drive,char * const buffer, bool LFN) {
|
|
if (drive==0) drive=DOS_GetDefaultDrive();
|
|
else drive--;
|
|
if ((drive>=DOS_DRIVES) || (!Drives[drive])) {
|
|
DOS_SetError(DOSERR_INVALID_DRIVE);
|
|
return false;
|
|
}
|
|
- strcpy(buffer,Drives[drive]->curdir);
|
|
+ if (LFN && uselfn) {
|
|
+ char cdir[DOS_PATHLENGTH],ldir[DOS_PATHLENGTH];
|
|
+ sprintf(cdir,"%c:\\%s",drive+'A',Drives[drive]->curdir);
|
|
+ DOS_GetSFNPath(cdir,ldir,true);
|
|
+ strcpy(buffer,ldir+3);
|
|
+ } else {
|
|
+ strcpy(buffer,Drives[drive]->curdir);
|
|
+ }
|
|
return true;
|
|
}
|
|
|
|
bool DOS_ChangeDir(char const * const dir) {
|
|
- Bit8u drive;char fulldir[DOS_PATHLENGTH];
|
|
+ Bit8u drive;char fulldir[DOS_PATHLENGTH],sdir[DOS_PATHLENGTH];
|
|
const char * testdir=dir;
|
|
if (strlen(testdir) && testdir[1]==':') testdir+=2;
|
|
size_t len=strlen(testdir);
|
|
@@ -204,13 +280,9 @@ bool DOS_ChangeDir(char const * const di
|
|
return false;
|
|
}
|
|
if (!DOS_MakeName(dir,fulldir,&drive)) return false;
|
|
- if (strlen(fulldir) && testdir[len-1]=='\\') {
|
|
- DOS_SetError(DOSERR_PATH_NOT_FOUND);
|
|
- return false;
|
|
- }
|
|
|
|
- if (Drives[drive]->TestDir(fulldir)) {
|
|
- strcpy(Drives[drive]->curdir,fulldir);
|
|
+ if (Drives[drive]->TestDir(fulldir)&&DOS_GetSFNPath(dir,sdir,false)) {
|
|
+ strcpy(Drives[drive]->curdir,sdir+3);
|
|
return true;
|
|
} else {
|
|
DOS_SetError(DOSERR_PATH_NOT_FOUND);
|
|
@@ -249,9 +321,10 @@ bool DOS_RemoveDir(char const * const di
|
|
return false;
|
|
}
|
|
/* See if it's current directory */
|
|
- char currdir[DOS_PATHLENGTH]= { 0 };
|
|
- DOS_GetCurrentDir(drive + 1 ,currdir);
|
|
- if(strcmp(currdir,fulldir) == 0) {
|
|
+ char currdir[DOS_PATHLENGTH]= { 0 }, lcurrdir[DOS_PATHLENGTH]= { 0 };
|
|
+ DOS_GetCurrentDir(drive + 1 ,currdir, false);
|
|
+ DOS_GetCurrentDir(drive + 1 ,lcurrdir, true);
|
|
+ if(strcasecmp(currdir,fulldir) == 0 || uselfn && strcasecmp(lcurrdir,fulldir) == 0) {
|
|
DOS_SetError(DOSERR_REMOVE_CURRENT_DIRECTORY);
|
|
return false;
|
|
}
|
|
@@ -332,12 +405,13 @@ bool DOS_FindFirst(char * search,Bit16u
|
|
find_last = strrchr(pattern,'.');
|
|
if(find_last) *find_last = 0;
|
|
//TODO use current date and time
|
|
- dta.SetResult(pattern,0,0,0,DOS_ATTR_DEVICE);
|
|
+ dta.SetResult(pattern,pattern,0,0,0,DOS_ATTR_DEVICE);
|
|
LOG(LOG_DOSMISC,LOG_WARN)("finding device %s",pattern);
|
|
return true;
|
|
}
|
|
|
|
- if (Drives[drive]->FindFirst(dir,dta,fcb_findfirst)) return true;
|
|
+ bool r=Drives[drive]->FindFirst(dir, dta, fcb_findfirst);
|
|
+ return r;
|
|
|
|
return false;
|
|
}
|
|
@@ -940,9 +1014,10 @@ static void DTAExtendName(char * const n
|
|
|
|
static void SaveFindResult(DOS_FCB & find_fcb) {
|
|
DOS_DTA find_dta(dos.tables.tempdta);
|
|
- char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;Bit8u drive;
|
|
+ char name[DOS_NAMELENGTH_ASCII],lname[LFN_NAMELENGTH];
|
|
+ Bit32u size;Bit16u date;Bit16u time;Bit8u attr;Bit8u drive;
|
|
char file_name[9];char ext[4];
|
|
- find_dta.GetResult(name,size,date,time,attr);
|
|
+ find_dta.GetResult(name,lname,size,date,time,attr);
|
|
drive=find_fcb.GetDrive()+1;
|
|
Bit8u find_attr = DOS_ATTR_ARCHIVE;
|
|
find_fcb.GetAttr(find_attr); /* Gets search attributes if extended */
|
|
diff -rupN dosbox_BAK/src/dos/dos_misc.cpp dosbox/src/dos/dos_misc.cpp
|
|
--- dosbox_BAK/src/dos/dos_misc.cpp 2015-08-30 01:02:00.536699449 -0700
|
|
+++ dosbox/src/dos/dos_misc.cpp 2015-08-30 01:03:17.436699426 -0700
|
|
@@ -89,6 +89,7 @@ static Bitu INT2A_Handler(void) {
|
|
}
|
|
|
|
static bool DOS_MultiplexFunctions(void) {
|
|
+ char name[256];
|
|
switch (reg_ax) {
|
|
/* ert, 20100711: Locking extensions */
|
|
case 0x1000: /* SHARE.EXE installation check */
|
|
@@ -187,6 +188,22 @@ static bool DOS_MultiplexFunctions(void)
|
|
|
|
}
|
|
return true;
|
|
+ case 0x1300:
|
|
+ case 0x1302:
|
|
+ reg_ax=0;
|
|
+ return true;
|
|
+ case 0x1612:
|
|
+ reg_ax=0;
|
|
+ name[0]=1;
|
|
+ name[1]=0;
|
|
+ MEM_BlockWrite(SegPhys(es)+reg_bx,name,0x20);
|
|
+ return true;
|
|
+ case 0x1613: /* Get SYSTEM.DAT path */
|
|
+ strcpy(name,"C:\\WINDOWS\\SYSTEM.DAT");
|
|
+ MEM_BlockWrite(SegPhys(es)+reg_di,name,(Bitu)(strlen(name)+1));
|
|
+ reg_ax=0;
|
|
+ reg_cx=strlen(name);
|
|
+ return true;
|
|
case 0x1605: /* Windows init broadcast */
|
|
if (enable_a20_on_windows_init) {
|
|
/* This hack exists because Windows 3.1 doesn't seem to enable A20 first during an
|
|
@@ -347,6 +364,12 @@ static bool DOS_MultiplexFunctions(void)
|
|
LOG(LOG_MISC,LOG_DEBUG)("HMA allocation: %u bytes at FFFF:%04x",reg_bx,reg_di);
|
|
DOS_HMA_CLAIMED(reg_bx);
|
|
} return true;
|
|
+ case 0x4a16: /* Open bootlog */
|
|
+ return true;
|
|
+ case 0x4a17: /* Write bootlog */
|
|
+ MEM_StrCopy(SegPhys(ds)+reg_dx,name,255);
|
|
+ LOG(LOG_DOSMISC,LOG_NORMAL)("BOOTLOG: %s\n",name);
|
|
+ return true;
|
|
}
|
|
|
|
return false;
|
|
diff -rupN dosbox_BAK/src/dos/dos_programs.cpp dosbox/src/dos/dos_programs.cpp
|
|
--- dosbox_BAK/src/dos/dos_programs.cpp 2015-08-30 01:02:00.536699448 -0700
|
|
+++ dosbox/src/dos/dos_programs.cpp 2015-08-30 01:03:17.436699426 -0700
|
|
@@ -110,7 +110,8 @@ Bitu ZDRIVE_NUM = 25;
|
|
class MOUNT : public Program {
|
|
public:
|
|
void ListMounts(void) {
|
|
- char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
|
|
+ char name[DOS_NAMELENGTH_ASCII],lname[LFN_NAMELENGTH];
|
|
+ Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
|
|
/* Command uses dta so set it to our internal dta */
|
|
RealPt save_dta = dos.dta();
|
|
dos.dta(dos.tables.tempdta);
|
|
@@ -126,7 +127,7 @@ public:
|
|
char root[4] = {(char)('A'+d),':','\\',0};
|
|
bool ret = DOS_FindFirst(root,DOS_ATTR_VOLUME);
|
|
if (ret) {
|
|
- dta.GetResult(name,size,date,time,attr);
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
DOS_FindNext(); //Mark entry as invalid
|
|
} else name[0] = 0;
|
|
|
|
diff -rupN dosbox_BAK/src/dos/drive_cache.cpp dosbox/src/dos/drive_cache.cpp
|
|
--- dosbox_BAK/src/dos/drive_cache.cpp 2015-08-30 01:02:00.536699449 -0700
|
|
+++ dosbox/src/dos/drive_cache.cpp 2015-08-30 01:03:17.440699731 -0700
|
|
@@ -133,8 +133,8 @@ void DOS_Drive_Cache::SetBaseDir(const c
|
|
strcpy(basePath,baseDir);
|
|
this->drive = drive;
|
|
if (OpenDir(baseDir,id)) {
|
|
- char* result = 0;
|
|
- ReadDir(id,result);
|
|
+ char* result = 0, *lresult = 0;
|
|
+ ReadDir(id,result,lresult);
|
|
};
|
|
// Get Volume Label
|
|
#if defined (WIN32) || defined (OS2)
|
|
@@ -213,7 +213,9 @@ void DOS_Drive_Cache::AddEntry(const cha
|
|
if (GetLongName(dir,file)>=0) return;
|
|
}
|
|
|
|
- CreateEntry(dir,file,false);
|
|
+ char sfile[DOS_NAMELENGTH];
|
|
+ sfile[0]=0;
|
|
+ CreateEntry(dir,file,sfile,false);
|
|
|
|
Bits index = GetLongName(dir,file);
|
|
if (index>=0) {
|
|
@@ -600,9 +602,9 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Ca
|
|
strcpy(work,basePath);
|
|
if (OpenDir(curDir,work,id)) {
|
|
char buffer[CROSS_LEN];
|
|
- char* result = 0;
|
|
+ char *result = 0, *lresult = 0;
|
|
strcpy(buffer,dirPath);
|
|
- ReadDir(id,result);
|
|
+ ReadDir(id,result,lresult);
|
|
strcpy(dirPath,buffer);
|
|
if (dirSearch[id]) {
|
|
dirSearch[id]->id = MAX_OPENDIRS;
|
|
@@ -633,9 +635,9 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Ca
|
|
if (!IsCachedIn(curDir)) {
|
|
if (OpenDir(curDir,expandedPath,id)) {
|
|
char buffer[CROSS_LEN];
|
|
- char* result = 0;
|
|
+ char *result = 0, *lresult = 0;
|
|
strcpy(buffer,dirPath);
|
|
- ReadDir(id,result);
|
|
+ ReadDir(id,result,lresult);
|
|
strcpy(dirPath,buffer);
|
|
if (dirSearch[id]) {
|
|
dirSearch[id]->id = MAX_OPENDIRS;
|
|
@@ -679,7 +681,7 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo*
|
|
// open dir
|
|
if (dirSearch[id]) {
|
|
// open dir
|
|
- void* dirp = drive->opendir(expandcopy);
|
|
+ dir_information* dirp = (dir_information*)drive->opendir(expandcopy); // verify this conversion from void* is valid
|
|
if (dirp) {
|
|
// Reset it..
|
|
drive->closedir(dirp);
|
|
@@ -694,14 +696,15 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo*
|
|
return false;
|
|
}
|
|
|
|
-void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, bool is_directory) {
|
|
+void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name, const char* sname, bool is_directory) {
|
|
CFileInfo* info = new CFileInfo;
|
|
+ strcpy(info->shortname, sname);
|
|
strcpy(info->orgname, name);
|
|
info->shortNr = 0;
|
|
info->isDir = is_directory;
|
|
|
|
// Check for long filenames...
|
|
- CreateShortName(dir, info);
|
|
+ if (sname[0]==0) CreateShortName(dir, info);
|
|
|
|
bool found = false;
|
|
|
|
@@ -740,13 +743,13 @@ void DOS_Drive_Cache::CopyEntry(CFileInf
|
|
dir->fileList.push_back(info);
|
|
}
|
|
|
|
-bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) {
|
|
+bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result, char * &lresult) {
|
|
// shouldnt happen...
|
|
if (id>MAX_OPENDIRS) return false;
|
|
|
|
if (!IsCachedIn(dirSearch[id])) {
|
|
// Try to open directory
|
|
- void* dirp = drive->opendir(dirPath);
|
|
+ dir_information* dirp = (dir_information*)drive->opendir(dirPath); // verify this conversion from void* is valid
|
|
if (!dirp) {
|
|
if (dirSearch[id]) {
|
|
dirSearch[id]->id = MAX_OPENDIRS;
|
|
@@ -755,12 +758,12 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id,
|
|
return false;
|
|
}
|
|
// Read complete directory
|
|
- char dir_name[CROSS_LEN];
|
|
+ char dir_name[CROSS_LEN], dir_sname[DOS_NAMELENGTH+1];
|
|
bool is_directory;
|
|
- if (drive->read_directory_first(dirp, dir_name, is_directory)) {
|
|
- CreateEntry(dirSearch[id], dir_name, is_directory);
|
|
- while (drive->read_directory_next(dirp, dir_name, is_directory)) {
|
|
- CreateEntry(dirSearch[id], dir_name, is_directory);
|
|
+ if (read_directory_first(dirp, dir_name, dir_sname, is_directory)) {
|
|
+ CreateEntry(dirSearch[id], dir_name, dir_sname, is_directory);
|
|
+ while (read_directory_next(dirp, dir_name, dir_sname, is_directory)) {
|
|
+ CreateEntry(dirSearch[id], dir_name, dir_sname, is_directory);
|
|
}
|
|
}
|
|
|
|
@@ -777,7 +780,7 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id,
|
|
LOG_DEBUG(buffer);
|
|
};*/
|
|
};
|
|
- if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true;
|
|
+ if (SetResult(dirSearch[id], result, lresult, dirSearch[id]->nextEntry)) return true;
|
|
if (dirSearch[id]) {
|
|
dirSearch[id]->id = MAX_OPENDIRS;
|
|
dirSearch[id] = 0;
|
|
@@ -785,15 +788,19 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id,
|
|
return false;
|
|
}
|
|
|
|
-bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bitu entryNr)
|
|
+bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, char* &lresult, Bitu entryNr)
|
|
{
|
|
static char res[CROSS_LEN] = { 0 };
|
|
+ static char lres[CROSS_LEN] = { 0 };
|
|
|
|
result = res;
|
|
+ lresult = lres;
|
|
+
|
|
if (entryNr>=dir->fileList.size()) return false;
|
|
CFileInfo* info = dir->fileList[entryNr];
|
|
// copy filename, short version
|
|
strcpy(res,info->shortname);
|
|
+ strcpy(lres,info->orgname);
|
|
// Set to next Entry
|
|
dir->nextEntry = entryNr+1;
|
|
return true;
|
|
@@ -852,13 +859,13 @@ bool DOS_Drive_Cache::FindFirst(char* pa
|
|
return true;
|
|
}
|
|
|
|
-bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result) {
|
|
+bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result, char* &lresult) {
|
|
// out of range ?
|
|
if ((id>=MAX_OPENDIRS) || !dirFindFirst[id]) {
|
|
LOG(LOG_MISC,LOG_ERROR)("DIRCACHE: FindFirst/Next failure : ID out of range: %04X",id);
|
|
return false;
|
|
}
|
|
- if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) {
|
|
+ if (!SetResult(dirFindFirst[id], result, lresult, dirFindFirst[id]->nextEntry)) {
|
|
// free slot
|
|
DeleteFileInfo(dirFindFirst[id]); dirFindFirst[id] = 0;
|
|
return false;
|
|
diff -rupN dosbox_BAK/src/dos/drive_fat.cpp dosbox/src/dos/drive_fat.cpp
|
|
--- dosbox_BAK/src/dos/drive_fat.cpp 2015-08-30 01:01:59.152699411 -0700
|
|
+++ dosbox/src/dos/drive_fat.cpp 2015-08-30 01:03:17.444700004 -0700
|
|
@@ -441,8 +441,9 @@ bool fatDrive::getFileDirEntry(char cons
|
|
if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) break;
|
|
else {
|
|
//Found something. See if it's a directory (findfirst always finds regular files)
|
|
- char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size;Bit8u find_attr;
|
|
- imgDTA->GetResult(find_name,find_size,find_date,find_time,find_attr);
|
|
+ char find_name[DOS_NAMELENGTH_ASCII],lfind_name[LFN_NAMELENGTH];
|
|
+ Bit16u find_date,find_time;Bit32u find_size;Bit8u find_attr;
|
|
+ imgDTA->GetResult(find_name,lfind_name,find_size,find_date,find_time,find_attr);
|
|
if(!(find_attr & DOS_ATTR_DIRECTORY)) break;
|
|
}
|
|
|
|
@@ -482,11 +483,12 @@ bool fatDrive::getDirClustNum(const char
|
|
findDir = strtok(NULL,"\\");
|
|
if(parDir && (findDir == NULL)) break;
|
|
|
|
- char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size;Bit8u find_attr;
|
|
+ char find_name[DOS_NAMELENGTH_ASCII],lfind_name[LFN_NAMELENGTH];
|
|
+ Bit16u find_date,find_time;Bit32u find_size;Bit8u find_attr;
|
|
if(!FindNextInternal(currentClust, *imgDTA, &foundEntry)) {
|
|
return false;
|
|
} else {
|
|
- imgDTA->GetResult(find_name,find_size,find_date,find_time,find_attr);
|
|
+ imgDTA->GetResult(find_name,lfind_name,find_size,find_date,find_time,find_attr);
|
|
if(!(find_attr &DOS_ATTR_DIRECTORY)) return false;
|
|
}
|
|
currentClust = foundEntry.loFirstClust;
|
|
@@ -919,7 +921,7 @@ bool fatDrive::FindFirst(const char *_di
|
|
direntry dummyClust;
|
|
if(fattype==FAT32) return false;
|
|
#if 0
|
|
- Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII];
|
|
+ Bit8u attr;char pattern[CROSS_LEN];
|
|
dta.GetSearchParams(attr,pattern);
|
|
if(attr==DOS_ATTR_VOLUME) {
|
|
if (strcmp(GetLabel(), "") == 0 ) {
|
|
@@ -966,8 +968,9 @@ bool fatDrive::FindNextInternal(Bit32u d
|
|
Bit32u tmpsector;
|
|
Bit8u attrs;
|
|
Bit16u dirPos;
|
|
- char srch_pattern[DOS_NAMELENGTH_ASCII];
|
|
+ char srch_pattern[CROSS_LEN];
|
|
char find_name[DOS_NAMELENGTH_ASCII];
|
|
+ char lfind_name[LFN_NAMELENGTH+1];
|
|
char extension[4];
|
|
|
|
dta.GetSearchParams(attrs, srch_pattern);
|
|
@@ -1005,10 +1008,14 @@ nextfile:
|
|
}
|
|
memset(find_name,0,DOS_NAMELENGTH_ASCII);
|
|
memset(extension,0,4);
|
|
+ memset(lfind_name,0,LFN_NAMELENGTH);
|
|
memcpy(find_name,§buf[entryoffset].entryname[0],8);
|
|
memcpy(extension,§buf[entryoffset].entryname[8],3);
|
|
+ memcpy(lfind_name,§buf[entryoffset].entryname[0],8);
|
|
+ memcpy(lfind_name,§buf[entryoffset].entryname[0],11);
|
|
trimString(&find_name[0]);
|
|
trimString(&extension[0]);
|
|
+ trimString(&lfind_name[0]);
|
|
|
|
//if(!(sectbuf[entryoffset].attrib & DOS_ATTR_DIRECTORY))
|
|
if (extension[0]!=0) {
|
|
@@ -1029,11 +1036,11 @@ nextfile:
|
|
|
|
|
|
/* Compare name to search pattern */
|
|
- if(!WildFileCmp(find_name,srch_pattern)) goto nextfile;
|
|
+ if(!WildFileCmp(find_name,srch_pattern)&&!LWildFileCmp(lfind_name,srch_pattern)) goto nextfile;
|
|
|
|
//dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].crtDate, sectbuf[entryoffset].crtTime, sectbuf[entryoffset].attrib);
|
|
|
|
- dta.SetResult(find_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].modDate, sectbuf[entryoffset].modTime, sectbuf[entryoffset].attrib);
|
|
+ dta.SetResult(find_name, lfind_name, sectbuf[entryoffset].entrysize, sectbuf[entryoffset].modDate, sectbuf[entryoffset].modTime, sectbuf[entryoffset].attrib);
|
|
|
|
memcpy(foundEntry, §buf[entryoffset], sizeof(direntry));
|
|
|
|
diff -rupN dosbox_BAK/src/dos/drive_iso.cpp dosbox/src/dos/drive_iso.cpp
|
|
--- dosbox_BAK/src/dos/drive_iso.cpp 2015-08-30 01:02:00.896699457 -0700
|
|
+++ dosbox/src/dos/drive_iso.cpp 2015-08-30 01:03:17.444700004 -0700
|
|
@@ -266,16 +266,16 @@ bool isoDrive::FindFirst(const char *dir
|
|
dta.SetDirID((Bit16u)dirIterator);
|
|
|
|
Bit8u attr;
|
|
- char pattern[ISO_MAXPATHNAME];
|
|
+ char pattern[CROSS_LEN];
|
|
dta.GetSearchParams(attr, pattern);
|
|
|
|
if (attr == DOS_ATTR_VOLUME) {
|
|
- dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME);
|
|
+ dta.SetResult(discLabel, discLabel, 0, 0, 0, DOS_ATTR_VOLUME);
|
|
return true;
|
|
} else if ((attr & DOS_ATTR_VOLUME) && isRoot && !fcb_findfirst) {
|
|
if (WildFileCmp(discLabel,pattern)) {
|
|
// Get Volume Label (DOS_ATTR_VOLUME) and only in basedir and if it matches the searchstring
|
|
- dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME);
|
|
+ dta.SetResult(discLabel, discLabel, 0, 0, 0, DOS_ATTR_VOLUME);
|
|
return true;
|
|
}
|
|
}
|
|
@@ -285,7 +285,7 @@ bool isoDrive::FindFirst(const char *dir
|
|
|
|
bool isoDrive::FindNext(DOS_DTA &dta) {
|
|
Bit8u attr;
|
|
- char pattern[DOS_NAMELENGTH_ASCII];
|
|
+ char pattern[CROSS_LEN], findName[DOS_NAMELENGTH_ASCII], lfindName[ISO_MAXPATHNAME];
|
|
dta.GetSearchParams(attr, pattern);
|
|
|
|
int dirIterator = dta.GetDirID();
|
|
@@ -298,11 +298,13 @@ bool isoDrive::FindNext(DOS_DTA &dta) {
|
|
else findAttr |= DOS_ATTR_ARCHIVE;
|
|
if (IS_HIDDEN(FLAGS1)) findAttr |= DOS_ATTR_HIDDEN;
|
|
|
|
- if (!IS_ASSOC(FLAGS1) && !(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern)
|
|
+ GetLongName((char*)de.ident,lfindName);
|
|
+ char temp[ISO_MAXPATHNAME*2];
|
|
+ sprintf(temp,"%s%s\n",lfindName,lfindName);
|
|
+ if (!IS_ASSOC(FLAGS1) && !(isRoot && de.ident[0]=='.') && (WildFileCmp((char*)de.ident, pattern) || LWildFileCmp(lfindName, pattern))
|
|
&& !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) {
|
|
|
|
/* file is okay, setup everything to be copied in DTA Block */
|
|
- char findName[DOS_NAMELENGTH_ASCII];
|
|
findName[0] = 0;
|
|
if(strlen((char*)de.ident) < DOS_NAMELENGTH_ASCII) {
|
|
strcpy(findName, (char*)de.ident);
|
|
@@ -311,7 +313,7 @@ bool isoDrive::FindNext(DOS_DTA &dta) {
|
|
Bit32u findSize = DATA_LENGTH(de);
|
|
Bit16u findDate = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay);
|
|
Bit16u findTime = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec);
|
|
- dta.SetResult(findName, findSize, findDate, findTime, findAttr);
|
|
+ dta.SetResult(findName, lfindName, findSize, findDate, findTime, findAttr);
|
|
return true;
|
|
}
|
|
}
|
|
@@ -533,7 +535,7 @@ bool isoDrive :: lookup(isoDirEntry *de,
|
|
*de = this->rootEntry;
|
|
if (!strcmp(path, "")) return true;
|
|
|
|
- char isoPath[ISO_MAXPATHNAME];
|
|
+ char isoPath[ISO_MAXPATHNAME], longname[ISO_MAXPATHNAME];
|
|
safe_strncpy(isoPath, path, ISO_MAXPATHNAME);
|
|
strreplace(isoPath, '\\', '/');
|
|
|
|
@@ -553,7 +555,8 @@ bool isoDrive :: lookup(isoDirEntry *de,
|
|
// look for the current path element
|
|
int dirIterator = GetDirIterator(de);
|
|
while (!found && GetNextDirEntry(dirIterator, de)) {
|
|
- if (!IS_ASSOC(FLAGS2) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH))) {
|
|
+ GetLongName((char*)de->ident,longname);
|
|
+ if (!IS_ASSOC(FLAGS2) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH)) ||0 == strncasecmp((char*) longname, name, ISO_MAXPATHNAME)) {
|
|
found = true;
|
|
}
|
|
}
|
|
@@ -570,3 +573,16 @@ void isoDrive :: MediaChange() {
|
|
IDE_ATAPI_MediaChangeNotify(toupper(driveLetter) - 'A'); /* ewwww */
|
|
}
|
|
|
|
+void isoDrive :: GetLongName(char *ident, char *lfindName) {
|
|
+ char *c=ident+strlen(ident);
|
|
+ int i,j=222-strlen(ident)-6;
|
|
+ for (i=5;i<j;i++) {
|
|
+ if (*(c+i)=='N'&&*(c+i+1)=='M'&&*(c+i+2)>0&&*(c+i+3)==1&&*(c+i+4)==0&&*(c+i+5)>0)
|
|
+ break;
|
|
+ }
|
|
+ if (i<j&&strcmp(ident,".")&&strcmp(ident,"..")) {
|
|
+ strncpy(lfindName,c+i+5,*(c+i+2)-5);
|
|
+ lfindName[*(c+i+2)-5]=0;
|
|
+ } else
|
|
+ strcpy(lfindName,ident);
|
|
+}
|
|
diff -rupN dosbox_BAK/src/dos/drive_local.cpp dosbox/src/dos/drive_local.cpp
|
|
--- dosbox_BAK/src/dos/drive_local.cpp 2015-08-30 01:02:00.744699454 -0700
|
|
+++ dosbox/src/dos/drive_local.cpp 2015-08-30 01:15:43.244721561 -0700
|
|
@@ -235,7 +235,7 @@ bool localDrive::FindFirst(const char *
|
|
if (this->isRemote() && this->isRemovable()) {
|
|
// cdroms behave a bit different than regular drives
|
|
if (sAttr == DOS_ATTR_VOLUME) {
|
|
- dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME);
|
|
+ dta.SetResult(dirCache.GetLabel(),dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME);
|
|
return true;
|
|
}
|
|
} else {
|
|
@@ -247,13 +247,13 @@ bool localDrive::FindFirst(const char *
|
|
DOS_SetError(DOSERR_NO_MORE_FILES);
|
|
return false;
|
|
}
|
|
- dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME);
|
|
+ dta.SetResult(dirCache.GetLabel(),dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME);
|
|
return true;
|
|
} else if ((sAttr & DOS_ATTR_VOLUME) && (*_dir == 0) && !fcb_findfirst) {
|
|
//should check for a valid leading directory instead of 0
|
|
//exists==true if the volume label matches the searchmask and the path is valid
|
|
if (WildFileCmp(dirCache.GetLabel(),tempDir)) {
|
|
- dta.SetResult(dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME);
|
|
+ dta.SetResult(dirCache.GetLabel(),dirCache.GetLabel(),0,0,0,DOS_ATTR_VOLUME);
|
|
return true;
|
|
}
|
|
}
|
|
@@ -263,31 +263,36 @@ bool localDrive::FindFirst(const char *
|
|
|
|
bool localDrive::FindNext(DOS_DTA & dta) {
|
|
|
|
- char * dir_ent;
|
|
+ char * dir_ent, *ldir_ent;
|
|
struct stat stat_block;
|
|
- char full_name[CROSS_LEN];
|
|
- char dir_entcopy[CROSS_LEN];
|
|
+ char full_name[CROSS_LEN], lfull_name[LFN_NAMELENGTH+1];
|
|
+ char dir_entcopy[CROSS_LEN], ldir_entcopy[CROSS_LEN];
|
|
|
|
- Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII];
|
|
+ Bit8u srch_attr;char srch_pattern[LFN_NAMELENGTH];
|
|
Bit8u find_attr;
|
|
|
|
dta.GetSearchParams(srch_attr,srch_pattern);
|
|
Bit16u id = dta.GetDirID();
|
|
|
|
again:
|
|
- if (!dirCache.FindNext(id,dir_ent)) {
|
|
+ if (!dirCache.FindNext(id,dir_ent,ldir_ent)) {
|
|
DOS_SetError(DOSERR_NO_MORE_FILES);
|
|
return false;
|
|
}
|
|
- if(!WildFileCmp(dir_ent,srch_pattern)) goto again;
|
|
+ if(!WildFileCmp(dir_ent,srch_pattern)&&!LWildFileCmp(ldir_ent,srch_pattern)) goto again;
|
|
|
|
strcpy(full_name,srchInfo[id].srch_dir);
|
|
strcat(full_name,dir_ent);
|
|
+
|
|
+ strcat(lfull_name,ldir_ent);
|
|
+ char temp[LFN_NAMELENGTH*2+2];
|
|
+ sprintf(temp,"%s%s",lfull_name,lfull_name);
|
|
|
|
//GetExpandName might indirectly destroy dir_ent (by caching in a new directory
|
|
//and due to its design dir_ent might be lost.)
|
|
//Copying dir_ent first
|
|
strcpy(dir_entcopy,dir_ent);
|
|
+ strcpy(ldir_entcopy,ldir_ent);
|
|
if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) {
|
|
goto again;//No symlinks and such
|
|
}
|
|
@@ -297,12 +302,14 @@ again:
|
|
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;
|
|
+ char find_name[DOS_NAMELENGTH_ASCII], *lfind_name=ldir_ent;
|
|
+ Bit16u find_date,find_time;Bit32u find_size;
|
|
|
|
if(strlen(dir_entcopy)<DOS_NAMELENGTH_ASCII){
|
|
strcpy(find_name,dir_entcopy);
|
|
upcase(find_name);
|
|
}
|
|
+ lfind_name[LFN_NAMELENGTH]=0;
|
|
|
|
find_size=(Bit32u) stat_block.st_size;
|
|
struct tm *time;
|
|
@@ -313,7 +320,7 @@ again:
|
|
find_time=6;
|
|
find_date=4;
|
|
}
|
|
- dta.SetResult(find_name,find_size,find_date,find_time,find_attr);
|
|
+ dta.SetResult(find_name,lfind_name,find_size,find_date,find_time,find_attr);
|
|
return true;
|
|
}
|
|
|
|
@@ -461,13 +468,13 @@ void localDrive::closedir(void *handle)
|
|
close_directory((dir_information*)handle);
|
|
}
|
|
|
|
-bool localDrive::read_directory_first(void *handle, char* entry_name, bool& is_directory) {
|
|
- return ::read_directory_first((dir_information*)handle, entry_name, is_directory);
|
|
+bool localDrive::read_directory_first(void *handle, char* entry_name, char* entry_sname, bool& is_directory) {
|
|
+ return ::read_directory_first((dir_information*)handle, entry_name, entry_sname, is_directory);
|
|
}
|
|
|
|
-bool localDrive::read_directory_next(void *handle, char* entry_name, bool& is_directory) {
|
|
- return ::read_directory_next((dir_information*)handle, entry_name, is_directory);
|
|
-}
|
|
+bool localDrive::read_directory_next(void *handle, char* entry_name, char* entry_sname, bool& is_directory) {
|
|
+ return ::read_directory_next((dir_information*)handle, entry_name, entry_sname, is_directory);
|
|
+}
|
|
|
|
localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) {
|
|
strcpy(basedir,startdir);
|
|
diff -rupN dosbox_BAK/src/dos/drives.cpp dosbox/src/dos/drives.cpp
|
|
--- dosbox_BAK/src/dos/drives.cpp 2015-08-30 01:02:00.780699455 -0700
|
|
+++ dosbox/src/dos/drives.cpp 2015-08-30 01:03:17.444700004 -0700
|
|
@@ -28,15 +28,19 @@ bool WildFileCmp(const char * file, cons
|
|
{
|
|
char file_name[9];
|
|
char file_ext[4];
|
|
- char wild_name[9];
|
|
- char wild_ext[4];
|
|
+ char wild_name[10];
|
|
+ char wild_ext[5];
|
|
const char * find_ext;
|
|
Bitu r;
|
|
|
|
- strcpy(file_name," ");
|
|
- strcpy(file_ext," ");
|
|
- strcpy(wild_name," ");
|
|
- strcpy(wild_ext," ");
|
|
+ for (r=0;r<9;r++) {
|
|
+ file_name[r]=0;
|
|
+ wild_name[r]=0;
|
|
+ }
|
|
+ for (r=0;r<4;r++) {
|
|
+ file_ext[r]=0;
|
|
+ wild_ext[r]=0;
|
|
+ }
|
|
|
|
find_ext=strrchr(file,'.');
|
|
if (find_ext) {
|
|
@@ -52,12 +56,12 @@ bool WildFileCmp(const char * file, cons
|
|
find_ext=strrchr(wild,'.');
|
|
if (find_ext) {
|
|
Bitu size=(Bitu)(find_ext-wild);
|
|
- if (size>8) size=8;
|
|
+ if (size>9) size=9;
|
|
memcpy(wild_name,wild,size);
|
|
find_ext++;
|
|
- memcpy(wild_ext,find_ext,(strlen(find_ext)>3) ? 3 : strlen(find_ext));
|
|
+ memcpy(wild_ext,find_ext,(strlen(find_ext)>4) ? 4 : strlen(find_ext));
|
|
} else {
|
|
- memcpy(wild_name,wild,(strlen(wild) > 8) ? 8 : strlen(wild));
|
|
+ memcpy(wild_name,wild,(strlen(wild) > 9) ? 9 : strlen(wild));
|
|
}
|
|
upcase(wild_name);upcase(wild_ext);
|
|
/* Names are right do some checking */
|
|
@@ -67,6 +71,7 @@ bool WildFileCmp(const char * file, cons
|
|
if (wild_name[r]!='?' && wild_name[r]!=file_name[r]) return false;
|
|
r++;
|
|
}
|
|
+ if (wild_name[r]&&wild_name[r]!='*') return false;
|
|
checkext:
|
|
r=0;
|
|
while (r<3) {
|
|
@@ -74,6 +79,75 @@ checkext:
|
|
if (wild_ext[r]!='?' && wild_ext[r]!=file_ext[r]) return false;
|
|
r++;
|
|
}
|
|
+ if (wild_ext[r]&&wild_ext[r]!='*') return false;
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool LWildFileCmp(const char * file, const char * wild)
|
|
+{
|
|
+ if (!uselfn) return false;
|
|
+ char file_name[256];
|
|
+ char file_ext[256];
|
|
+ char wild_name[256];
|
|
+ char wild_ext[256];
|
|
+ const char * find_ext;
|
|
+ Bitu r;
|
|
+
|
|
+ for (r=0;r<256;r++) {
|
|
+ file_name[r]=0;
|
|
+ wild_name[r]=0;
|
|
+ }
|
|
+ for (r=0;r<256;r++) {
|
|
+ file_ext[r]=0;
|
|
+ wild_ext[r]=0;
|
|
+ }
|
|
+
|
|
+ Bitu size,elen;
|
|
+ find_ext=strrchr(file,'.');
|
|
+ if (find_ext) {
|
|
+ size=(Bitu)(find_ext-file);
|
|
+ if (size>255) size=255;
|
|
+ memcpy(file_name,file,size);
|
|
+ find_ext++;
|
|
+ elen=strlen(find_ext);
|
|
+ memcpy(file_ext,find_ext,(strlen(find_ext)>255) ? 255 : strlen(find_ext));
|
|
+ } else {
|
|
+ size=strlen(file);
|
|
+ elen=0;
|
|
+ memcpy(file_name,file,(strlen(file) > 255) ? 255 : strlen(file));
|
|
+ }
|
|
+ upcase(file_name);upcase(file_ext);
|
|
+ char nwild[LFN_NAMELENGTH+2];
|
|
+ strcpy(nwild,wild);
|
|
+ if (strrchr(nwild,'*')&&strrchr(nwild,'.')==NULL) strcat(nwild,".*");
|
|
+ find_ext=strrchr(nwild,'.');
|
|
+ if (find_ext) {
|
|
+ Bitu size=(Bitu)(find_ext-nwild);
|
|
+ if (size>255) size=255;
|
|
+ memcpy(wild_name,nwild,size);
|
|
+ find_ext++;
|
|
+ memcpy(wild_ext,find_ext,(strlen(find_ext)>255) ? 255 : strlen(find_ext));
|
|
+ } else {
|
|
+ memcpy(wild_name,nwild,(strlen(nwild) > 255) ? 255 : strlen(nwild));
|
|
+ }
|
|
+ upcase(wild_name);upcase(wild_ext);
|
|
+ /* Names are right do some checking */
|
|
+ r=0;
|
|
+ while (r<size) {
|
|
+ if (wild_name[r]=='*') goto checkext;
|
|
+ if (wild_name[r]!='?' && wild_name[r]!=file_name[r]) return false;
|
|
+ r++;
|
|
+ }
|
|
+ if (wild_name[r]&&wild_name[r]!='*') return false;
|
|
+checkext:
|
|
+ r=0;
|
|
+ while (r<elen) {
|
|
+ if (wild_ext[r]=='*') return true;
|
|
+ if (wild_ext[r]!='?' && wild_ext[r]!=file_ext[r]) return false;
|
|
+ r++;
|
|
+ }
|
|
+ if (wild_ext[r]&&wild_ext[r]!='*') return false;
|
|
+
|
|
return true;
|
|
}
|
|
|
|
diff -rupN dosbox_BAK/src/dos/drives.h dosbox/src/dos/drives.h
|
|
--- dosbox_BAK/src/dos/drives.h 2015-08-30 01:01:59.104699409 -0700
|
|
+++ dosbox/src/dos/drives.h 2015-08-30 01:27:46.700741140 -0700
|
|
@@ -26,6 +26,7 @@
|
|
#include "shell.h" /* for DOS_Shell */
|
|
|
|
bool WildFileCmp(const char * file, const char * wild);
|
|
+bool LWildFileCmp(const char * file, const char * wild);
|
|
void Set_Label(char const * const input, char * const output, bool cdrom);
|
|
|
|
class DriveManager {
|
|
@@ -77,8 +78,8 @@ public:
|
|
virtual void SetLabel(const char *label, bool iscdrom, bool updatable) { dirCache.SetLabel(label,iscdrom,updatable); };
|
|
virtual void *opendir(const char *dir);
|
|
virtual void closedir(void *handle);
|
|
- virtual bool read_directory_first(void *handle, char* entry_name, bool& is_directory);
|
|
- virtual bool read_directory_next(void *handle, char* entry_name, bool& is_directory);
|
|
+ virtual bool read_directory_first(void *handle, char* entry_name, char* entry_sname, bool& is_directory);
|
|
+ virtual bool read_directory_next(void *handle, char* entry_name, char* entry_sname, bool& is_directory);
|
|
|
|
virtual void EmptyCache(void) { dirCache.EmptyCache(); };
|
|
virtual void MediaChange() {};
|
|
@@ -413,6 +414,7 @@ private:
|
|
bool GetNextDirEntry(const int dirIterator, isoDirEntry* de);
|
|
void FreeDirIterator(const int dirIterator);
|
|
bool ReadCachedSector(Bit8u** buffer, const Bit32u sector);
|
|
+ void GetLongName(char *ident, char *lfindName);
|
|
|
|
struct DirIterator {
|
|
bool valid;
|
|
diff -rupN dosbox_BAK/src/dos/drive_virtual.cpp dosbox/src/dos/drive_virtual.cpp
|
|
--- dosbox_BAK/src/dos/drive_virtual.cpp 2015-08-30 01:02:00.480699445 -0700
|
|
+++ dosbox/src/dos/drive_virtual.cpp 2015-08-30 01:03:17.444700004 -0700
|
|
@@ -28,6 +28,7 @@
|
|
|
|
struct VFILE_Block {
|
|
const char * name;
|
|
+ const char * lname;
|
|
Bit8u * data;
|
|
Bit32u size;
|
|
Bit16u date;
|
|
@@ -49,6 +50,7 @@ void VFILE_Shutdown(void) {
|
|
void VFILE_Register(const char * name,Bit8u * data,Bit32u size) {
|
|
VFILE_Block * new_file=new VFILE_Block;
|
|
new_file->name=name;
|
|
+ new_file->lname=name;
|
|
new_file->data=data;
|
|
new_file->size=size;
|
|
new_file->date=DOS_PackDate(2002,10,1);
|
|
@@ -210,14 +212,14 @@ bool Virtual_Drive::FileExists(const cha
|
|
|
|
bool Virtual_Drive::FindFirst(const char * _dir,DOS_DTA & dta,bool fcb_findfirst) {
|
|
search_file=first_file;
|
|
- Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII];
|
|
+ Bit8u attr;char pattern[CROSS_LEN];
|
|
dta.GetSearchParams(attr,pattern);
|
|
if (attr == DOS_ATTR_VOLUME) {
|
|
- dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_VOLUME);
|
|
+ dta.SetResult("DOSBOX","DOSBOX",0,0,0,DOS_ATTR_VOLUME);
|
|
return true;
|
|
} else if ((attr & DOS_ATTR_VOLUME) && !fcb_findfirst) {
|
|
if (WildFileCmp("DOSBOX",pattern)) {
|
|
- dta.SetResult("DOSBOX",0,0,0,DOS_ATTR_VOLUME);
|
|
+ dta.SetResult("DOSBOX","DOSBOX",0,0,0,DOS_ATTR_VOLUME);
|
|
return true;
|
|
}
|
|
}
|
|
@@ -225,11 +227,11 @@ bool Virtual_Drive::FindFirst(const char
|
|
}
|
|
|
|
bool Virtual_Drive::FindNext(DOS_DTA & dta) {
|
|
- Bit8u attr;char pattern[DOS_NAMELENGTH_ASCII];
|
|
+ Bit8u attr;char pattern[CROSS_LEN];
|
|
dta.GetSearchParams(attr,pattern);
|
|
while (search_file) {
|
|
if (WildFileCmp(search_file->name,pattern)) {
|
|
- dta.SetResult(search_file->name,search_file->size,search_file->date,search_file->time,DOS_ATTR_ARCHIVE);
|
|
+ dta.SetResult(search_file->name,search_file->lname,search_file->size,search_file->date,search_file->time,DOS_ATTR_ARCHIVE);
|
|
search_file=search_file->next;
|
|
return true;
|
|
}
|
|
diff -rupN dosbox_BAK/src/hardware/hardware.cpp dosbox/src/hardware/hardware.cpp
|
|
--- dosbox_BAK/src/hardware/hardware.cpp 2015-08-30 01:01:55.076699300 -0700
|
|
+++ dosbox/src/hardware/hardware.cpp 2015-08-30 01:17:35.064726278 -0700
|
|
@@ -106,9 +106,9 @@ std::string GetCaptureFilePath(const cha
|
|
lowcase(file_start);
|
|
strcat(file_start,"_");
|
|
bool is_directory;
|
|
- char tempname[CROSS_LEN];
|
|
- bool testRead = read_directory_first(dir, tempname, is_directory );
|
|
- for ( ; testRead; testRead = read_directory_next(dir, tempname, is_directory) ) {
|
|
+ char tempname[CROSS_LEN], sname[12];
|
|
+ bool testRead = read_directory_first(dir, tempname, sname, is_directory );
|
|
+ for ( ; testRead; testRead = read_directory_next(dir, tempname, sname, is_directory) ) {
|
|
char * test=strstr(tempname,ext);
|
|
if (!test || strlen(test)!=strlen(ext))
|
|
continue;
|
|
@@ -148,8 +148,9 @@ FILE * OpenCaptureFile(const char * type
|
|
strcat(file_start,"_");
|
|
bool is_directory;
|
|
char tempname[CROSS_LEN];
|
|
- bool testRead = read_directory_first(dir, tempname, is_directory );
|
|
- for ( ; testRead; testRead = read_directory_next(dir, tempname, is_directory) ) {
|
|
+ bool testRead = read_directory_first(dir, tempname, tempname, is_directory );
|
|
+ for ( ; testRead; testRead = read_directory_next(dir, tempname, tempname, is_directory) ) {
|
|
+ // didn't adapt this for long file names
|
|
char * test=strstr(tempname,ext);
|
|
if (!test || strlen(test)!=strlen(ext))
|
|
continue;
|
|
diff -rupN dosbox_BAK/src/ints/xms.cpp dosbox/src/ints/xms.cpp
|
|
--- dosbox_BAK/src/ints/xms.cpp 2015-08-30 01:02:01.036699461 -0700
|
|
+++ dosbox/src/ints/xms.cpp 2015-08-30 01:03:17.448700244 -0700
|
|
@@ -132,6 +132,7 @@ Bitu XMS_GetEnabledA20(void) {
|
|
static RealPt xms_callback;
|
|
static bool umb_available = false;
|
|
static bool umb_init = false;
|
|
+bool uselfn;
|
|
|
|
static XMS_Block xms_handles[XMS_HANDLES];
|
|
|
|
@@ -545,6 +546,8 @@ private:
|
|
public:
|
|
XMS(Section* configuration):Module_base(configuration){
|
|
Section_prop * section=static_cast<Section_prop *>(configuration);
|
|
+ //dos.version.major = section->Get_string("ver");
|
|
+ uselfn = !strcmp(section->Get_string("ver"),"7.0");
|
|
umb_available=false;
|
|
|
|
if (!section->Get_bool("xms")) return;
|
|
diff -rupN dosbox_BAK/src/misc/cross.cpp dosbox/src/misc/cross.cpp
|
|
--- dosbox_BAK/src/misc/cross.cpp 2015-08-30 01:01:56.052699303 -0700
|
|
+++ dosbox/src/misc/cross.cpp 2015-08-30 01:03:17.448700244 -0700
|
|
@@ -154,7 +154,7 @@ dir_information* open_directory(const ch
|
|
return (_access(dirname,0) ? NULL : &dir);
|
|
}
|
|
|
|
-bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
+bool read_directory_first2(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data);
|
|
if (INVALID_HANDLE_VALUE == dirp->handle) {
|
|
return false;
|
|
@@ -168,7 +168,7 @@ bool read_directory_first(dir_informatio
|
|
return true;
|
|
}
|
|
|
|
-bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
+bool read_directory_next2(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
int result = FindNextFile(dirp->handle, &dirp->search_data);
|
|
if (result==0) return false;
|
|
|
|
@@ -180,6 +180,34 @@ bool read_directory_next(dir_information
|
|
return true;
|
|
}
|
|
|
|
+bool read_directory_first(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory) {
|
|
+ dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data);
|
|
+ if (INVALID_HANDLE_VALUE == dirp->handle) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
|
|
+ safe_strncpy(entry_sname,dirp->search_data.cAlternateFileName,13);
|
|
+
|
|
+ if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
|
|
+ else is_directory = false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool read_directory_next(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory) {
|
|
+ int result = FindNextFile(dirp->handle, &dirp->search_data);
|
|
+ if (result==0) return false;
|
|
+
|
|
+ safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
|
|
+ safe_strncpy(entry_sname,dirp->search_data.cAlternateFileName,13);
|
|
+
|
|
+ if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
|
|
+ else is_directory = false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
void close_directory(dir_information* dirp) {
|
|
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
|
FindClose(dirp->handle);
|
|
@@ -196,7 +224,7 @@ dir_information* open_directory(const ch
|
|
return dir.dir?&dir:NULL;
|
|
}
|
|
|
|
-bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
+bool read_directory_first(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory) {
|
|
struct dirent* dentry = readdir(dirp->dir);
|
|
if (dentry==NULL) {
|
|
return false;
|
|
@@ -204,6 +232,7 @@ bool read_directory_first(dir_informatio
|
|
|
|
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
|
|
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
|
+ entry_sname[0]=0;
|
|
|
|
#ifdef DIRENT_HAS_D_TYPE
|
|
if(dentry->d_type == DT_DIR) {
|
|
@@ -227,7 +256,7 @@ bool read_directory_first(dir_informatio
|
|
return true;
|
|
}
|
|
|
|
-bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
+bool read_directory_next(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory) {
|
|
struct dirent* dentry = readdir(dirp->dir);
|
|
if (dentry==NULL) {
|
|
return false;
|
|
@@ -235,6 +264,7 @@ bool read_directory_next(dir_information
|
|
|
|
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
|
|
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
|
+ entry_sname[0]=0;
|
|
|
|
#ifdef DIRENT_HAS_D_TYPE
|
|
if(dentry->d_type == DT_DIR) {
|
|
diff -rupN dosbox_BAK/src/misc/programs.cpp dosbox/src/misc/programs.cpp
|
|
--- dosbox_BAK/src/misc/programs.cpp 2015-08-30 01:01:56.256699348 -0700
|
|
+++ dosbox/src/misc/programs.cpp 2015-08-30 01:03:17.448700244 -0700
|
|
@@ -148,9 +148,9 @@ Program::Program() {
|
|
while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1;
|
|
envscan+=3;
|
|
CommandTail tail;
|
|
- MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128);
|
|
- if (tail.count<127) tail.buffer[tail.count]=0;
|
|
- else tail.buffer[126]=0;
|
|
+ MEM_BlockRead(PhysMake(dos.psp(),CTBUF+1),&tail,CTBUF+1);
|
|
+ if (tail.count<CTBUF) tail.buffer[tail.count]=0;
|
|
+ else tail.buffer[CTBUF-1]=0;
|
|
char filename[256+1];
|
|
MEM_StrCopy(envscan,filename,256);
|
|
cmd = new CommandLine(filename,tail.buffer);
|
|
diff -rupN dosbox_BAK/src/misc/support.cpp dosbox/src/misc/support.cpp
|
|
--- dosbox_BAK/src/misc/support.cpp 2015-08-30 01:01:56.052699296 -0700
|
|
+++ dosbox/src/misc/support.cpp 2015-08-30 01:03:17.448700244 -0700
|
|
@@ -118,6 +118,7 @@ char * ScanCMDRemain(char * cmd) {
|
|
|
|
char * StripWord(char *&line) {
|
|
char * scan=line;
|
|
+ int q=0;
|
|
scan=ltrim(scan);
|
|
if (*scan=='"') {
|
|
char * end_quote=strchr(scan+1,'"');
|
|
@@ -130,6 +131,23 @@ char * StripWord(char *&line) {
|
|
char * begin=scan;
|
|
for (char c = *scan ;(c = *scan);scan++) {
|
|
if (isspace(*reinterpret_cast<unsigned char*>(&c))) {
|
|
+ *scan++=0;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ line=scan;
|
|
+ return begin;
|
|
+ }
|
|
+
|
|
+ char * StripArg(char *&line) {
|
|
+ char * scan=line;
|
|
+ int q=0;
|
|
+ scan=ltrim(scan);
|
|
+ char * begin=scan;
|
|
+ for (char c = *scan ;(c = *scan);scan++) {
|
|
+ if (*scan=='"') {
|
|
+ q++;
|
|
+ } else if (q/2*2==q && isspace(*reinterpret_cast<unsigned char*>(&c))) {
|
|
*scan++=0;
|
|
break;
|
|
}
|
|
diff -rupN dosbox_BAK/src/shell/shell_cmds.cpp dosbox/src/shell/shell_cmds.cpp
|
|
--- dosbox_BAK/src/shell/shell_cmds.cpp 2015-08-30 01:02:01.212699470 -0700
|
|
+++ dosbox/src/shell/shell_cmds.cpp 2015-08-30 01:03:17.524701530 -0700
|
|
@@ -397,7 +397,10 @@ continue_1:
|
|
args = ExpandDot(args,buffer);
|
|
StripSpaces(args);
|
|
if (!DOS_Canonicalize(args,full)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return; }
|
|
- bool res=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME);
|
|
+ char spath[DOS_PATHLENGTH],sargs[DOS_PATHLENGTH];
|
|
+ DOS_GetSFNPath(args,spath,false);
|
|
+ sprintf(sargs,"\"%s\"",spath);
|
|
+ bool res=DOS_FindFirst(sargs,0xffff & ~DOS_ATTR_VOLUME);
|
|
if (!res) {
|
|
WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args);
|
|
dos.dta(save_dta);
|
|
@@ -405,10 +408,11 @@ continue_1:
|
|
}
|
|
//end can't be 0, but if it is we'll get a nice crash, who cares :)
|
|
char * end=strrchr(full,'\\')+1;*end=0;
|
|
- char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u time,date;Bit8u attr;
|
|
+ char name[DOS_NAMELENGTH_ASCII],lname[LFN_NAMELENGTH+1];
|
|
+ Bit32u size;Bit16u time,date;Bit8u attr;
|
|
DOS_DTA dta(dos.dta());
|
|
while (res) {
|
|
- dta.GetResult(name,size,date,time,attr);
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
if (!(attr & (DOS_ATTR_DIRECTORY|DOS_ATTR_READ_ONLY))) {
|
|
strcpy(end,name);
|
|
if (!DOS_UnlinkFile(full)) WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),full);
|
|
@@ -438,7 +442,7 @@ void DOS_Shell::CMD_RENAME(char * args){
|
|
StripSpaces(args);
|
|
if(!*args) {SyntaxError();return;}
|
|
if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;}
|
|
- char * arg1=StripWord(args);
|
|
+ char * arg1=StripArg(args);
|
|
char* slash = strrchr(arg1,'\\');
|
|
if(slash) {
|
|
slash++;
|
|
@@ -457,15 +461,17 @@ void DOS_Shell::CMD_RENAME(char * args){
|
|
|
|
char dir_current[DOS_PATHLENGTH + 1];
|
|
dir_current[0] = '\\'; //Absolute addressing so we can return properly
|
|
- DOS_GetCurrentDir(0,dir_current + 1);
|
|
+ DOS_GetCurrentDir(0,dir_current + 1,false);
|
|
if(!DOS_ChangeDir(dir_source)) {
|
|
WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));
|
|
return;
|
|
}
|
|
- DOS_Rename(slash,args);
|
|
+ if (!DOS_Rename(slash,args))
|
|
+ WriteOut(MSG_Get("SHELL_CMD_RENAME_ERROR"),slash);
|
|
DOS_ChangeDir(dir_current);
|
|
} else {
|
|
- DOS_Rename(arg1,args);
|
|
+ if (!DOS_Rename(arg1,args))
|
|
+ WriteOut(MSG_Get("SHELL_CMD_RENAME_ERROR"),arg1);
|
|
}
|
|
}
|
|
|
|
@@ -506,15 +512,18 @@ void DOS_Shell::CMD_EXIT(char * args) {
|
|
void DOS_Shell::CMD_CHDIR(char * args) {
|
|
HELP("CHDIR");
|
|
StripSpaces(args);
|
|
+ char sargs[CROSS_LEN];
|
|
+ DOS_GetSFNPath(args,sargs,false);
|
|
+
|
|
Bit8u drive = DOS_GetDefaultDrive()+'A';
|
|
char dir[DOS_PATHLENGTH];
|
|
if (!*args) {
|
|
- DOS_GetCurrentDir(0,dir);
|
|
+ DOS_GetCurrentDir(0,dir,true);
|
|
WriteOut("%c:\\%s\n",drive,dir);
|
|
} else if(strlen(args) == 2 && args[1]==':') {
|
|
Bit8u targetdrive = (args[0] | 0x20)-'a' + 1;
|
|
unsigned char targetdisplay = *reinterpret_cast<unsigned char*>(&args[0]);
|
|
- if(!DOS_GetCurrentDir(targetdrive,dir)) {
|
|
+ if(!DOS_GetCurrentDir(targetdrive,dir,true)) { // verify that this should be true
|
|
if(drive == 'Z') {
|
|
WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(targetdisplay));
|
|
} else {
|
|
@@ -525,7 +534,7 @@ void DOS_Shell::CMD_CHDIR(char * args) {
|
|
WriteOut("%c:\\%s\n",toupper(targetdisplay),dir);
|
|
if(drive == 'Z')
|
|
WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT"),toupper(targetdisplay));
|
|
- } else if (!DOS_ChangeDir(args)) {
|
|
+ } else if (!DOS_ChangeDir(sargs)) {
|
|
/* Changedir failed. Check if the filename is longer then 8 and/or contains spaces */
|
|
|
|
std::string temps(args),slashpart;
|
|
@@ -536,6 +545,8 @@ void DOS_Shell::CMD_CHDIR(char * args) {
|
|
}
|
|
separator = temps.find_first_of("\\/");
|
|
if(separator != std::string::npos) temps.erase(separator);
|
|
+ separator = temps.find_first_of("\"");
|
|
+ if(separator != std::string::npos) temps.erase(separator);
|
|
separator = temps.rfind('.');
|
|
if(separator != std::string::npos) temps.erase(separator);
|
|
separator = temps.find(' ');
|
|
@@ -544,10 +555,6 @@ void DOS_Shell::CMD_CHDIR(char * args) {
|
|
if(temps.size() >6) temps.erase(6);
|
|
temps += "~1";
|
|
WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temps.insert(0,slashpart).c_str());
|
|
- } else if (temps.size()>8) {
|
|
- temps.erase(6);
|
|
- temps += "~1";
|
|
- WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temps.insert(0,slashpart).c_str());
|
|
} else {
|
|
if (drive == 'Z') {
|
|
WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_3"));
|
|
@@ -615,6 +622,7 @@ void DOS_Shell::CMD_DIR(char * args) {
|
|
HELP("DIR");
|
|
char numformat[16];
|
|
char path[DOS_PATHLENGTH];
|
|
+ char sargs[CROSS_LEN];
|
|
|
|
std::string line;
|
|
if(GetEnvStr("DIRCMD",line)){
|
|
@@ -674,10 +682,16 @@ void DOS_Shell::CMD_DIR(char * args) {
|
|
}
|
|
if (!strrchr(args,'*') && !strrchr(args,'?')) {
|
|
Bit16u attribute=0;
|
|
- if(DOS_GetFileAttr(args,&attribute) && (attribute&DOS_ATTR_DIRECTORY) ) {
|
|
+ DOS_GetSFNPath(args,sargs,false);
|
|
+ if(DOS_GetFileAttr(sargs,&attribute) && (attribute&DOS_ATTR_DIRECTORY) ) {
|
|
+ DOS_FindFirst(sargs,0xffff & ~DOS_ATTR_VOLUME);
|
|
+ DOS_DTA dta(dos.dta());
|
|
+ strcpy(args,sargs);
|
|
strcat(args,"\\*.*"); // if no wildcard and a directory, get its files
|
|
}
|
|
}
|
|
+ DOS_GetSFNPath(args,sargs,false);
|
|
+ sprintf(args,"\"%s\"",sargs);
|
|
if (!strrchr(args,'.')) {
|
|
strcat(args,".*"); // if no extension, get them all
|
|
}
|
|
@@ -688,10 +702,9 @@ void DOS_Shell::CMD_DIR(char * args) {
|
|
return;
|
|
}
|
|
*(strrchr(path,'\\')+1)=0;
|
|
- if (!optB) {
|
|
- CMD_VOL(empty_string);
|
|
- WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path);
|
|
- }
|
|
+ DOS_GetSFNPath(path,sargs,true);
|
|
+ if (*(sargs+strlen(sargs)-1) != '\\') strcat(sargs,"\\");
|
|
+ if (!optB) WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),sargs);
|
|
|
|
/* Command uses dta so set it to our internal dta */
|
|
RealPt save_dta=dos.dta();
|
|
@@ -713,8 +726,9 @@ void DOS_Shell::CMD_DIR(char * args) {
|
|
}
|
|
|
|
do { /* File name and extension */
|
|
- char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
|
|
- dta.GetResult(name,size,date,time,attr);
|
|
+ char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH+1];
|
|
+ Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
|
|
/* Skip non-directories if option AD is present */
|
|
if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue;
|
|
@@ -722,8 +736,8 @@ void DOS_Shell::CMD_DIR(char * args) {
|
|
/* output the file */
|
|
if (optB) {
|
|
// this overrides pretty much everything
|
|
- if (strcmp(".",name) && strcmp("..",name)) {
|
|
- WriteOut("%s\n",name);
|
|
+ if (strcmp(".",uselfn?lname:name) && strcmp("..",uselfn?lname:name)) {
|
|
+ WriteOut("%s\n",uselfn?lname:name);
|
|
}
|
|
} else {
|
|
char * ext = empty_string;
|
|
@@ -746,7 +760,7 @@ void DOS_Shell::CMD_DIR(char * args) {
|
|
for (size_t i=14-namelen;i>0;i--) WriteOut(" ");
|
|
}
|
|
} else {
|
|
- WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"<DIR>",day,month,year,hour,minute);
|
|
+ WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d %s\n",name,ext,"<DIR>",day,month,year,hour,minute,uselfn?lname:"");
|
|
}
|
|
dir_count++;
|
|
} else {
|
|
@@ -754,7 +768,7 @@ void DOS_Shell::CMD_DIR(char * args) {
|
|
WriteOut("%-16s",name);
|
|
} else {
|
|
FormatNumber(size,numformat);
|
|
- WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",name,ext,numformat,day,month,year,hour,minute);
|
|
+ WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d %s\n",name,ext,numformat,day,month,year,hour,minute,uselfn?lname:"");
|
|
}
|
|
file_count++;
|
|
byte_count+=size;
|
|
@@ -820,7 +834,7 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
dos.dta(dos.tables.tempdta);
|
|
DOS_DTA dta(dos.dta());
|
|
Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
|
|
- char name[DOS_NAMELENGTH_ASCII];
|
|
+ char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH+1];
|
|
std::vector<copysource> sources;
|
|
// ignore /b and /t switches: always copy binary
|
|
while(ScanCMDBool(args,"B")) ;
|
|
@@ -839,9 +853,10 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
// Gather all sources (extension to copy more then 1 file specified at command line)
|
|
// Concatenating files go as follows: All parts except for the last bear the concat flag.
|
|
// This construction allows them to be counted (only the non concat set)
|
|
+ char q[]="\"";
|
|
char* source_p = NULL;
|
|
char source_x[DOS_PATHLENGTH+CROSS_LEN];
|
|
- while ( (source_p = StripWord(args)) && *source_p ) {
|
|
+ while ( (source_p = StripArg(args)) && *source_p ) {
|
|
do {
|
|
char* plus = strchr(source_p,'+');
|
|
// If StripWord() previously cut at a space before a plus then
|
|
@@ -860,8 +875,10 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
if (source_x[source_x_len-1]==':') has_drive_spec = true;
|
|
}
|
|
if (!has_drive_spec && !strpbrk(source_p,"*?") ) { //doubt that fu*\*.* is valid
|
|
- if (DOS_FindFirst(source_p,0xffff & ~DOS_ATTR_VOLUME)) {
|
|
- dta.GetResult(name,size,date,time,attr);
|
|
+ char spath[DOS_PATHLENGTH];
|
|
+ DOS_GetSFNPath(source_p,spath,false);
|
|
+ if (DOS_FindFirst(spath,0xffff & ~DOS_ATTR_VOLUME)) {
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
if (attr & DOS_ATTR_DIRECTORY)
|
|
strcat(source_x,"\\*.*");
|
|
}
|
|
@@ -926,7 +943,7 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
// add '\\' if target is a directory
|
|
if (pathTarget[strlen(pathTarget)-1]!='\\') {
|
|
if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) {
|
|
- dta.GetResult(name,size,date,time,attr);
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
if (attr & DOS_ATTR_DIRECTORY)
|
|
strcat(pathTarget,"\\");
|
|
}
|
|
@@ -989,7 +1006,7 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
}
|
|
|
|
while (ret) {
|
|
- dta.GetResult(name,size,date,time,attr);
|
|
+ dta.GetResult(name,lname,size,date,time,attr);
|
|
|
|
if ((attr & DOS_ATTR_DIRECTORY)==0) {
|
|
strcpy(nameSource,pathSource);
|
|
@@ -997,7 +1014,8 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
// Open Source
|
|
if (DOS_OpenFile(nameSource,0,&sourceHandle)) {
|
|
// Create Target or open it if in concat mode
|
|
- strcpy(nameTarget,pathTarget);
|
|
+ strcpy(nameTarget,q);
|
|
+ strcat(nameTarget,pathTarget);
|
|
|
|
if (ext) { // substitute parts if necessary
|
|
if (!ext[-1]) { // substitute extension
|
|
@@ -1009,7 +1027,8 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
}
|
|
}
|
|
|
|
- if (nameTarget[pathTargetLen-1]=='\\') strcat(nameTarget,name);
|
|
+ if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,uselfn?lname:name);
|
|
+ strcat(nameTarget,q);
|
|
//Don't create a new file when in concat mode
|
|
if (oldsource.concat || DOS_CreateFile(nameTarget,0,&targetHandle)) {
|
|
Bit32u dummy=0;
|
|
@@ -1026,7 +1045,10 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
} while (toread==0x8000);
|
|
failed |= DOS_CloseFile(sourceHandle);
|
|
failed |= DOS_CloseFile(targetHandle);
|
|
- WriteOut(" %s\n",name);
|
|
+ if (strcmp(name,lname)&&uselfn)
|
|
+ WriteOut(" %s [%s]\n",lname,name);
|
|
+ else
|
|
+ WriteOut(" %s\n",uselfn?lname:name);
|
|
if(!source.concat) count++; //Only count concat files once
|
|
} else {
|
|
DOS_CloseFile(sourceHandle);
|
|
@@ -1046,6 +1068,7 @@ void DOS_Shell::CMD_COPY(char * args) {
|
|
|
|
WriteOut(MSG_Get("SHELL_CMD_COPY_SUCCESS"),count);
|
|
dos.dta(save_dta);
|
|
+ Drives[DOS_GetDefaultDrive()]->EmptyCache();
|
|
}
|
|
|
|
/* NTS: WARNING, this function modifies the buffer pointed to by char *args */
|
|
@@ -1133,7 +1156,7 @@ void DOS_Shell::CMD_IF(char * args) {
|
|
if(strncasecmp(args,"EXIST ",6) == 0) {
|
|
args += 6; //Skip text
|
|
StripSpaces(args);
|
|
- char* word = StripWord(args);
|
|
+ char* word = StripArg(args);
|
|
if (!*word) {
|
|
WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME"));
|
|
return;
|
|
@@ -1225,7 +1248,7 @@ void DOS_Shell::CMD_TYPE(char * args) {
|
|
Bit16u handle;
|
|
char * word;
|
|
nextfile:
|
|
- word=StripWord(args);
|
|
+ word=StripArg(args);
|
|
if (!DOS_OpenFile(word,0,&handle)) {
|
|
WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),word);
|
|
return;
|
|
@@ -1475,8 +1498,11 @@ void DOS_Shell::CMD_SUBST (char * args)
|
|
strcat(mountstring,temp_str);
|
|
strcat(mountstring," ");
|
|
|
|
- Bit8u drive;char fulldir[DOS_PATHLENGTH];
|
|
- if (!DOS_MakeName(const_cast<char*>(arg.c_str()),fulldir,&drive)) throw 0;
|
|
+ Bit8u drive;char dir[DOS_PATHLENGTH+2],fulldir[DOS_PATHLENGTH];
|
|
+ if (strchr(arg.c_str(),'\"')==NULL)
|
|
+ sprintf(dir,"\"%s\"",arg.c_str());
|
|
+ else strcpy(dir,arg.c_str());
|
|
+ if (!DOS_MakeName(dir,fulldir,&drive)) throw 0;
|
|
|
|
if( ( ldp=dynamic_cast<localDrive*>(Drives[drive])) == 0 ) throw 0;
|
|
char newname[CROSS_LEN];
|
|
diff -rupN dosbox_BAK/src/shell/shell.cpp dosbox/src/shell/shell.cpp
|
|
--- dosbox_BAK/src/shell/shell.cpp 2015-08-30 01:02:01.320699468 -0700
|
|
+++ dosbox/src/shell/shell.cpp 2015-08-30 01:03:17.512701529 -0700
|
|
@@ -504,7 +504,7 @@ void SHELL_Init() {
|
|
MSG_Add("SHELL_MISSING_PARAMETER","Required parameter missing.\n");
|
|
MSG_Add("SHELL_CMD_CHDIR_ERROR","Unable to change to: %s.\n");
|
|
MSG_Add("SHELL_CMD_CHDIR_HINT","Hint: To change to different drive type \033[31m%c:\033[0m\n");
|
|
- MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 characters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n");
|
|
+ MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname contains unquoted spaces.\nTry \033[31mcd %s\033[0m or properly quote them with quotation marks.\n");
|
|
MSG_Add("SHELL_CMD_CHDIR_HINT_3","You are still on drive Z:, change to a mounted drive with \033[31mC:\033[0m.\n");
|
|
MSG_Add("SHELL_CMD_DATE_HELP","Displays or changes the internal date.\n");
|
|
MSG_Add("SHELL_CMD_DATE_ERROR","The specified date is not correct.\n");
|
|
@@ -525,6 +525,7 @@ void SHELL_Init() {
|
|
" /H: Synchronize with host\n");
|
|
MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n");
|
|
MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n");
|
|
+ MSG_Add("SHELL_CMD_RENAME_ERROR","Unable to rename: %s.\n");
|
|
MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s.\n");
|
|
MSG_Add("SHELL_CMD_DEL_SURE","Are you sure[Y,N]?");
|
|
MSG_Add("SHELL_SYNTAXERROR","The syntax of the command is incorrect.\n");
|
|
@@ -49696,10 +49697,10 @@ static unsigned char hexmem32_exe[] = {
|
|
CommandTail tail;
|
|
tail.count=(Bit8u)strlen(init_line);
|
|
strcpy(tail.buffer,init_line);
|
|
- MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128);
|
|
+ MEM_BlockWrite(PhysMake(psp_seg,CTBUF+1),&tail,CTBUF+1);
|
|
|
|
/* Setup internal DOS Variables */
|
|
- dos.dta(RealMake(psp_seg,0x80));
|
|
+ dos.dta(RealMake(psp_seg,CTBUF+1));
|
|
dos.psp(psp_seg);
|
|
}
|
|
|
|
diff -rupN dosbox_BAK/src/shell/shell_misc.cpp dosbox/src/shell/shell_misc.cpp
|
|
--- dosbox_BAK/src/shell/shell_misc.cpp 2015-08-30 01:02:01.364699472 -0700
|
|
+++ dosbox/src/shell/shell_misc.cpp 2015-08-30 01:03:17.524701530 -0700
|
|
@@ -35,7 +35,7 @@
|
|
void DOS_Shell::ShowPrompt(void) {
|
|
char dir[DOS_PATHLENGTH];
|
|
dir[0] = 0; //DOS_GetCurrentDir doesn't always return something. (if drive is messed up)
|
|
- DOS_GetCurrentDir(0,dir);
|
|
+ DOS_GetCurrentDir(0,dir,uselfn);
|
|
std::string line;
|
|
const char * promptstr = "\0";
|
|
|
|
@@ -297,9 +297,20 @@ void DOS_Shell::InputCommand(char * line
|
|
// build new completion list
|
|
// Lines starting with CD will only get directories in the list
|
|
bool dir_only = (strncasecmp(line,"CD ",3)==0);
|
|
+ int q=0;
|
|
|
|
// get completion mask
|
|
char *p_completion_start = strrchr(line, ' ');
|
|
+ while (p_completion_start) {
|
|
+ q=0;
|
|
+ char *i;
|
|
+ for (i=line;i<p_completion_start;i++)
|
|
+ if (*i=='\"') q++;
|
|
+ if (q/2*2==q) break;
|
|
+ *i=0;
|
|
+ p_completion_start = strrchr(line, ' ');
|
|
+ *i=' ';
|
|
+ }
|
|
|
|
if (p_completion_start) {
|
|
p_completion_start ++;
|
|
@@ -314,7 +325,7 @@ void DOS_Shell::InputCommand(char * line
|
|
if ((path = strrchr(line+completion_index,'/'))) completion_index = (Bit16u)(path-line+1);
|
|
|
|
// build the completion list
|
|
- char mask[DOS_PATHLENGTH];
|
|
+ char mask[DOS_PATHLENGTH+2],smask[DOS_PATHLENGTH];
|
|
if (p_completion_start) {
|
|
strcpy(mask, p_completion_start);
|
|
char* dot_pos=strrchr(mask,'.');
|
|
@@ -332,6 +343,9 @@ void DOS_Shell::InputCommand(char * line
|
|
RealPt save_dta=dos.dta();
|
|
dos.dta(dos.tables.tempdta);
|
|
|
|
+ DOS_GetSFNPath(mask,smask,false);
|
|
+ sprintf(mask,"\"%s\"",smask);
|
|
+
|
|
bool res = DOS_FindFirst(mask, 0xffff & ~DOS_ATTR_VOLUME);
|
|
if (!res) {
|
|
dos.dta(save_dta);
|
|
@@ -339,24 +353,34 @@ void DOS_Shell::InputCommand(char * line
|
|
}
|
|
|
|
DOS_DTA dta(dos.dta());
|
|
- char name[DOS_NAMELENGTH_ASCII];Bit32u sz;Bit16u date;Bit16u time;Bit8u att;
|
|
+ char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH], qlname[LFN_NAMELENGTH+2];
|
|
+ Bit32u sz;Bit16u date;Bit16u time;Bit8u att;
|
|
|
|
std::list<std::string> executable;
|
|
+ q=0;
|
|
+ while (*p_completion_start)
|
|
+ if (*p_completion_start++=='\"')
|
|
+ q++;
|
|
while (res) {
|
|
- dta.GetResult(name,sz,date,time,att);
|
|
+ dta.GetResult(name,lname,sz,date,time,att);
|
|
+ if (strchr(uselfn?lname:name,' ')!=NULL&&q/2*2==q)
|
|
+ sprintf(qlname,"\"%s\"",uselfn?lname:name);
|
|
+ else
|
|
+ strcpy(qlname,uselfn?lname:name);
|
|
// add result to completion list
|
|
|
|
char *ext; // file extension
|
|
if (strcmp(name, ".") && strcmp(name, "..")) {
|
|
if (dir_only) { //Handle the dir only case different (line starts with cd)
|
|
- if(att & DOS_ATTR_DIRECTORY) l_completion.push_back(name);
|
|
+ if(att & DOS_ATTR_DIRECTORY) l_completion.push_back(qlname);
|
|
+
|
|
} else {
|
|
ext = strrchr(name, '.');
|
|
if (ext && (strcmp(ext, ".BAT") == 0 || strcmp(ext, ".COM") == 0 || strcmp(ext, ".EXE") == 0))
|
|
// we add executables to the a seperate list and place that list infront of the normal files
|
|
- executable.push_front(name);
|
|
+ executable.push_front(qlname);
|
|
else
|
|
- l_completion.push_back(name);
|
|
+ l_completion.push_back(qlname);
|
|
}
|
|
}
|
|
res=DOS_FindNext();
|
|
@@ -737,13 +761,13 @@ failed:
|
|
/* Fill the command line */
|
|
CommandTail cmdtail;
|
|
cmdtail.count = 0;
|
|
- memset(&cmdtail.buffer,0,127); //Else some part of the string is unitialized (valgrind)
|
|
- if (strlen(line)>126) line[126]=0;
|
|
+ memset(&cmdtail.buffer,0,CTBUF); //Else some part of the string is unitialized (valgrind)
|
|
+ if (strlen(line)>=CTBUF) line[CTBUF-1]=0;
|
|
cmdtail.count=(Bit8u)strlen(line);
|
|
memcpy(cmdtail.buffer,line,strlen(line));
|
|
cmdtail.buffer[strlen(line)]=0xd;
|
|
/* Copy command line in stack block too */
|
|
- MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmdtail,128);
|
|
+ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmdtail,CTBUF+1);
|
|
/* Parse FCB (first two parameters) and put them into the current DOS_PSP */
|
|
Bit8u add;
|
|
FCB_Parsename(dos.psp(),0x5C,0x00,cmdtail.buffer,&add);
|