Ejemplo n.º 1
0
static xmlParserInputPtr external_entity_loader(const char *URL, const char *ID,
                                                xmlParserCtxtPtr ctxt)
{
    xmlParserInputPtr input;

    TRACE("(%s, %s, %p)\n", wine_dbgstr_a(URL), wine_dbgstr_a(ID), ctxt);

    assert(MSXML_hInstance != NULL);
    assert(datatypes_rsrc != NULL);
    assert(datatypes_handle != NULL);
    assert(datatypes_src != NULL);

    /* TODO: if the desired schema is in the cache, load it from there */
    if (lstrcmpA(URL, "urn:schemas-microsoft-com:datatypes") == 0)
    {
        TRACE("loading built-in schema for %s\n", URL);
        input = xmlNewStringInputStream(ctxt, datatypes_src);
    }
    else
    {
        input = _external_entity_loader(URL, ID, ctxt);
    }

    return input;
}
Ejemplo n.º 2
0
/* try to launch a unix app from a comma separated string of app names */
static int launch_app( WCHAR *candidates, const WCHAR *argv1 )
{
    char *app, *applist, *cmdline;
    const char *argv_new[3];

    if (!(applist = strdup_unixcp( candidates ))) return 1;
    if (!(cmdline = strdup_unixcp( argv1 )))
    {
        HeapFree( GetProcessHeap(), 0, applist );
        return 1;
    }
    app = strtok( applist, "," );
    while (app)
    {
        WINE_TRACE( "Considering: %s\n", wine_dbgstr_a(app) );
        WINE_TRACE( "argv[1]: %s\n", wine_dbgstr_a(cmdline) );

        argv_new[0] = app;
        argv_new[1] = cmdline;
        argv_new[2] = NULL;

        _spawnvp( _P_OVERLAY, app, argv_new );  /* only returns on error */
        app = strtok( NULL, "," );  /* grab the next app */
    }
    WINE_ERR( "could not find a suitable app to run\n" );

    HeapFree( GetProcessHeap(), 0, applist );
    HeapFree( GetProcessHeap(), 0, cmdline );
    return 1;
}
Ejemplo n.º 3
0
/***********************************************************************
 *              pif_cmd
 *
 * execute a pif file.
 */
