Exemplo n.º 1
0
static void ensure_drive_c_is_mapped(void)
{
    struct stat buf;
    const char *configdir = wine_get_config_dir();
    int len;
    char *drive_c_dir;
    
    if (drives[2].in_use) return;

    len = snprintf(NULL, 0, "%s/../drive_c", configdir);
    drive_c_dir = HeapAlloc(GetProcessHeap(), 0, len);
    snprintf(drive_c_dir, len, "%s/../drive_c", configdir);
    HeapFree(GetProcessHeap(), 0, drive_c_dir);

    if (stat(drive_c_dir, &buf) == 0)
    {
        WCHAR label[64];
        LoadStringW (GetModuleHandle (NULL), IDS_SYSTEM_DRIVE_LABEL, label,
                     sizeof(label)/sizeof(label[0]));
        add_drive('C', "../drive_c", NULL, label, 0, DRIVE_FIXED);
    }
    else
    {
        report_error(NO_DRIVE_C);
    }
}
Exemplo n.º 2
0
/* inspired by write_desktop_entry() in xdg support code */
static BOOL generate_bundle_script(const char *file, const char *path,
        const char *args, const char *workdir)
{
    FILE *fp;
    const char *libpath;

    WINE_TRACE("Creating Bundle helper script at %s\n", wine_dbgstr_a(file));

    fp = fopen(file, "w");
    if (fp == NULL)
        return FALSE;

    fprintf(fp, "#!/bin/sh\n");

    fprintf(fp, "PATH=\"%s\"\nexport PATH\n", getenv("PATH"));
    libpath = getenv("DYLD_FALLBACK_LIBRARY_PATH");
    if (libpath)
        fprintf(fp, "DYLD_FALLBACK_LIBRARY_PATH=\"%s\"\nexport DYLD_FALLBACK_LIBRARY_PATH\n", libpath);
    fprintf(fp, "WINEPREFIX=\"%s\"\nexport WINEPREFIX\n\n", wine_get_config_dir());

    if (workdir)
        fprintf(fp, "cd \"%s\"\n", workdir);
    fprintf(fp, "exec sh -c \"exec wine %s %s\"\n\n", path, args);

    fprintf(fp, "#EOF\n");

    fclose(fp);
    chmod(file, 0755);

    return TRUE;
}
Exemplo n.º 3
0
/***********************************************************************
 *           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, app[MAX_PATH];
    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;
    if (!GetShortPathNameA( appname, app, MAX_PATH )) return;
    GetShortPathNameW( path, path, MAX_PATH );
    file = CreateFileW( config, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 );
    if (file == INVALID_HANDLE_VALUE) return;

    buffer = HeapAlloc( GetProcessHeap(), 0, sizeof("[autoexec]") +
                        sizeof("mount -z c") + sizeof("config -securemode") +
                        25 * (strlen(config_dir) + sizeof("mount c /dosdevices/c:")) +
                        4 * strlenW( path ) +
                        6 + strlen( app ) + strlen( args ) + 20 );
    p = buffer;
    p += sprintf( p, "[autoexec]\n" );
    for (i = 25; i >= 0; i--)
        if (!(drives & (1 << i)))
        {
            p += sprintf( p, "mount -z %c\n", 'a' + i );
            break;
        }
    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, "\nconfig -securemode\n" );
    p += sprintf( p, "%s %s\n", app, args );
    p += sprintf( p, "exit\n" );
    if (WriteFile( file, buffer, strlen(buffer), &written, NULL ) && written == strlen(buffer))
    {
        const char *args[5];
        char *config_file = wine_get_unix_file_name( config );
        args[0] = dosbox;
        args[1] = "-userconf";
        args[2] = "-conf";
        args[3] = config_file;
        args[4] = NULL;
        ret = _spawnvp( _P_WAIT, args[0], args );
    }
    CloseHandle( file );
    DeleteFileW( config );
    HeapFree( GetProcessHeap(), 0, buffer );
    ExitProcess( ret );
}
Exemplo n.º 4
0
/***********************************************************************
 *           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 (tolower(appname[0]) == 'z')
    {
        WINE_MESSAGE( "winevdm: Cannot start DOS application %s\n", appname );
        WINE_MESSAGE( "         because DOSBox doesn't support running from the Z: drive.\n" );
        ExitProcess(1);
    }
    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 );
}
Exemplo n.º 5
0
static char *get_dosdevices_path(void)
{
    const char *config_dir = wine_get_config_dir();
    size_t len = strlen(config_dir) + sizeof("/dosdevices/a::");
    char *path = HeapAlloc( GetProcessHeap(), 0, len );
    if (path)
    {
        strcpy( path, config_dir );
        strcat( path, "/dosdevices/a::" );
    }
    return path;
}
Exemplo n.º 6
0
/***********************************************************************
 *           setup_config_dir
 *
 * Setup the wine configuration dir.
 */
