Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Aug 2002 14:43:34 +0300 (EEST)
From:      "Jukka A. Ukkonen" <jau@cs132140.pp.htv.fi>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/41543: Easier wine/w23 support
Message-ID:  <200208111143.OAA41137@cs78135006.pp.htv.fi>

next in thread | raw e-mail | index | archive | help

>Number:         41543
>Category:       kern
>Synopsis:       Easier wine/w23 support
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Aug 11 04:50:02 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Jukka A. Ukkonen
>Release:        Irrelevant
>Organization:
Private person
>Environment:

	Any FreeBSD running on hardware which is also supported
	by ms-windows

>Description:

	It seemed like a good idea to allow FreeBSD to recognize
	ms-windows binaries on the fly and start wine as an interpreter
	for such binaries, if it is installed on the system.
	All it takes is adding one more very simple imgact function
	exec_wine_imgact() to the kernel.
	This is very much in analogy to how the kernel handles
	"#!" at the beginning of scripts.
	The actual benefit is lowering very much the threshold for
	windows users to start using FreeBSD instead.

>How-To-Repeat:

	No bug or problem, just an extension.

>Fix:
	
	The following shar bundle contains my initial version of
	exec_wine_imgact() and an include file describing the header
	parts of a windows binary. To make it obvious that this is
	just an extension I put the header to <compat/windos.h>.
	You are welcome to choose otherwise.

	Due to my systems have always had a tendency to quickly
	become somewhat modified I have no idea how well this will
	fit in any vanilla FreeBSD system, but the need for changes
	should be relatively minor. And in any case, it is the idea
	that counts.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	windos.h
