dosbox-x/patch-integration/LFN/dosbox-x-patch-20150830-0426.patch
Jonathan Campbell edeb689c41 update status. LFN not applied, but we're getting closer to the issue.
It seems to be an issue with case sensitivity in filenames on Linux and
opening files with the LFN code.
2015-08-30 09:36:37 -07:00

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,&reg_ax,&reg_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,&sectbuf[entryoffset].entryname[0],8);
memcpy(extension,&sectbuf[entryoffset].entryname[8],3);
+ memcpy(lfind_name,&sectbuf[entryoffset].entryname[0],8);
+ memcpy(lfind_name,&sectbuf[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, &sectbuf[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);