static void setup_config_dir(void)
{
    const char *p, *config_dir = wine_get_config_dir();

    if (chdir( config_dir ) == -1)
    {
        if (errno != ENOENT) fatal_perror( "chdir to %s\n", config_dir );

        if ((p = strrchr( config_dir, '/' )) && p != config_dir)
        {
            struct stat st;
            char *tmp_dir;

            if (!(tmp_dir = malloc( p + 1 - config_dir ))) fatal_error( "out of memory\n" );
            memcpy( tmp_dir, config_dir, p - config_dir );
            tmp_dir[p - config_dir] = 0;
            if (!stat( tmp_dir, &st ) && st.st_uid != getuid())
                fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
                             tmp_dir );
            free( tmp_dir );
        }

        mkdir( config_dir, 0777 );
        if (chdir( config_dir ) == -1) fatal_perror( "chdir to %s\n", config_dir );

        if ((p = getenv( "WINEARCH" )) && !strcmp( p, "win32" ))
        {
            /* force creation of a 32-bit prefix */
            int fd = open( "system.reg", O_WRONLY | O_CREAT | O_EXCL, 0666 );
            if (fd != -1)
            {
                static const char regfile[] = "WINE REGISTRY Version 2\n\n#arch=win32\n";
                write( fd, regfile, sizeof(regfile) - 1 );
                close( fd );
            }
        }
        MESSAGE( "wine: created the configuration directory '%s'\n", config_dir );
    }

    if (mkdir( "dosdevices", 0777 ) == -1)
    {
        if (errno == EEXIST) return;
        fatal_perror( "cannot create %s/dosdevices\n", config_dir );
    }

    /* create the drive symlinks */

    mkdir( "drive_c", 0777 );
    symlink( "../drive_c", "dosdevices/c:" );
    symlink( "/", "dosdevices/z:" );
}
Exemplo n.º 7
0
/* execute rundll32 on the wine.inf file if necessary */
static void update_wineprefix( int force )
{
    const char *config_dir = wine_get_config_dir();
    char *inf_path = get_wine_inf_path();
    int fd;
    struct stat st;

    if (!inf_path)
    {
        WINE_MESSAGE( "wine: failed to update %s, wine.inf not found\n", config_dir );
        return;
    }
    if ((fd = open( inf_path, O_RDONLY )) == -1)
    {
        WINE_MESSAGE( "wine: failed to update %s with %s: %s\n",
                      config_dir, inf_path, strerror(errno) );
        goto done;
    }
    fstat( fd, &st );
    close( fd );

    if (update_timestamp( config_dir, st.st_mtime ) || force)
    {
        HANDLE process;
        DWORD count = 0;

        if ((process = start_rundll32( inf_path, FALSE )))
        {
            HWND hwnd = show_wait_window();
            for (;;)
            {
                MSG msg;
                DWORD res = MsgWaitForMultipleObjects( 1, &process, FALSE, INFINITE, QS_ALLINPUT );
                if (res == WAIT_OBJECT_0)
                {
                    CloseHandle( process );
                    if (count++ || !(process = start_rundll32( inf_path, TRUE ))) break;
                }
                else while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
            }
            DestroyWindow( hwnd );
        }
        WINE_MESSAGE( "wine: configuration in '%s' has been updated.\n", config_dir );
    }

done:
    HeapFree( GetProcessHeap(), 0, inf_path );
}
Exemplo n.º 8
0
static HWND show_wait_window(void)
{
    const char *config_dir = wine_get_config_dir();
    WCHAR *name;
    HWND hwnd;
    DWORD len;

    len = MultiByteToWideChar( CP_UNIXCP, 0, config_dir, -1, NULL, 0 );
    name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
    MultiByteToWideChar( CP_UNIXCP, 0, config_dir, -1, name, len );
    hwnd = CreateDialogParamW( GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_WAITDLG), 0,
                               wait_dlgproc, (LPARAM)name );
    ShowWindow( hwnd, SW_SHOWNORMAL );
    HeapFree( GetProcessHeap(), 0, name );
    return hwnd;
}
Exemplo n.º 9
0
/***********************************************************************
 *           setup_config_dir
 *
 * Setup the wine configuration dir.
 */
