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; }

