mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-01 13:43:50 +00:00
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
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "wine/port.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "wincon.h"
|
#include "wincon.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(winevdm);
|
WINE_DEFAULT_DEBUG_CHANNEL(winevdm);
|
||||||
|
@ -101,6 +106,93 @@ typedef struct {
|
||||||
|
|
||||||
#include "poppack.h"
|
#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
|
* 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";
|
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( "winevdm: Cannot start DOS application %s\n", filename );
|
||||||
WINE_MESSAGE( " %s.\n", reason );
|
WINE_MESSAGE( " %s.\n", reason );
|
||||||
WINE_MESSAGE( " Try running this application with DOSBox.\n" );
|
WINE_MESSAGE( " Try running this application with DOSBox.\n" );
|
||||||
|
|
Loading…
Reference in a new issue