static VOID pif_cmd( char *filename, char *cmdline)
{ 
    HANDLE hFile;
    char progpath[MAX_PATH];
    char buf[128];
    char progname[64];
    char title[31];
    char optparams[65];
    char startdir[65];
    char *p;
    int closeonexit;
    int textmode;
    if( (hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ,
                    NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
    {
        WINE_ERR("open file %s failed\n", wine_dbgstr_a(filename));
        return;
    }
    if( !read_pif_file( hFile, progname, title, optparams, startdir,
                &closeonexit, &textmode)) {
        WINE_ERR( "failed to read %s\n", wine_dbgstr_a(filename));
        CloseHandle( hFile);
        sprintf( buf, "%s\nInvalid file format. Check your pif file.", 
                filename);
        MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONWARNING);
        SetLastError( ERROR_BAD_FORMAT);
        return;
    }
    CloseHandle( hFile);
    if( (p = strrchr( progname, '.')) && !strcasecmp( p, ".bat"))
        WINE_FIXME(".bat programs in pif files are not supported.\n"); 
    /* first change dir, so the search below can start from there */
    if( startdir[0] && !SetCurrentDirectoryA( startdir)) {
        WINE_ERR("Cannot change directory %s\n", wine_dbgstr_a( startdir));
        sprintf( buf, "%s\nInvalid startup directory. Check your pif file.", 
                filename);
        MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONWARNING);
    }
    /* search for the program */
    if( !SearchPathA( NULL, progname, NULL, MAX_PATH, progpath, NULL )) {
        sprintf( buf, "%s\nInvalid program file name. Check your pif file.", 
                filename);
        MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONERROR);
        SetLastError( ERROR_FILE_NOT_FOUND);
        return;
    }
    if( textmode)
        if( AllocConsole())
            SetConsoleTitleA( title) ;
    /* if no arguments on the commandline, use them from the pif file */
    if( !cmdline[0] && optparams[0])
        cmdline = optparams;
    /* FIXME: do something with:
     * - close on exit
     * - graphic modes
     * - hot key's
     * - etc.
     */ 
    start_dos_exe( progpath, cmdline );
}
Ejemplo n.º 4
0
/* HAL callback for property changes */
static void hal_property_modified (LibHalContext *ctx, const char *udi,
                                   const char *key, dbus_bool_t is_removed, dbus_bool_t is_added)
{
    TRACE( "udi %s key %s %s\n", wine_dbgstr_a(udi), wine_dbgstr_a(key),
           is_added ? "added" : is_removed ? "removed" : "modified" );

    if (!strcmp( key, "volume.mount_point" )) hal_new_device( ctx, udi );
}
Ejemplo n.º 5
0
static DBusHandlerResult udisks_filter( DBusConnection *ctx, DBusMessage *msg, void *user_data )
{
    char *path;
    DBusError error;

    p_dbus_error_init( &error );

    /* udisks signals */
    if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceAdded" ) &&
        p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_new_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceRemoved" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_removed_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.UDisks", "DeviceChanged" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_changed_device( path );
    }
    /* udisks2 signals */
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        TRACE( "added %s\n", wine_dbgstr_a(path) );
        udisks2_add_devices( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved" ) &&
             p_dbus_message_get_args( msg, &error, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID ))
    {
        udisks_removed_device( path );
    }
    else if (p_dbus_message_is_signal( msg, "org.freedesktop.DBus.Properties", "PropertiesChanged" ))
    {
        const char *udi = p_dbus_message_get_path( msg );
        TRACE( "changed %s\n", wine_dbgstr_a(udi) );
        udisks2_add_devices( udi );
    }
    else TRACE( "ignoring message type=%d path=%s interface=%s method=%s\n",
                p_dbus_message_get_type( msg ), p_dbus_message_get_path( msg ),
                p_dbus_message_get_interface( msg ), p_dbus_message_get_member( msg ) );

    p_dbus_error_free( &error );
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
Archivo: main.c Proyecto: AndreRH/wine
/* try to launch a unix app from a comma separated string of app names */
static int launch_app( const WCHAR *candidates, const WCHAR *argv1 )
{
    char *cmdline;
    int i, count;
    char **argv_new;

    if (!(cmdline = strdup_unixcp( argv1 ))) return 1;

    while (*candidates)
    {
        WCHAR **args = CommandLineToArgvW( candidates, &count );

        if (!(argv_new = HeapAlloc( GetProcessHeap(), 0, (count + 2) * sizeof(*argv_new) ))) break;
        for (i = 0; i < count; i++) argv_new[i] = strdup_unixcp( args[i] );
        argv_new[count] = cmdline;
        argv_new[count + 1] = NULL;

        TRACE( "Trying" );
        for (i = 0; i <= count; i++) TRACE( " %s", wine_dbgstr_a( argv_new[i] ));
        TRACE( "\n" );

        _spawnvp( _P_OVERLAY, argv_new[0], (const char **)argv_new );  /* only returns on error */
        for (i = 0; i < count; i++) HeapFree( GetProcessHeap(), 0, argv_new[i] );
        HeapFree( GetProcessHeap(), 0, argv_new );
        candidates += strlenW( candidates ) + 1;  /* grab the next app */
    }
    WINE_ERR( "could not find a suitable app to open %s\n", debugstr_w( argv1 ));

    HeapFree( GetProcessHeap(), 0, cmdline );
    return 1;
}
Ejemplo n.º 8
0
Archivo: schema.c Proyecto: r6144/wine
static cache_entry* cache_entry_from_url(char const* url)
{
    cache_entry* entry = heap_alloc(sizeof(cache_entry));
    xmlSchemaParserCtxtPtr spctx = xmlSchemaNewParserCtxt(url);
    entry->type = SCHEMA_TYPE_XSD;
    entry->ref = 0;
    if (spctx)
    {
        if((entry->schema = xmlSchemaParse(spctx)))
        {
            xmldoc_init(entry->schema->doc, &CLSID_DOMDocument40);
            entry->doc = entry->schema->doc;
            xmldoc_add_ref(entry->doc);
        }
        else
        {
            heap_free(entry);
            entry = NULL;
        }
        xmlSchemaFreeParserCtxt(spctx);
    }
    else
    {
        FIXME("schema for nsURI %s not found\n", wine_dbgstr_a(url));
        heap_free(entry);
        entry = NULL;
    }
    return entry;
}
Ejemplo n.º 9
0
static void add_dos_device( const char *udi, const char *device,
                            const char *mount_point, const char *type )
{
    struct dos_drive *drive;

    /* first check if it already exists */
    LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
    {
        if (!strcmp( udi, drive->udi )) goto found;
    }

    if (!(drive = HeapAlloc( GetProcessHeap(), 0, sizeof(*drive) ))) return;
    if (!(drive->udi = HeapAlloc( GetProcessHeap(), 0, strlen(udi)+1 )))
    {
        HeapFree( GetProcessHeap(), 0, drive );
        return;
    }
    strcpy( drive->udi, udi );
    list_add_tail( &drives_list, &drive->entry );

found:
    drive->drive = add_drive( device, type );
    if (drive->drive != -1)
    {
        HKEY hkey;

        set_mount_point( drive, mount_point );

        WINE_TRACE( "added device %c: udi %s for %s on %s type %s\n",
                    'a' + drive->drive, wine_dbgstr_a(udi), wine_dbgstr_a(device),
                    wine_dbgstr_a(mount_point), wine_dbgstr_a(type) );

        /* hack: force the drive type in the registry */
        if (!RegCreateKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Drives", &hkey ))
        {
            char name[3] = "a:";
            name[0] += drive->drive;
            if (!type || strcmp( type, "cdrom" )) type = "floppy";  /* FIXME: default to floppy */
            RegSetValueExA( hkey, name, 0, REG_SZ, (const BYTE *)type, strlen(type) + 1 );
            RegCloseKey( hkey );
        }

        send_notify( drive->drive, DBT_DEVICEARRIVAL );
    }
}
Ejemplo n.º 10
0
HRESULT WINAPI D3D10CompileEffectFromMemory(void *data, SIZE_T data_size, const char *filename,
        const D3D10_SHADER_MACRO *defines, ID3D10Include *include, UINT hlsl_flags, UINT fx_flags,
        ID3D10Blob **effect, ID3D10Blob **errors)
{
    TRACE("data %p, data_size %lu, filename %s, defines %p, include %p, "
            "hlsl_flags %#x, fx_flags %#x, effect %p, errors %p.\n",
            data, data_size, wine_dbgstr_a(filename), defines, include,
            hlsl_flags, fx_flags, effect, errors);

    return D3DCompile(data, data_size, filename, defines, include,
            NULL, "fx_4_0", hlsl_flags, fx_flags, effect, errors);
}
Ejemplo n.º 11
0
static IUri *convert_file_uri(IUri *uri)
{
    wine_get_unix_file_name_t wine_get_unix_file_name_ptr;
    IUriBuilder *uri_builder;
    struct stat dummy;
    WCHAR *new_path;
    char *unixpath;
    BSTR filename;
    IUri *new_uri;
    HRESULT hres;

    /* check if the argument is a local file */
    wine_get_unix_file_name_ptr = (wine_get_unix_file_name_t)
           GetProcAddress( GetModuleHandleA( "KERNEL32" ), "wine_get_unix_file_name" );
    if(!wine_get_unix_file_name_ptr)
        return NULL;

    hres = IUri_GetPath(uri, &filename);
    if(FAILED(hres))
        return NULL;

    unixpath = wine_get_unix_file_name_ptr(filename);
    SysFreeString(filename);
    if(unixpath && stat(unixpath, &dummy) >= 0) {
        int len;

        len = MultiByteToWideChar(CP_UNIXCP, 0, unixpath, -1, NULL, 0);
        new_path = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
        if(new_path)
            MultiByteToWideChar(CP_UNIXCP, 0, unixpath, -1, new_path, len);
        HeapFree(GetProcessHeap(), 0, unixpath);
    }else {
        WINE_WARN("File %s does not exist\n", wine_dbgstr_a(unixpath));
        HeapFree(GetProcessHeap(), 0, unixpath);
        new_path = NULL;
    }

    hres = CreateIUriBuilder(uri, 0, 0, &uri_builder);
    if(SUCCEEDED(hres) && new_path)
        hres = IUriBuilder_SetPath(uri_builder, new_path);
    HeapFree(GetProcessHeap(), 0, new_path);
    if(FAILED(hres))
        return NULL;

    hres = IUriBuilder_CreateUri(uri_builder, 0, 0, 0, &new_uri);
    IUriBuilder_Release(uri_builder);
    if(FAILED(hres))
        return NULL;

    return new_uri;
}
Ejemplo n.º 12
0
/* HAL callback for removed device */
static void hal_removed_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;

    TRACE( "removed %s\n", wine_dbgstr_a(udi) );

    if (!remove_dos_device( -1, udi ))
    {
        p_dbus_error_init( &error );
        p_libhal_device_remove_property_watch( ctx, udi, &error );
        p_dbus_error_free( &error );
    }
    else remove_volume( udi );
}
BOOL add_drive(char letter, const char *targetpath, const char *device, const WCHAR *label,
               DWORD serial, DWORD type)
{
    int driveIndex = letter_to_index(letter);

    if(drives[driveIndex].in_use)
        return FALSE;

    WINE_TRACE("letter == '%c', unixpath == %s, device == %s, label == %s, serial == %08x, type == %d\n",
               letter, wine_dbgstr_a(targetpath), wine_dbgstr_a(device),
               wine_dbgstr_w(label), serial, type);

    drives[driveIndex].letter   = toupper(letter);
    drives[driveIndex].unixpath = targetpath ? strdupA(targetpath) : NULL;
    drives[driveIndex].device   = device ? strdupA(device) : NULL;
    drives[driveIndex].label    = label ? strdupW(label) : NULL;
    drives[driveIndex].serial   = serial;
    drives[driveIndex].type     = type;
    drives[driveIndex].in_use   = TRUE;
    drives[driveIndex].modified = TRUE;

    return TRUE;
}
Ejemplo n.º 14
0
static HANDLE CALLBACK WHD_Open(LPSTR name, BYTE flags)
{
    unsigned    mode = 0;

    WINE_FIXME("(%s %x)\n", wine_dbgstr_a(name), flags);
    switch (flags)
    {
    case 0: mode = GENERIC_READ | GENERIC_WRITE; break;
    case 2: mode = GENERIC_READ; break;
    default: WINE_FIXME("Undocumented flags %x\n", flags);
    }
    return CreateFile(name, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
Ejemplo n.º 15
0
Archivo: main.c Proyecto: AndreRH/wine
static WCHAR *convert_file_uri(IUri *uri)
{
    wine_get_unix_file_name_t wine_get_unix_file_name_ptr;
    struct stat dummy;
    WCHAR *new_path;
    char *unixpath;
    BSTR filename;
    HRESULT hres;

    /* check if the argument is a local file */
    wine_get_unix_file_name_ptr = (wine_get_unix_file_name_t)
           GetProcAddress( GetModuleHandleA( "KERNEL32" ), "wine_get_unix_file_name" );
    if(!wine_get_unix_file_name_ptr)
        return NULL;

    hres = IUri_GetPath(uri, &filename);
    if(FAILED(hres))
        return NULL;

    WINE_TRACE("Windows path: %s\n", wine_dbgstr_w(filename));

    unixpath = wine_get_unix_file_name_ptr(filename);
    SysFreeString(filename);
    if(unixpath && stat(unixpath, &dummy) >= 0) {
        WINE_TRACE("Unix path: %s\n", wine_dbgstr_a(unixpath));
        new_path = encode_unix_path(unixpath);
        HeapFree(GetProcessHeap(), 0, unixpath);
    }else {
        WINE_WARN("File %s does not exist\n", wine_dbgstr_a(unixpath));
        HeapFree(GetProcessHeap(), 0, unixpath);
        new_path = NULL;
    }

    WINE_TRACE("New path: %s\n", wine_dbgstr_w(new_path));

    return new_path;
}
Ejemplo n.º 16
0
/*************************************************************************
 * AddERExcludedApplicationA  [FAULTREP.@]
 *
 * See AddERExcludedApplicationW
 */
BOOL WINAPI AddERExcludedApplicationA(LPCSTR lpAppFileName)
{
    int len = MultiByteToWideChar(CP_ACP, 0, lpAppFileName, -1, NULL, 0);
    WCHAR *wstr;
    BOOL ret;

    TRACE("(%s)\n", wine_dbgstr_a(lpAppFileName));
    if (len == 0)
        return FALSE;
    wstr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
    MultiByteToWideChar(CP_ACP, 0, lpAppFileName, -1, wstr, len);
    ret = AddERExcludedApplicationW(wstr);
    HeapFree(GetProcessHeap(), 0, wstr);
    return ret;
}
Ejemplo n.º 17
0
HRESULT WINAPI D3D10CompileEffectFromMemory(void *data, SIZE_T data_size, const char *filename,
        const D3D10_SHADER_MACRO *defines, ID3D10Include *include, UINT hlsl_flags, UINT fx_flags,
        ID3D10Blob **effect, ID3D10Blob **errors)
{
    FIXME("data %p, data_size %lu, filename %s, defines %p, include %p,"
            " hlsl_flags %#x, fx_flags %#x, effect %p, errors %p stub!\n",
            data, data_size, wine_dbgstr_a(filename), defines, include,
            hlsl_flags, fx_flags, effect, errors);

    if (effect)
        *effect = NULL;
    if (errors)
        *errors = NULL;

    return E_NOTIMPL;
}
Ejemplo n.º 18
0
/* HAL callback for removed device */
static void removed_device( LibHalContext *ctx, const char *udi )
{
    DBusError error;
    struct dos_drive *drive;

    WINE_TRACE( "removed %s\n", wine_dbgstr_a(udi) );

    LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry )
    {
        if (strcmp( udi, drive->udi )) continue;
        p_dbus_error_init( &error );
        p_libhal_device_remove_property_watch( ctx, udi, &error );
        remove_dos_device( drive );
        p_dbus_error_free( &error );
        return;
    }
}
Ejemplo n.º 19
0
static int new_cabinet( char *cab_dir )
{
    static const WCHAR plusW[] = {'+',0};
    WCHAR **file;
    ERF erf;
    BOOL ret = FALSE;
    HFCI fci;
    CCAB cab;

    cab.cb                = opt_cabinet_size;
    cab.cbFolderThresh    = CB_MAX_DISK;
    cab.cbReserveCFHeader = opt_reserve_space;
    cab.cbReserveCFFolder = 0;
    cab.cbReserveCFData   = 0;
    cab.iCab              = 0;
    cab.iDisk             = 0;
    cab.setID             = opt_cabinet_id;
    cab.szDisk[0]         = 0;

    strcpy( cab.szCabPath, cab_dir );
    strcat( cab.szCabPath, "\\" );
    format_cab_name( cab.szCab, 1, opt_cab_file );

    fci = FCICreate( &erf, fci_file_placed, cab_alloc, cab_free,fci_open, fci_read,
                     fci_write, fci_close, fci_lseek, fci_delete, fci_get_temp, &cab, NULL );

    for (file = opt_files; *file; file++)
    {
        if (!strcmpW( *file, plusW ))
            FCIFlushFolder( fci, fci_get_next_cab, fci_status );
        else
            if (!(ret = add_file_or_directory( fci, *file ))) break;
    }

    if (ret)
    {
        if (!(ret = FCIFlushCabinet( fci, FALSE, fci_get_next_cab, fci_status )))
            WINE_MESSAGE( "cabarc: Failed to create cabinet %s\n", wine_dbgstr_a(opt_cab_file) );
    }
    FCIDestroy( fci );
    return !ret;
}
Ejemplo n.º 20
0
static BOOL get_display_device_reg_key(char *key, unsigned len)
{
    static const char display_device_guid_prop[] = "__wine_display_device_guid";
    static const char video_path[] = "System\\CurrentControlSet\\Control\\Video\\{";
    static const char display0[] = "}\\0000";
    ATOM guid_atom;

    assert(len >= sizeof(video_path) + sizeof(display0) + 40);

    guid_atom = HandleToULong(GetPropA(GetDesktopWindow(), display_device_guid_prop));
    if (!guid_atom) return FALSE;

    memcpy(key, video_path, sizeof(video_path));

    if (!GlobalGetAtomNameA(guid_atom, key + strlen(key), 40))
        return FALSE;

    strcat(key, display0);

    TRACE("display device key %s\n", wine_dbgstr_a(key));
    return TRUE;
}
Ejemplo n.º 21
0
static HANDLE RPCSS_NPConnect(void)
{
  HANDLE the_pipe;
  DWORD dwmode, wait_result;
  HANDLE master_mutex = RPCSS_GetMasterMutex();
  
  WINE_TRACE("\n");

  while (TRUE) {

    wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT);
    switch (wait_result) {
      case WAIT_ABANDONED: 
      case WAIT_OBJECT_0:
        break;
      case WAIT_FAILED:
      case WAIT_TIMEOUT:
      default: 
        WINE_ERR("This should never happen: couldn't enter mutex.\n");
        return NULL;
    }

    /* try to open the client side of the named pipe. */
    the_pipe = CreateFileA(
      NAME_RPCSS_NAMED_PIPE,           /* pipe name */
      GENERIC_READ | GENERIC_WRITE,    /* r/w access */
      0,                               /* no sharing */
      NULL,                            /* no security attributes */
      OPEN_EXISTING,                   /* open an existing pipe */
      0,                               /* default attributes */
      NULL                             /* no template file */
    );

    if (the_pipe != INVALID_HANDLE_VALUE)
      break;

    if (GetLastError() != ERROR_PIPE_BUSY) {
      WINE_WARN("Unable to open named pipe %s (assuming unavailable).\n", 
        wine_dbgstr_a(NAME_RPCSS_NAMED_PIPE));
      break;
    }

    WINE_WARN("Named pipe busy (will wait)\n");
    
    if (!ReleaseMutex(master_mutex))
      WINE_ERR("Failed to release master mutex.  Expect deadlock.\n");

    /* wait for the named pipe.  We are only 
       willing to wait only 5 seconds.  It should be available /very/ soon. */
    if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT))
    {
      WINE_ERR("Named pipe unavailable after waiting.  Something is probably wrong.\n");
      return NULL;
    }

  }

  if (the_pipe != INVALID_HANDLE_VALUE) {
    dwmode = PIPE_READMODE_MESSAGE;
    /* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */
    if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL))
      WINE_WARN("Failed to set pipe handle state\n");
  }

  if (!ReleaseMutex(master_mutex))
    WINE_ERR("Uh oh, failed to leave the RPC Master Mutex!\n");

  return the_pipe;
}
Ejemplo n.º 22
0
HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out)
{
    domselection *This = heap_alloc(sizeof(domselection));
    xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc);
    HRESULT hr;

    TRACE("(%p, %s, %p)\n", node, wine_dbgstr_a((char const*)query), out);

    *out = NULL;
    if (!This || !ctxt || !query)
    {
        xmlXPathFreeContext(ctxt);
        heap_free(This);
        return E_OUTOFMEMORY;
    }

    This->IXMLDOMSelection_iface.lpVtbl = &domselection_vtbl;
    This->ref = 1;
    This->resultPos = 0;
    This->node = node;
    This->enumvariant = NULL;
    init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMSelection_iface, &domselection_dispex);
    xmldoc_add_ref(This->node->doc);

    ctxt->error = query_serror;
    ctxt->node = node;
    registerNamespaces(ctxt);

    if (is_xpathmode(This->node->doc))
    {
        xmlXPathRegisterAllFunctions(ctxt);
        This->result = xmlXPathEvalExpression(query, ctxt);
    }
    else
    {
        xmlChar* pattern_query = XSLPattern_to_XPath(ctxt, query);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"not", xmlXPathNotFunction);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"boolean", xmlXPathBooleanFunction);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"index", XSLPattern_index);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"end", XSLPattern_end);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"nodeType", XSLPattern_nodeType);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IEq", XSLPattern_OP_IEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_INEq", XSLPattern_OP_INEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILt", XSLPattern_OP_ILt);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILEq", XSLPattern_OP_ILEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGt", XSLPattern_OP_IGt);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGEq", XSLPattern_OP_IGEq);

        This->result = xmlXPathEvalExpression(pattern_query, ctxt);
        xmlFree(pattern_query);
    }

    if (!This->result || This->result->type != XPATH_NODESET)
    {
        hr = E_FAIL;
        goto cleanup;
    }

    *out = (IXMLDOMNodeList*)&This->IXMLDOMSelection_iface;
    hr = S_OK;
    TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval));

