--- Begin Message ---
Source: dosbox
Version: 0.74-4
Severity: wishlist
Tags: patch
Hi Maintainer
Since wine 1.3.12, wine will attempt to launch MS-DOS executables with
dosbox [1].
For this integration to work, dosbox needs to support the 'mount -z y'
command to move the Z: mount to Y:.
This feature was added upstream in r3736 [2].
I examined the svn log to find other patches relating to wine and
found one other; r3742 [3].
Please consider including the two attached patches to improve
interoperability with wine.
Regards
Graham
[1] https://www.winehq.org/announce/1.3.12
[2] http://sourceforge.net/p/dosbox/code-0/3736/
[3] http://sourceforge.net/p/dosbox/code-0/3743/
Description: Rewrite mount without arguments to display volume label as well.
Some refactoring of the code.
Add mount -z X, where X is the new virtual drive for the Wine Team.
Origin: upstream, http://sourceforge.net/p/dosbox/code-0/3736/
Author: Peter Veenstra <[email protected]>
Last-Update: 2011-07-23
--- a/src/dos/dos_programs.cpp
+++ b/src/dos/dos_programs.cpp
@@ -49,27 +49,55 @@
#endif
void MSCDEX_SetCDInterface(int intNr, int forceCD);
-
+static Bitu ZDRIVE_NUM = 25;
class MOUNT : public Program {
public:
- void Run(void)
- {
+ void ListMounts(void) {
+ char name[DOS_NAMELENGTH_ASCII];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);
+ DOS_DTA dta(dos.dta());
+
+ WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1"));
+ WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),"Drive","Type","Label");
+ for(int p = 0;p < 8;p++) WriteOut("----------");
+
+ for (int d = 0;d < DOS_DRIVES;d++) {
+ if (!Drives[d]) continue;
+
+ char root[4] = {'A'+d,':','\\',0};
+ bool ret = DOS_FindFirst(root,DOS_ATTR_VOLUME);
+ if (ret) {
+ dta.GetResult(name,size,date,time,attr);
+ DOS_FindNext(); //Mark entry as invalid
+ } else name[0] = 0;
+
+ /* Change 8.3 to 11.0 */
+ char* dot = strchr(name,'.');
+ if(dot && (dot - name == 8) ) {
+ name[8] = name[9];name[9] = name[10];name[10] = name[11];name[11] = 0;
+ }
+
+ root[1] = 0; //This way, the format string can be reused.
+ WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),root, Drives[d]->GetInfo(),name);
+ }
+ dos.dta(save_dta);
+ }
+
+ void Run(void) {
DOS_Drive * newdrive;char drive;
std::string label;
std::string umount;
+ std::string newz;
//Hack To allow long commandlines
ChangeToLongCmd();
/* Parse the command line */
/* if the command line is empty show current mounts */
if (!cmd->GetCount()) {
- WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1"));
- for (int d=0;d<DOS_DRIVES;d++) {
- if (Drives[d]) {
- WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),d+'A',Drives[d]->GetInfo());
- }
- }
+ ListMounts();
return;
}
@@ -84,12 +112,12 @@
if (cmd->FindString("-u",umount,false)) {
umount[0] = toupper(umount[0]);
int i_drive = umount[0]-'A';
- if(i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) {
+ if (i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) {
switch (DriveManager::UnmountDrive(i_drive)) {
case 0:
Drives[i_drive] = 0;
if(i_drive == DOS_GetDefaultDrive())
- DOS_SetDrive(toupper('Z') - 'A');
+ DOS_SetDrive(ZDRIVE_NUM);
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]);
break;
case 1:
@@ -104,8 +132,46 @@
}
return;
}
-
- // Show list of cdroms
+
+ /* Check for moving Z: */
+ /* Only allowing moving it once. It is merely a convenience added for the wine team */
+ if (ZDRIVE_NUM == 25 && cmd->FindString("-z", newz,false)) {
+ newz[0] = toupper(newz[0]);
+ int i_newz = newz[0] - 'A';
+ if (i_newz >= 0 && i_newz < DOS_DRIVES-1 && !Drives[i_newz]) {
+ ZDRIVE_NUM = i_newz;
+ /* remap drives */
+ Drives[i_newz] = Drives[25];
+ Drives[25] = 0;
+ DOS_Shell *fs = static_cast<DOS_Shell *>(first_shell); //dynamic ?
+ /* Update environment */
+ std::string line = "";
+ char ppp[2] = {newz[0],0};
+ std::string tempenv = ppp; tempenv += ":\\";
+ if (fs->GetEnvStr("PATH",line)){
+ std::string::size_type idx = line.find('=');
+ std::string value = line.substr(idx +1 , std::string::npos);
+ while ( (idx = value.find("Z:\\")) != std::string::npos ||
+ (idx = value.find("z:\\")) != std::string::npos )
+ value.replace(idx,3,tempenv);
+ line = value;
+ }
+ if (!line.size()) line = tempenv;
+ fs->SetEnv("PATH",line.c_str());
+ tempenv += "COMMAND.COM";
+ fs->SetEnv("COMSPEC",tempenv.c_str());
+
+ /* Update batch file if running from Z: (very likely: autoexec) */
+ if(fs->bf) {
+ std::string &name = fs->bf->filename;
+ if(name.length() >2 && name[0] == 'Z' && name[1] == ':') name[0] = newz[0];
+ }
+ /* Change the active drive */
+ if (DOS_GetDefaultDrive() == 25) DOS_SetDrive(i_newz);
+ }
+ return;
+ }
+ /* Show list of cdroms */
if (cmd->FindExist("-cd",false)) {
int num = SDL_CDNumDrives();
WriteOut(MSG_Get("PROGRAM_MOUNT_CDROMS_FOUND"),num);
@@ -1347,8 +1413,9 @@
/*Add Messages */
MSG_Add("PROGRAM_MOUNT_CDROMS_FOUND","CDROMs found: %d\n");
+ MSG_Add("PROGRAM_MOUNT_STATUS_FORMAT","%-5s %-58s %-12s\n");
MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n");
- MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n");
+ MSG_Add("PROGRAM_MOUNT_STATUS_1","The currently mounted drives are:\n");
MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n");
MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n");
MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n");
Description: Be friendly for other open source projects: work with WINE style namemangling.
Patch 3382938 from Andre_H (modified).
Origin: upstream, http://sourceforge.net/p/dosbox/code-0/3743/
Author: Peter Veenstra <[email protected]>
Last-Update: 2011-08-30
--- a/src/dos/drive_cache.cpp
+++ b/src/dos/drive_cache.cpp
@@ -370,6 +370,60 @@
return false;
}
+#define WINE_DRIVE_SUPPORT 1
+#if WINE_DRIVE_SUPPORT
+//Changes to interact with WINE by supporting their namemangling.
+//The code is rather slow, because orglist is unordered, so it needs to be avoided if possible.
+//Hence the tests in GetLongFileName
+
+
+// From the Wine project
+static Bits wine_hash_short_file_name( char* name, char* buffer )
+{
+ static const char hash_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
+ static const char invalid_chars[] = { '*','?','<','>','|','"','+','=',',',';','[',']',' ','\345','~','.',0 };
+ char* p;
+ char* ext;
+ char* end = name + strlen(name);
+ char* dst;
+ unsigned short hash;
+ int i;
+
+ // Compute the hash code of the file name
+ for (p = name, hash = 0xbeef; p < end - 1; p++)
+ hash = (hash<<3) ^ (hash>>5) ^ tolower(*p) ^ (tolower(p[1]) << 8);
+ hash = (hash<<3) ^ (hash>>5) ^ tolower(*p); // Last character
+
+
+ // Find last dot for start of the extension
+ for (p = name + 1, ext = NULL; p < end - 1; p++) if (*p == '.') ext = p;
+
+ // Copy first 4 chars, replacing invalid chars with '_'
+ for (i = 4, p = name, dst = buffer; i > 0; i--, p++)
+ {
+ if (p == end || p == ext) break;
+ *dst++ = (*p < 0 || strchr( invalid_chars, *p ) != NULL) ? '_' : toupper(*p);
+ }
+ // Pad to 5 chars with '~'
+ while (i-- >= 0) *dst++ = '~';
+
+ // Insert hash code converted to 3 ASCII chars
+ *dst++ = hash_chars[(hash >> 10) & 0x1f];
+ *dst++ = hash_chars[(hash >> 5) & 0x1f];
+ *dst++ = hash_chars[hash & 0x1f];
+
+ // Copy the first 3 chars of the extension (if any)
+ if (ext)
+ {
+ *dst++ = '.';
+ for (i = 3, ext++; (i > 0) && ext < end; i--, ext++)
+ *dst++ = (*ext < 0 || strchr( invalid_chars, *ext ) != NULL) ? '_' : toupper(*ext);
+ }
+
+ return dst - buffer;
+}
+#endif
+
Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) {
std::vector<CFileInfo*>::size_type filelist_size = curDir->fileList.size();
if (GCC_UNLIKELY(filelist_size<=0)) return -1;
@@ -390,6 +444,20 @@
return mid;
};
}
+#ifdef WINE_DRIVE_SUPPORT
+ if (strlen(shortName) < 8 || shortName[4] != '~' || shortName[5] == '.' || shortName[6] == '.' || shortName[7] == '.') return -1; // not available
+ // else it's most likely a Wine style short name ABCD~###, # = not dot (length at least 8)
+ // The above test is rather strict as the following loop can be really slow if filelist_size is large.
+ char buff[CROSS_LEN];
+ for (Bits i = 0; i < filelist_size; i++) {
+ res = wine_hash_short_file_name(curDir->fileList[i]->orgname,buff);
+ if (!strncmp(shortName,buff,res))
+ { // Found
+ strcpy(shortName,curDir->fileList[i]->orgname);
+ return i;
+ };
+ }
+#endif
// not available
return -1;
}
--- End Message ---