static void setup_config_dir(void)
{
    const char *p, *config_dir = wine_get_config_dir();

    if (chdir( config_dir ) == -1)
    {
        if (errno != ENOENT) fatal_perror( "chdir to %s\n", config_dir );

        if ((p = strrchr( config_dir, '/' )) && p != config_dir)
        {
            struct stat st;
            char *tmp_dir;

            if (!(tmp_dir = malloc( p + 1 - config_dir ))) fatal_error( "out of memory\n" );
            memcpy( tmp_dir, config_dir, p - config_dir );
            tmp_dir[p - config_dir] = 0;
            if (!stat( tmp_dir, &st ) && st.st_uid != getuid())
                fatal_error( "'%s' is not owned by you, refusing to create a configuration directory there\n",
                             tmp_dir );
            free( tmp_dir );
        }

        mkdir( config_dir, 0777 );
        if (chdir( config_dir ) == -1) fatal_perror( "chdir to %s\n", config_dir );
        MESSAGE( "wine: created the configuration directory '%s'\n", config_dir );
    }

    if (mkdir( "dosdevices", 0777 ) == -1)
    {
        if (errno == EEXIST) return;
        fatal_perror( "cannot create %s/dosdevices\n", config_dir );
    }

    /* create the drive symlinks */

    mkdir( "drive_c", 0777 );
    symlink( "../drive_c", "dosdevices/c:" );
    symlink( "/", "dosdevices/z:" );
}
Exemplo n.º 10
0
/***********************************************************************
 *           server_init_thread
 *
 * Send an init thread request. Return 0 if OK.
 */