cleanup:
    if (This && FAILED(hr))
        IXMLDOMSelection_Release( &This->IXMLDOMSelection_iface );
    xmlXPathFreeContext(ctxt);
    return hr;
}
Ejemplo n.º 23
0
HRESULT queryresult_create(xmlNodePtr node, xmlChar* szQuery, IXMLDOMNodeList **out)
{
    queryresult *This = heap_alloc_zero(sizeof(queryresult));
    xmlXPathContextPtr ctxt = xmlXPathNewContext(node->doc);
    HRESULT hr;

    TRACE("(%p, %s, %p)\n", node, wine_dbgstr_a((char const*)szQuery), out);

    *out = NULL;
    if (This == NULL || ctxt == NULL || szQuery == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto cleanup;
    }

    This->lpVtbl = &queryresult_vtbl;
    This->ref = 1;
    This->resultPos = 0;
    This->node = node;
    xmldoc_add_ref(This->node->doc);

    ctxt->error = query_serror;
    ctxt->node = node;
    registerNamespaces(ctxt);

    if (is_xpathmode(This->node->doc))
    {
        xmlXPathRegisterAllFunctions(ctxt);
        This->result = xmlXPathEvalExpression(szQuery, ctxt);
    }
    else
    {
        xmlChar* xslpQuery = XSLPattern_to_XPath(ctxt, szQuery);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"not", xmlXPathNotFunction);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"boolean", xmlXPathBooleanFunction);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"index", XSLPattern_index);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"end", XSLPattern_end);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"nodeType", XSLPattern_nodeType);

        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IEq", XSLPattern_OP_IEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_INEq", XSLPattern_OP_INEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILt", XSLPattern_OP_ILt);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_ILEq", XSLPattern_OP_ILEq);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGt", XSLPattern_OP_IGt);
        xmlXPathRegisterFunc(ctxt, (xmlChar const*)"OP_IGEq", XSLPattern_OP_IGEq);

        This->result = xmlXPathEvalExpression(xslpQuery, ctxt);
        xmlFree(xslpQuery);
    }

    if (!This->result || This->result->type != XPATH_NODESET)
    {
        hr = E_FAIL;
        goto cleanup;
    }

    init_dispex(&This->dispex, (IUnknown*)&This->lpVtbl, &queryresult_dispex);

    *out = (IXMLDOMNodeList *) &This->lpVtbl;
    hr = S_OK;
    TRACE("found %d matches\n", xmlXPathNodeSetGetLength(This->result->nodesetval));

