winevdm: Try to exec dosbox if DOS is not supported natively.
This commit is contained in:
parent
cf1cd33570
commit
56193df2fd
|
@ -18,14 +18,19 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "winuser.h"
|
||||
#include "wincon.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(winevdm);
|
||||
|
@ -101,6 +106,93 @@ typedef struct {
|
|||
|
||||
#include "poppack.h"
|
||||
|
||||
/***********************************************************************
|
||||
* find_dosbox
|
||||
*/
|
||||
static char *find_dosbox(void)
|
||||
{
|
||||
const char *envpath = getenv( "PATH" );
|
||||
struct stat st;
|
||||
char *path, *p, *buffer, *dir;
|
||||
|
||||
if (!envpath) return NULL;
|
||||
path = HeapAlloc( GetProcessHeap(), 0, strlen(envpath) );
|
||||
buffer = HeapAlloc( GetProcessHeap(), 0, strlen(path) + sizeof("/dosbox") );
|
||||
strcpy( path, envpath );
|
||||
p = path;
|
||||
while (*p)
|
||||
{
|
||||
while (*p == ':') p++;
|
||||
if (!*p) break;
|
||||
dir = p;
|
||||
while (*p && *p != ':') p++;
|
||||
*p++ = 0;
|
||||
strcpy( buffer, dir );
|
||||
strcat( buffer, "/dosbox" );
|
||||
if (!stat( buffer, &st ))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
HeapFree( GetProcessHeap(), 0, path );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* start_dosbox
|
||||
*/
|
||||
static void start_dosbox( const char *appname, const char *args )
|
||||
{
|
||||
static const WCHAR cfgW[] = {'c','f','g',0};
|
||||
const char *config_dir = wine_get_config_dir();
|
||||
WCHAR path[MAX_PATH], config[MAX_PATH];
|
||||
HANDLE file;
|
||||
char *p, *buffer;
|
||||
int i;
|
||||
int ret = 1;
|
||||
DWORD written, drives = GetLogicalDrives();
|
||||
char *dosbox = find_dosbox();
|
||||
|
||||
if (!dosbox) return;
|
||||
if (!GetTempPathW( MAX_PATH, path )) return;
|
||||
if (!GetTempFileNameW( path, cfgW, 0, config )) return;
|
||||
if (!GetCurrentDirectoryW( MAX_PATH, path )) return;
|
||||
file = CreateFileW( config, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
if (file == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
buffer = HeapAlloc( GetProcessHeap(), 0, sizeof("[autoexec]") +
|
||||
25 * (strlen(config_dir) + sizeof("mount c /dosdevices/c:")) +
|
||||
4 * strlenW( path ) +
|
||||
6 + strlen( appname ) + strlen( args ) + 20 );
|
||||
p = buffer;
|
||||
p += sprintf( p, "[autoexec]\n" );
|
||||
for (i = 0; i < 25; i++)
|
||||
if (drives & (1 << i))
|
||||
p += sprintf( p, "mount %c %s/dosdevices/%c:\n", 'a' + i, config_dir, 'a' + i );
|
||||
p += sprintf( p, "%c:\ncd ", path[0] );
|
||||
p += WideCharToMultiByte( CP_UNIXCP, 0, path + 2, -1, p, 4 * strlenW(path), NULL, NULL ) - 1;
|
||||
p += sprintf( p, "\n%s %s\n", appname, args );
|
||||
p += sprintf( p, "exit\n" );
|
||||
if (WriteFile( file, buffer, strlen(buffer), &written, NULL ) && written == strlen(buffer))
|
||||
{
|
||||
const char *args[4];
|
||||
char *config_file = wine_get_unix_file_name( config );
|
||||
args[0] = dosbox;
|
||||
args[1] = "-conf";
|
||||
args[2] = config_file;
|
||||
args[3] = NULL;
|
||||
ret = spawnvp( _P_WAIT, args[0], args );
|
||||
}
|
||||
CloseHandle( file );
|
||||
DeleteFileW( config );
|
||||
HeapFree( GetProcessHeap(), 0, buffer );
|
||||
ExitProcess( ret );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* start_dos_exe
|
||||
*/
|
||||
|
@ -119,6 +211,8 @@ static void start_dos_exe( LPCSTR filename, LPCSTR cmdline )
|
|||
}
|
||||
else reason = "because the DOS memory range is unavailable";
|
||||
|
||||
start_dosbox( filename, cmdline );
|
||||
|
||||
WINE_MESSAGE( "winevdm: Cannot start DOS application %s\n", filename );
|
||||
WINE_MESSAGE( " %s.\n", reason );
|
||||
WINE_MESSAGE( " Try running this application with DOSBox.\n" );
|
||||
|
|
Loading…
Reference in New Issue