size_t server_init_thread( void *entry_point )
{
    static const int is_win64 = (sizeof(void *) > sizeof(int));
    const char *arch = getenv( "WINEARCH" );
    int ret;
    int reply_pipe[2];
    struct sigaction sig_act;
    size_t info_size;

    sig_act.sa_handler = SIG_IGN;
    sig_act.sa_flags   = 0;
    sigemptyset( &sig_act.sa_mask );

    /* ignore SIGPIPE so that we get an EPIPE error instead  */
    sigaction( SIGPIPE, &sig_act, NULL );

    /* create the server->client communication pipes */
    if (server_pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
    if (server_pipe( ntdll_get_thread_data()->wait_fd ) == -1) server_protocol_perror( "pipe" );
    wine_server_send_fd( reply_pipe[1] );
    wine_server_send_fd( ntdll_get_thread_data()->wait_fd[1] );
    ntdll_get_thread_data()->reply_fd = reply_pipe[0];
    close( reply_pipe[1] );

    SERVER_START_REQ( init_thread )
    {
        req->unix_pid    = getpid();
        req->unix_tid    = get_unix_tid();
        req->teb         = wine_server_client_ptr( NtCurrentTeb() );
        req->entry       = wine_server_client_ptr( entry_point );
        req->reply_fd    = reply_pipe[1];
        req->wait_fd     = ntdll_get_thread_data()->wait_fd[1];
        req->debug_level = (TRACE_ON(server) != 0);
        req->cpu         = client_cpu;
        ret = wine_server_call( req );
        NtCurrentTeb()->ClientId.UniqueProcess = ULongToHandle(reply->pid);
        NtCurrentTeb()->ClientId.UniqueThread  = ULongToHandle(reply->tid);
        info_size         = reply->info_size;
        server_start_time = reply->server_start;
        server_cpus       = reply->all_cpus;
    }
    SERVER_END_REQ;

    is_wow64 = !is_win64 && (server_cpus & (1 << CPU_x86_64)) != 0;
    ntdll_get_thread_data()->wow64_redir = is_wow64;

    switch (ret)
    {
    case STATUS_SUCCESS:
        if (arch)
        {
            if (!strcmp( arch, "win32" ) && (is_win64 || is_wow64))
                fatal_error( "WINEARCH set to win32 but '%s' is a 64-bit installation.\n",
                             wine_get_config_dir() );
            if (!strcmp( arch, "win64" ) && !is_win64 && !is_wow64)
                fatal_error( "WINEARCH set to win64 but '%s' is a 32-bit installation.\n",
                             wine_get_config_dir() );
        }
        return info_size;
    case STATUS_NOT_REGISTRY_FILE:
        fatal_error( "'%s' is a 32-bit installation, it cannot support 64-bit applications.\n",
                     wine_get_config_dir() );
    case STATUS_NOT_SUPPORTED:
        if (is_win64)
            fatal_error( "wineserver is 32-bit, it cannot support 64-bit applications.\n" );
        else
            fatal_error( "'%s' is a 64-bit installation, it cannot be used with a 32-bit wineserver.\n",
                         wine_get_config_dir() );
    default:
        server_protocol_error( "init_thread failed with status %x\n", ret );
    }
}
Exemplo n.º 11
0
/* open the master server socket and start waiting for new clients */
void open_master_socket(void)
{
    const char *server_dir = wine_get_server_dir();
    const char *config_dir = wine_get_config_dir();
    int fd, pid, status, sync_pipe[2];
    char dummy;

    /* make sure no request is larger than the maximum size */
    assert( sizeof(union generic_request) == sizeof(struct request_max_size) );
    assert( sizeof(union generic_reply) == sizeof(struct request_max_size) );

    /* make sure the stdio fds are open */
    fd = open( "/dev/null", O_RDWR );
    while (fd >= 0 && fd <= 2) fd = dup( fd );

    if (!server_dir) fatal_error( "directory %s cannot be accessed\n", config_dir );
    if (chdir( config_dir ) == -1) fatal_perror( "chdir to %s", config_dir );
    if ((config_dir_fd = open( ".", O_RDONLY )) == -1) fatal_perror( "open %s", config_dir );

    create_server_dir( server_dir );

    if (!foreground)
    {
        if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" );
        pid = fork();
        switch( pid )
        {
        case 0:  /* child */
            setsid();
            close( sync_pipe[0] );

            acquire_lock();

            /* close stdin and stdout */
            dup2( fd, 0 );
            dup2( fd, 1 );

            /* signal parent */
            dummy = 0;
            write( sync_pipe[1], &dummy, 1 );
            close( sync_pipe[1] );
            break;

        case -1:
            fatal_perror( "fork" );
            break;

        default:  /* parent */
            close( sync_pipe[1] );

            /* wait for child to signal us and then exit */
            if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0);

            /* child terminated, propagate exit status */
            waitpid( pid, &status, 0 );
            if (WIFEXITED(status)) _exit( WEXITSTATUS(status) );
            _exit(1);
        }
    }
    else  /* remain in the foreground */
    {
        acquire_lock();
    }

    /* init the process tracing mechanism */
    init_tracing_mechanism();
    close( fd );
}
Exemplo n.º 12
0
/* open the master server socket and start waiting for new clients */
void open_master_socket(void)
{
    const char *server_dir = wine_get_server_dir();
    int fd, pid, status, sync_pipe[2];
    char dummy;

    /* make sure no request is larger than the maximum size */
    assert( sizeof(union generic_request) == sizeof(struct request_max_size) );
    assert( sizeof(union generic_reply) == sizeof(struct request_max_size) );

    if (!server_dir) fatal_error( "directory %s cannot be accessed\n", wine_get_config_dir() );
    create_server_dir( server_dir );

    if (!foreground)
    {
        if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" );
        pid = fork();
        switch( pid )
        {
        case 0:  /* child */
            setsid();
            close( sync_pipe[0] );

            acquire_lock();

            /* close stdin and stdout */
            if ((fd = open( "/dev/null", O_RDWR )) != -1)
            {
                dup2( fd, 0 );
                dup2( fd, 1 );
                close( fd );
            }

            /* signal parent */
            dummy = 0;
            write( sync_pipe[1], &dummy, 1 );
            close( sync_pipe[1] );
            break;

        case -1:
            fatal_perror( "fork" );
            break;

        default:  /* parent */
            close( sync_pipe[1] );

            /* wait for child to signal us and then exit */
            if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0);

            /* child terminated, propagate exit status */
            wait4( pid, &status, 0, NULL );
            if (WIFEXITED(status)) _exit( WEXITSTATUS(status) );
            _exit(1);
        }
    }
    else  /* remain in the foreground */
    {
        acquire_lock();
    }

    /* setup msghdr structure constant fields */
    msghdr.msg_name    = NULL;
    msghdr.msg_namelen = 0;
    msghdr.msg_iov     = &myiovec;
    msghdr.msg_iovlen  = 1;

    /* init startup time */
    gettimeofday( &server_start_time, NULL );
}