cleanup:
    if (This != NULL && FAILED(hr))
        IXMLDOMNodeList_Release( (IXMLDOMNodeList*) &This->lpVtbl );
    xmlXPathFreeContext(ctxt);
    return hr;
}
/* some of this code appears to be broken by bugs in Wine: the label
 * setting code has no effect, for instance  */
void apply_drive_changes(void)
{
    int i;
    HANDLE mgr;
    DWORD len;
    struct mountmgr_unix_drive *ioctl;

    WINE_TRACE("\n");

    if ((mgr = open_mountmgr()) == INVALID_HANDLE_VALUE) return;

    /* add each drive and remove as we go */
    for(i = 0; i < 26; i++)
    {
        if (!drives[i].modified) continue;
        drives[i].modified = FALSE;

        len = sizeof(*ioctl);
        if (drives[i].in_use)
        {
            if (drives[i].unixpath) len += strlen(drives[i].unixpath) + 1;
            if (drives[i].device) len += strlen(drives[i].device) + 1;
        }
        if (!(ioctl = HeapAlloc( GetProcessHeap(), 0, len ))) continue;
        ioctl->size = len;
        ioctl->type = DRIVE_NO_ROOT_DIR;
        ioctl->letter = 'a' + i;
        ioctl->mount_point_offset = 0;
        ioctl->device_offset = 0;
        if (drives[i].in_use)
        {
            char *ptr = (char *)(ioctl + 1);

            ioctl->type = drives[i].type;
            if (drives[i].unixpath)
            {
                strcpy( ptr, drives[i].unixpath );
                ioctl->mount_point_offset = ptr - (char *)ioctl;
                ptr += strlen(ptr) + 1;
            }

            if (drives[i].device)
            {
                strcpy( ptr, drives[i].device );
                ioctl->device_offset = ptr - (char *)ioctl;
            }
        }

        if (DeviceIoControl( mgr, IOCTL_MOUNTMGR_DEFINE_UNIX_DRIVE, ioctl, len, NULL, 0, NULL, NULL ))
        {
            set_drive_label( drives[i].letter, drives[i].label );
            if (drives[i].in_use) set_drive_serial( drives[i].letter, drives[i].serial );
            WINE_TRACE( "set drive %c: to %s type %u\n", 'a' + i,
                        wine_dbgstr_a(drives[i].unixpath), drives[i].type );
        }
        else WINE_WARN( "failed to set drive %c: to %s type %u err %u\n", 'a' + i,
                       wine_dbgstr_a(drives[i].unixpath), drives[i].type, GetLastError() );
        HeapFree( GetProcessHeap(), 0, ioctl );
    }
    CloseHandle( mgr );
}
Ejemplo n.º 25
0
int wmain( int argc, WCHAR *argv[] )
{
    static const WCHAR noneW[] = {'n','o','n','e',0};
    static const WCHAR mszipW[] = {'m','s','z','i','p',0};

    WCHAR *p, *command;
    char buffer[MAX_PATH];
    char filename[MAX_PATH];
    char *cab_file, *file_part;
    int i;

    while (argv[1] && argv[1][0] == '-')
    {
        switch (argv[1][1])
        {
        case 'd':
            argv++; argc--;
            opt_cabinet_size = atoiW( argv[1] );
            if (opt_cabinet_size < 50000)
            {
                WINE_MESSAGE( "cabarc: Cabinet size must be at least 50000\n" );
                return 1;
            }
            break;
        case 'h':
            usage();
            return 0;
        case 'i':
            argv++; argc--;
            opt_cabinet_id = atoiW( argv[1] );
            break;
        case 'm':
            argv++; argc--;
            if (!strcmpiW( argv[1], noneW )) opt_compression = tcompTYPE_NONE;
            else if (!strcmpiW( argv[1], mszipW )) opt_compression = tcompTYPE_MSZIP;
            else
            {
                WINE_MESSAGE( "cabarc: Unknown compression type '%s'\n", optarg );
                return 1;
            }
            break;
        case 'p':
            opt_preserve_paths = 1;
            break;
        case 'r':
            opt_recurse = 1;
            break;
        case 's':
            argv++; argc--;
            opt_reserve_space = atoiW( argv[1] );
            break;
        case 'v':
            opt_verbose++;
            break;
        default:
            usage();
            return 1;
        }
        argv++; argc--;
    }

    command = argv[1];
    if (argc < 3 || !command[0] || command[1])
    {
        usage();
        return 1;
    }
    cab_file = strdupWtoA( CP_ACP, argv[2] );
    argv += 2;
    argc -= 2;

    if (!GetFullPathNameA( cab_file, MAX_PATH, buffer, &file_part ) || !file_part)
    {
        WINE_ERR( "cannot get full name for %s\n", wine_dbgstr_a( cab_file ));
        return 1;
    }
    strcpy(filename, file_part);
    file_part[0] = 0;

    /* map slash to backslash in all file arguments */
    for (i = 1; i < argc; i++)
        for (p = argv[i]; *p; p++)
            if (*p == '/') *p = '\\';
    opt_files = argv + 1;
    opt_cab_file = filename;

    switch (*command)
    {
    case 'l':
    case 'L':
        return list_cabinet( buffer );
    case 'n':
    case 'N':
        return new_cabinet( buffer );
    case 'x':
    case 'X':
        if (argc > 1)  /* check for destination dir as last argument */
        {
            WCHAR *last = argv[argc - 1];
            if (last[0] && last[strlenW(last) - 1] == '\\')
            {
                opt_dest_dir = last;
                argv[--argc] = NULL;
            }
        }
        WINE_TRACE("Extracting file(s) from cabinet %s\n", wine_dbgstr_a(cab_file));
        return extract_cabinet( buffer );
    default:
        usage();
        return 1;
    }
}
Ejemplo n.º 26
0
/* UDisks callback for removed device */
static void udisks_removed_device( const char *udi )
{
    TRACE( "removed %s\n", wine_dbgstr_a(udi) );

    if (!remove_dos_device( -1, udi )) remove_volume( udi );
}
Ejemplo n.º 27
0
HRESULT dt_validate(XDR_DT dt, xmlChar const* content)
{
    xmlDocPtr tmp_doc;
    xmlNodePtr node;
    xmlNsPtr ns;
    HRESULT hr;

    TRACE("(dt:%s, %s)\n", dt_to_str(dt), wine_dbgstr_a((char const*)content));

    if (!datatypes_schema)
    {
        xmlSchemaParserCtxtPtr spctx;
        assert(datatypes_src != NULL);
        spctx = xmlSchemaNewMemParserCtxt((char const*)datatypes_src, datatypes_len);
        datatypes_schema = Schema_parse(spctx);
        xmlSchemaFreeParserCtxt(spctx);
    }

    switch (dt)
    {
        case DT_INVALID:
            return E_FAIL;
        case DT_BIN_BASE64:
        case DT_BIN_HEX:
        case DT_BOOLEAN:
        case DT_CHAR:
        case DT_DATE:
        case DT_DATE_TZ:
        case DT_DATETIME:
        case DT_DATETIME_TZ:
        case DT_FIXED_14_4:
        case DT_FLOAT:
        case DT_I1:
        case DT_I2:
        case DT_I4:
        case DT_I8:
        case DT_INT:
        case DT_NMTOKEN:
        case DT_NMTOKENS:
        case DT_NUMBER:
        case DT_R4:
        case DT_R8:
        case DT_STRING:
        case DT_TIME:
        case DT_TIME_TZ:
        case DT_UI1:
        case DT_UI2:
        case DT_UI4:
        case DT_UI8:
        case DT_URI:
        case DT_UUID:
            if (!datatypes_schema)
            {
                ERR("failed to load schema for urn:schemas-microsoft-com:datatypes, "
                    "you're probably using an old version of libxml2: " LIBXML_DOTTED_VERSION "\n");

                /* Hopefully they don't need much in the way of XDR datatypes support... */
                return S_OK;
            }

            if (content && xmlStrlen(content))
            {
                tmp_doc = xmlNewDoc(NULL);
                node = xmlNewChild((xmlNodePtr)tmp_doc, NULL, dt_to_str(dt), content);
                ns = xmlNewNs(node, DT_nsURI, BAD_CAST "dt");
                xmlSetNs(node, ns);
                xmlDocSetRootElement(tmp_doc, node);

                hr = Schema_validate_tree(datatypes_schema, (xmlNodePtr)tmp_doc);
                xmlFreeDoc(tmp_doc);
            }
            else
            {   /* probably the node is being created manually and has no content yet */
                hr = S_OK;
            }
            return hr;
        default:
            FIXME("need to handle dt:%s\n", dt_to_str(dt));
            return S_OK;
    }
}
Ejemplo n.º 28
0
HRESULT dt_validate(XDR_DT dt, xmlChar const* content)
{
    xmlDocPtr tmp_doc;
    xmlNodePtr node;
    xmlNsPtr ns;
    HRESULT hr;

    TRACE("(dt:%s, %s)\n", dt_to_str(dt), wine_dbgstr_a((char const*)content));

    if (!datatypes_schema)
    {
        xmlSchemaParserCtxtPtr spctx;
        assert(datatypes_src != NULL);
        spctx = xmlSchemaNewMemParserCtxt((char const*)datatypes_src, datatypes_len);
        datatypes_schema = Schema_parse(spctx);
        xmlSchemaFreeParserCtxt(spctx);
    }

    switch (dt)
    {
        case DT_INVALID:
            return E_FAIL;
        case DT_BIN_BASE64:
        case DT_BIN_HEX:
        case DT_BOOLEAN:
        case DT_CHAR:
        case DT_DATE:
        case DT_DATE_TZ:
        case DT_DATETIME:
        case DT_DATETIME_TZ:
        case DT_FIXED_14_4:
        case DT_FLOAT:
        case DT_I1:
        case DT_I2:
        case DT_I4:
        case DT_I8:
        case DT_INT:
        case DT_NMTOKEN:
        case DT_NMTOKENS:
        case DT_NUMBER:
        case DT_R4:
        case DT_R8:
        case DT_STRING:
        case DT_TIME:
        case DT_TIME_TZ:
        case DT_UI1:
        case DT_UI2:
        case DT_UI4:
        case DT_UI8:
        case DT_URI:
        case DT_UUID:
            assert(datatypes_schema != NULL);
            if (content && xmlStrlen(content))
            {
                tmp_doc = xmlNewDoc(NULL);
                node = xmlNewChild((xmlNodePtr)tmp_doc, NULL, dt_to_str(dt), content);
                ns = xmlNewNs(node, DT_nsURI, BAD_CAST "dt");
                xmlSetNs(node, ns);
                xmlDocSetRootElement(tmp_doc, node);

                hr = Schema_validate_tree(datatypes_schema, (xmlNodePtr)tmp_doc);
                xmlFreeDoc(tmp_doc);
            }
            else
            {   /* probably the node is being created manually and has no content yet */
                hr = S_OK;
            }
            return hr;
        default:
            FIXME("need to handle dt:%s\n", dt_to_str(dt));
            return S_OK;
    }
}
Ejemplo n.º 29
0
/* create a new dos drive */
NTSTATUS add_dos_device( int letter, const char *udi, const char *device,
                         const char *mount_point, enum device_type type )
{
    struct dos_drive *drive, *next;

    if (letter == -1)  /* auto-assign a letter */
    {
        letter = add_drive( device, type );
        if (letter == -1) return STATUS_OBJECT_NAME_COLLISION;
    }
    else  /* simply reset the device symlink */
    {
        char *path, *p;

        if (!(path = get_dosdevices_path( &p ))) return STATUS_NO_MEMORY;
        *p = 'a' + letter;
        unlink( path );
        if (device) symlink( device, path );
    }

    LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry )
    {
        if (udi && drive->udi && !strcmp( udi, drive->udi ))
        {
            if (type == drive->type) goto found;
            delete_disk_device( drive );
            continue;
        }
        if (drive->drive == letter) delete_disk_device( drive );
    }

    if (create_disk_device( udi, type, &drive )) return STATUS_NO_MEMORY;