#	imgact_wine.c
#
echo x - windos.h
sed 's/^X//' >windos.h << 'END-of-windos.h'
X
X#ifndef	_COMPAT_WINDOS_H
X#define	_COMPAT_WINDOS_H
X
X/*
X *  This file was originally taken from the Willows twin package
X *  and modified to better suit being used inside a UNIX kernel.
X *
X *  This file does nothing more than describes the format of
X *  a ms-windows binary file header.
X */
X
X#ifndef	WINDOS_WORD
Xtypedef unsigned short	    WORD;
X#  define WINDOS_WORD	    WORD
X#endif
X
X#ifndef	WINDOS_DWORD
Xtypedef unsigned long	    DWORD;
X#  define WINDOS_DWORD	    DWORD
X#endif
X
X/*  
X *  Old MZ header for DOS programs.
X *  We check only the magic and the e_lfanew offset to
X *  the new executable header.
X *
X *  The new format executables should start with PE\0\0.
X *  The next two bytes after the "PE\0\0" tag specify
X *  the hardware architecture for which the binary has
X *  been compiled.
X */
X
Xtypedef struct
X{
X        WORD    e_magic;        /* MZ Header signature */
X        WORD    e_cblp;         /* Bytes on last page of file */
X        WORD    e_cp;           /* Pages in file */
X        WORD    e_crlc;         /* Relocations */
X        WORD    e_cparhdr;      /* Size of header in paragraphs */
X        WORD    e_minalloc;     /* Minimum extra paragraphs needed */
X        WORD    e_maxalloc;     /* Maximum extra paragraphs needed */
X        WORD    e_ss;           /* Initial (relative) SS value */
X        WORD    e_sp;           /* Initial SP value */
X        WORD    e_csum;         /* Checksum */
X        WORD    e_ip;           /* Initial IP value */
X        WORD    e_cs;           /* Initial (relative) CS value */
X        WORD    e_lfarlc;       /* File address of relocation table */
X        WORD    e_ovno;         /* Overlay number */    
X        WORD    e_res[4];       /* Reserved words */    
X        WORD    e_oemid;        /* OEM identifier (for e_oeminfo) */
X        WORD    e_oeminfo;      /* OEM information; e_oemid specific */
X        WORD    e_res2[10];     /* Reserved words */
X        WORD    e_lfanew;       /* Offset to extended header */
X} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;  
X
X#define IMAGE_DOS_SIGNATURE     0x5A4D          /* MZ */ 
X#define IMAGE_OS2_SIGNATURE     0x454E          /* NE */
X#define IMAGE_OS2_SIGNATURE_LE  0x454C          /* LE */
X#define IMAGE_VXD_SIGNATURE     0x454C          /* LE */
X#define IMAGE_NT_SIGNATURE      0x00004550      /* PE00 */
X
X#endif
END-of-windos.h
echo x - imgact_wine.c
sed 's/^X//' >imgact_wine.c << 'END-of-imgact_wine.c'
X/*
X * Copyright (c) 2002, Jukka A. Ukkonen <jau(a)drop-this-part.iki.fi>
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X * 1. Redistributions of source code must retain the above copyright
X *    notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X *    notice, this list of conditions and the following disclaimer in the
X *    documentation and/or other materials provided with the distribution.
X *
X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
X * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X *
X * $Id: imgact_wine.c,v 1.1 2002/07/20 18:25:47 jau Exp $
X */
X
X/*
X *	Set the editor tab-width to 4
X *	to view/edit this file.
X *	Otherwise this might look a bit funny.
X */
X
X#include <sys/param.h>
X#include <sys/systm.h>
X#include <sys/sysproto.h>
X#include <sys/exec.h>
X#include <sys/imgact.h>
X#include <sys/kernel.h>
X
X#include <vm/vm_param.h>
X#include <compat/windos.h>
X
X#if defined(USER_LDT) && defined(SYSVSHM) \
X    && defined(SYSVSEM) && defined(SYSVMSG)
X#  define   IMGACT_WINE_OK
X#else
X#  undef    IMGACT_WINE_OK
X#endif
X
X/*
X *  We do not really have to test for this limit,
X *  because "/usr/local/bin/wine" is static and
X *  obviously also much shoter than 64 bytes.
X */
X
X#define MAXWINECMDLEN	64
X
Xstatic int	exec_wine_imgact __P((struct image_params *imgp));
X
X/*
X *  Shell interpreter image activator. A interpreter name beginning
X *  at imgp->stringbase is the minimal successful exit requirement.
X */
X
Xstatic int
Xexec_wine_imgact (imgp)
X	struct image_params		*imgp;
X{
X	const char			*image_header = imgp->image_header;
X	const char			*ihp, *line_endp;
X	char				*interp;
X	IMAGE_DOS_HEADER	*mshdr;
X	u_int16_t			extoffs;
X
X#ifndef	IMGACT_WINE_OK
X	return (-1);
X#else
X
X#  if !defined(i386) && !defined(alpha) && !defined(ppc)
X	return (-1);
X#  else
X
X	/* a wine/ms-win executable? */
X
X	if ((image_header[0] != 'M') || (image_header[1] != 'Z'))
X		return (-1);
X
X	
X	mshdr = (IMAGE_DOS_HEADER *) image_header;
X
X	extoffs = mshdr.e_lfanew;
X
X#    if BYTE_ORDER == BIG_ENDIAN
X	extoffs = (extoffs >> 8) | (extoffs << 8);
X#    endif
X
X
X	if (extoffs > PAGE_SIZE)
X		return (-1);
X
X	/*
X	 *  If it happens to be a PE\0\0 format object,
X	 *  we can test also whether it has been intended
X	 *  for our present HW architecture.
X	 */
X
X	if ((image_header[extoffs] == 0x50)		/* 'P' */
X		&& (image_header[extoffs + 1] == 0x45)	/* 'E' */
X		&& (image_header[extoffs + 2] == 0)
X		&& (image_header[extoffs + 3] == 0)) {
X
X	    /*
X	     *	We *must not* return ENOEXEC here.
X	     *	The exec() code will do it unless no other
X	     *	imgact activator takes the job.
X	     */
X
X#    if defined(i386)
X		if ((image_header[extoffs + 4] != 0x4c)
X			|| (image_header[extoffs + 4] != 0x01))
X			return (-1);
X#    endif
X
X#    if defined(alpha)
X		if ((image_header[extoffs + 4] != 0x84)
X			|| (image_header[extoffs + 4] != 0x01))
X			return (-1);
X#    endif
X
X#    if defined(ppc)
X		if ((image_header[extoffs + 4] != 0xf0)
X			|| (image_header[extoffs + 4] != 0x01))
X			return (-1);
X#    endif
X
X	}
X#    if !defined(i386)
X	else {
X	    /*
X	     *	Not a new format PE binary is assumed to be
X	     *	invariably a i386 binary.
X	     *	Because we are not running on a i386 host,
X	     *	there is pretty little we can do.
X	     */
X	    return (-1);
X	}
X#    endif
X
X	imgp->interpreted = 1;
X
X	interp = imgp->interpreter_name;
X	ihp = "/usr/local/bin/wine";
X
X	while (*interp++ = *ihp++);
X
X	imgp->argv0 = imgp->uap->fname;
X
X	return (0);
X
X#  endif
X#endif
X}
X
X/*
X * Tell kern_execve.c about it, with a little help from the linker.
X * Since `const' objects end up in the text segment, TEXT_SET is the
X * correct directive to use.
X */
X
Xstatic const struct execsw  wine_execsw = { exec_wine_imgact, "Wine" };
X
XEXEC_SET(wine, wine_execsw);
END-of-imgact_wine.c
exit

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208111143.OAA41137>