found:
    RtlFreeHeap( GetProcessHeap(), 0, drive->unix_device );
    drive->unix_device = strdupA( device );
    set_drive_letter( drive, letter );
    set_unix_mount_point( drive, mount_point );

    if (drive->drive != -1)
    {
        HKEY hkey;

        TRACE( "added device %c: udi %s for %s on %s type %u\n",
                    'a' + drive->drive, wine_dbgstr_a(udi), wine_dbgstr_a(device),
                    wine_dbgstr_a(mount_point), type );

        /* hack: force the drive type in the registry */
        if (!RegCreateKeyW( HKEY_LOCAL_MACHINE, drives_keyW, &hkey ))
        {
            const WCHAR *type_name = drive_types[type];
            WCHAR name[3] = {'a',':',0};

            name[0] += drive->drive;
            if (!type_name[0] && type == DEVICE_HARDDISK) type_name = drive_types[DEVICE_FLOPPY];
            if (type_name[0])
                RegSetValueExW( hkey, name, 0, REG_SZ, (const BYTE *)type_name,
                                (strlenW(type_name) + 1) * sizeof(WCHAR) );
            else
                RegDeleteValueW( hkey, name );
            RegCloseKey( hkey );
        }

        if (udi) send_notify( drive->drive, DBT_DEVICEARRIVAL );
    }
    return STATUS_SUCCESS;
}
Ejemplo n.º 30
0
/***********************************************************************
 *           read_pif_file
 *pif386rec_tu
 * Read a pif file and return the header and possibly the 286 (real mode)
 * record or 386 (enhanced mode) record. Returns FALSE if the file is
 * invalid otherwise TRUE.
 */
static BOOL read_pif_file( HANDLE hFile, char *progname, char *title,
        char *optparams, char *startdir, int *closeonexit, int *textmode)
{
    DWORD nread;
    LARGE_INTEGER filesize;
    recordhead_t rhead;
    BOOL found386rec = FALSE;
    pif386rec_t pif386rec;
    pifhead_t pifheader;
    if( !GetFileSizeEx( hFile, &filesize) ||
            filesize.QuadPart <  (sizeof(pifhead_t) + sizeof(recordhead_t))) {
        WINE_ERR("Invalid pif file: size error %d\n", (int)filesize.QuadPart);
        return FALSE;
    }
    SetFilePointer( hFile, 0, NULL, FILE_BEGIN);
    if( !ReadFile( hFile, &pifheader, sizeof(pifhead_t), &nread, NULL))
        return FALSE;
    WINE_TRACE("header: program %s title %s startdir %s params %s\n",
            wine_dbgstr_a(pifheader.program),
            wine_dbgstr_an(pifheader.windowtitle, sizeof(pifheader.windowtitle)),
            wine_dbgstr_a(pifheader.startdir),
            wine_dbgstr_a(pifheader.optparams)); 
    WINE_TRACE("header: memory req'd %d desr'd %d drive %d videomode %d\n",
            pifheader.memmin, pifheader.memmax, pifheader.startdrive,
            pifheader.videomode);
    WINE_TRACE("header: flags 0x%x 0x%x 0x%x\n",
            pifheader.hdrflags1, pifheader.hdrflags2, pifheader.hdrflags3);
    ReadFile( hFile, &rhead, sizeof(recordhead_t), &nread, NULL);
    if( strncmp( rhead.recordname, "MICROSOFT PIFEX", 15)) {
        WINE_ERR("Invalid pif file: magic string not found\n");
        return FALSE;
    }
    /* now process the following records */
    while( 1) {
        WORD nextrecord = rhead.posofnextrecord;
        if( (nextrecord & 0x8000) || 
                filesize.QuadPart <( nextrecord + sizeof(recordhead_t))) break;
        if( !SetFilePointer( hFile, nextrecord, NULL, FILE_BEGIN) ||
                !ReadFile( hFile, &rhead, sizeof(recordhead_t), &nread, NULL))
            return FALSE;
        if( !rhead.recordname[0]) continue; /* deleted record */
        WINE_TRACE("reading record %s size %d next 0x%x\n",
                wine_dbgstr_a(rhead.recordname), rhead.sizeofdata,
                rhead.posofnextrecord );
        if( !strncmp( rhead.recordname, "WINDOWS 386", 11)) {
            found386rec = TRUE;
            ReadFile( hFile, &pif386rec, sizeof(pif386rec_t), &nread, NULL);
            WINE_TRACE("386rec: memory req'd %d des'd %d EMS req'd %d des'd %d XMS req'd %d des'd %d\n",
                    pif386rec.memmin, pif386rec.memmax,
                    pif386rec.emsmin, pif386rec.emsmax,
                    pif386rec.xmsmin, pif386rec.xmsmax);
            WINE_TRACE("386rec: option 0x%x memory 0x%x video 0x%x\n",
                    pif386rec.optflags, pif386rec.memflags,
                    pif386rec.videoflags);
            WINE_TRACE("386rec: optional parameters %s\n",
                    wine_dbgstr_a(pif386rec.optparams));
        }
    }
    /* prepare the return data */
    lstrcpynA( progname, pifheader.program, sizeof(pifheader.program)+1);
    lstrcpynA( title, pifheader.windowtitle, sizeof(pifheader.windowtitle)+1);
    if( found386rec)
        lstrcpynA( optparams, pif386rec.optparams, sizeof( pif386rec.optparams)+1);
    else
        lstrcpynA( optparams, pifheader.optparams, sizeof(pifheader.optparams)+1);
    lstrcpynA( startdir, pifheader.startdir, sizeof(pifheader.startdir)+1);
    *closeonexit = pifheader.hdrflags1 & 0x10;
    *textmode = found386rec ? pif386rec.videoflags & 0x0010
                            : pifheader.hdrflags1 & 0x0002;
    return TRUE;
}