Release 950727

Sat Jul 22 22:39:09 IDT 1995 Michael Veksler <e1678223@tochnapc2.technion.ac.il>

	* [ipc/*]
	New directory. This directory contains the new inter-wine
 	communications support. It enables DDE protocols between two wine
 	instances.  Currently it is limited to DDE, but can be enhanced to
 	support OLE between 2 different wine instances.  This is very
 	important for libwine.a DDE/OLE support.

	* [tools/ipcl]
    	A script to delete garbage IPC handles (shared memory, semaphores
 	and message queues).  The current inter-wine communication is not
 	perfect, and sometimes leaves garbage behind.

	* [if1632/relay.c] [include/atom.h] [include/global.h]
 	[loader/selector.c] [loader/task.c] [loader/module.c]
 	[loader/signal.c] [memory/global.c] [misc/atom.c]
 	[windows/class.c] [windows/message.c] [windows/win.c]
	[Imakefile]
    	Hooks for inter-wine DDE support, current Global.*Atom functions
 	renamed to Local.*Atom since Global.*Atom are used for Inter-Wine
 	DDE communication. (The first call to these functions sets up the
 	IPC structures - which otherwise cause unneeded overhead.

Mon Jul 17 19:55:21 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [controls/menu.c]
	Don't crash if a NULL string is passed to menu functions.

	* [memory/selector.c]
	We now use a bit in ldt_flags_copy to indicate free LDT entries.
	Fixed a bug in SELECTOR_ReallocBlock that could cause it to
	overwrite valid LDT entries when growing a block.

	* [miscemu/instr.c]
	Emulate int xx instruction by storing the interrupt vector in
	CS:IP and returning directly. This allows a program to install an
	interrupt vector.

	* [windows/win.c]
	Added function WIN_GetTopParent to get the top-level parent of a
	window.

Sun Jul  16 18:17:17 1995  Gregory Trubetskoy <grisha@mira.com>

        * [loader/resource.c]
        Added LoadIconHandler. It doesn't do anything yet, but now you
        can use borland help files with winhelp.exe.

Sun Jul 16 11:58:45 1995 Anand Kumria <akumria@ozemail.com.au>

	* [misc/main.c]
	Fixed to return 386 Enhanced mode correctly. Also return the same
 	type of CPU, for both Enhanced and Standard mode, namely a 386.

Sun Jul 16 00:02:04 1995    Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [Configure] [include/options.h] [include/wineopts.h]
	  [misc/main.c][misc/spy.c]
	  Removed support of spy file. Redirected spy messages to stddeb.
	  Removed -spy option. Added -debugmsg +spy option.

	* [debugger/dbg.y][debugger/debug.l]
	Enabled segmented addresses (seg:offs) for break and x commands.

	* [if1632/gdi.spec] [objects/region.c] [windows/graphics.c]
	  [include/region.h]
	FrameRgn, REGION_FrameRgn: New functions

	* [if1632/kernel.spec]
	IsWinOldApTask: Return false

	* [if1632/mouse.spec]
	CplApplet: Removed

	* [if1632/user.spec] [windows/win.c]
	ShowOwnedPopups: New function

	* [if1632/winsock.spec] [misc/winsocket.c]
	inet_addr, select: New prototypes in relay code
	Fixed memory layout for netdb functions (getXbyY).
	WINSOCK_ioctlsocket: Translated FIONREAD, FIONBIO, and FIOASYNC

	* [objects/clipping.c]
	RectVisible: Fixed call to LPToDP

	* [rc/winerc.c]
	main: Removed extra argument to getopt for Linux.

Tue Jul 11 00:14:41 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [controls/listbox.c]
	Yet another fix for ListBoxDirectory().
	
	* [loader/module.c] [if1632/kernel.spec]
	Make GetModuleHandle() accept instance handles as parameter.

        * [if1632/relay.c] [loader/task.c]
	Put a magic cookie at the bottom of the 32 bit stack, and check on
	each return from a 32 bit function whether it's still there. Complain
	if it's not.

        * [if1632/user.spec]
	Wrong entry for CloseDriver().

	* [misc/dos_fs.c] [loader/task.c] [include/dos_fs.h] [misc/file.c]
	[miscemu/int21.c]
	Large parts of dos_fs.c simplified. Changed it to use one
	current drive/directory per task, which is set to the module path on
	task creation.
	Prevent CorelPaint from closing stdin.
	open() with O_CREAT set must be passed three parameters.
	DOS FindFirst()/FindNext() could crash when FA_LABEL was set. Fixed,
	it's in DOS_readdir() now.

	* [misc/profile.c]
	Some badly written software (Lotus Freelance Graphics) passes a bogus
	size parameter that caused Wine to write off the end of a segment.
	Fixed. (It's probably too paranoid now.)
	
	* [multimedia/mmsystem.c] [multimedia/time.c] [multimedia/joystick.c]
	[multimedia/Imakefile] [if1632/winprocs.spec]
	16 bit entry point for MMSysTimeCallback.
	Split off time.c and joystick.c from mmsystem.c.
	
	* [objects/dib.c]
	GetDIBits(): call XGetImage() via CallTo32_LargeStack.

        * [windows/cursor.c]
	DestroyCursor(): do nothing for builtin cursors.
	
	* [windows/mdi.c]
	Half of WM_MDISETMENU implemented.
	
	* [windows/win.c]
	EnumWindows() and EnumTaskWindows() never enumerated any windows.
	Fixed.

	* [windows/*.c]
	Fixed GetParent() to return correct values for owned windows.

	* [windows/message.c]
	Don't try to activate disabled top-level windows.

        * [windows/nonclient.c]
	Work around a bug in gcc-2.7.0.
	
	* [tools/build.c] [include/stackframe.h] [memory/global.c] 
	[loader/task.c] [memory/selector.c]
	Some Visual Basic programs (and possibly others, too) expect ES to be 
	preserved by a call to an API function, so we have to save it.
	In GlobalFree() and FreeSelector(), we must clear CURRENT_STACK16->es 
	to prevent segfaults if ES contained the selector to be freed.

Sun Jul  9 20:21:20 1995  Jon Tombs  <jon@gtex02.us.es>

	* [*/*]
	Added missing prototypes to header files and relevant includes
	to reduce compile time warnings.

Sun Jul  9 18:32:56 1995  Michael Patra  <micky@marie.physik.tu-berlin.de>

	* [configure.in] [include/config.h] [*/Makefile.in]
	New configuration scheme based on autoconf.

Sat Jul  8 14:12:45 1995  Morten Welinder  <terra+@cs.cmu.edu>

	* [miscemu/ioports.c]
	Revamp to have only one in- and one out- variant, both really
 	implemented.

	* [miscemu/instr.c]
	INSTR_EmulateInstruction: Use new ioport interface.  Implement
 	string io.  Correct instruction pointer for 32-bit code.

	* [include/miscemu.h]
	Update port function prototypes.

	* [include/registers.h]
	Defined FS and GS.

Sat Jul  8 13:38:54 1995  Hans de Graaff  <graaff@twi72.twi.tudelft.nl>

	* [misc/dos_fs.c]
	ChopOffSlash(): A path consisting off a single slash is left
 	intact, and multiple slashes are all removed.
This commit is contained in:
Alexandre Julliard 1995-07-29 13:09:43 +00:00
parent ded3038c1c
commit e2991ea7bd
165 changed files with 10348 additions and 2538 deletions

View File

@ -1,14 +1,15 @@
This is release 950706 of Wine the MS Windows emulator. This is still a
This is release 950727 of Wine the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work.
Patches should be submitted to "wine-new@amscons.com". Please don't forget
to include a ChangeLog entry. I'll make a new release every other Sunday.
WHAT'S NEW with Wine-950706: (see ChangeLog for details)
- Built-in debugger supports single-stepping (please test it on *BSD).
- Winelib should compile again.
- More OLE2 functions.
WHAT'S NEW with Wine-950727: (see ChangeLog for details)
- New configuration scheme based on autoconf (please test it).
- DDE communication between separate Wine processes.
- Lots of file handling fixes.
- Fixes to built-in WINSOCK.DLL.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@ -17,11 +18,11 @@ Because of lags created by using mirror, this message may reach you before
the release is available at the ftp sites. The sources will be available
from the following locations:
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950706.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950706.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950706.tar.gz
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950706.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950706.tar.gz
sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950727.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950727.tar.gz
ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950727.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-950727.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.

190
ChangeLog
View File

@ -1,5 +1,193 @@
----------------------------------------------------------------------
Wed Jul 5 19:06:35 1995 Alexandre Julliard <alex@numenor>
Sat Jul 22 22:39:09 IDT 1995 Michael Veksler <e1678223@tochnapc2.technion.ac.il>
* [ipc/*]
New directory. This directory contains the new inter-wine
communications support. It enables DDE protocols between two wine
instances. Currently it is limited to DDE, but can be enhanced to
support OLE between 2 different wine instances. This is very
important for libwine.a DDE/OLE support.
* [tools/ipcl]
A script to delete garbage IPC handles (shared memory, semaphores
and message queues). The current inter-wine communication is not
perfect, and sometimes leaves garbage behind.
* [if1632/relay.c] [include/atom.h] [include/global.h]
[loader/selector.c] [loader/task.c] [loader/module.c]
[loader/signal.c] [memory/global.c] [misc/atom.c]
[windows/class.c] [windows/message.c] [windows/win.c]
[Imakefile]
Hooks for inter-wine DDE support, current Global.*Atom functions
renamed to Local.*Atom since Global.*Atom are used for Inter-Wine
DDE communication. (The first call to these functions sets up the
IPC structures - which otherwise cause unneeded overhead.
Mon Jul 17 19:55:21 1995 Alexandre Julliard <julliard@sunsite.unc.edu>
* [controls/menu.c]
Don't crash if a NULL string is passed to menu functions.
* [memory/selector.c]
We now use a bit in ldt_flags_copy to indicate free LDT entries.
Fixed a bug in SELECTOR_ReallocBlock that could cause it to
overwrite valid LDT entries when growing a block.
* [miscemu/instr.c]
Emulate int xx instruction by storing the interrupt vector in
CS:IP and returning directly. This allows a program to install an
interrupt vector.
* [windows/win.c]
Added function WIN_GetTopParent to get the top-level parent of a
window.
Sun Jul 16 18:17:17 1995 Gregory Trubetskoy <grisha@mira.com>
* [loader/resource.c]
Added LoadIconHandler. It doesn't do anything yet, but now you
can use borland help files with winhelp.exe.
Sun Jul 16 11:58:45 1996 Anand Kumria <akumria@ozemail.com.au>
* [misc/main.c]
Fixed to return 386 Enhanced mode correctly. Also return the same
type of CPU, for both Enhanced and Standard mode, namely a 386.
Sun Jul 16 00:02:04 1995 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [Configure] [include/options.h] [include/wineopts.h]
[misc/main.c][misc/spy.c]
Removed support of spy file. Redirected spy messages to stddeb.
Removed -spy option. Added -debugmsg +spy option.
* [debugger/dbg.y][debugger/debug.l]
Enabled segmented addresses (seg:offs) for break and x commands.
* [if1632/gdi.spec] [objects/region.c] [windows/graphics.c]
[include/region.h]
FrameRgn, REGION_FrameRgn: New functions
* [if1632/kernel.spec]
IsWinOldApTask: Return false
* [if1632/mouse.spec]
CplApplet: Removed
* [if1632/user.spec] [windows/win.c]
ShowOwnedPopups: New function
* [if1632/winsock.spec] [misc/winsocket.c]
inet_addr, select: New prototypes in relay code
Fixed memory layout for netdb functions (getXbyY).
WINSOCK_ioctlsocket: Translated FIONREAD, FIONBIO, and FIOASYNC
* [objects/clipping.c]
RectVisible: Fixed call to LPToDP
* [rc/winerc.c]
main: Removed extra argument to getopt for Linux.
Tue Jul 11 00:14:41 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [controls/listbox.c]
Yet another fix for ListBoxDirectory().
* [loader/module.c] [if1632/kernel.spec]
Make GetModuleHandle() accept instance handles as parameter.
* [if1632/relay.c] [loader/task.c]
Put a magic cookie at the bottom of the 32 bit stack, and check on
each return from a 32 bit function whether it's still there. Complain
if it's not.
* [if1632/user.spec]
Wrong entry for CloseDriver().
* [misc/dos_fs.c] [loader/task.c] [include/dos_fs.h] [misc/file.c]
[miscemu/int21.c]
Large parts of dos_fs.c simplified. Changed it to use one
current drive/directory per task, which is set to the module path on
task creation.
Prevent CorelPaint from closing stdin.
open() with O_CREAT set must be passed three parameters.
DOS FindFirst()/FindNext() could crash when FA_LABEL was set. Fixed,
it's in DOS_readdir() now.
* [misc/profile.c]
Some badly written software (Lotus Freelance Graphics) passes a bogus
size parameter that caused Wine to write off the end of a segment.
Fixed. (It's probably too paranoid now.)
* [multimedia/mmsystem.c] [multimedia/time.c] [multimedia/joystick.c]
[multimedia/Imakefile] [if1632/winprocs.spec]
16 bit entry point for MMSysTimeCallback.
Split off time.c and joystick.c from mmsystem.c.
* [objects/dib.c]
GetDIBits(): call XGetImage() via CallTo32_LargeStack.
* [windows/cursor.c]
DestroyCursor(): do nothing for builtin cursors.
* [windows/mdi.c]
Half of WM_MDISETMENU implemented.
* [windows/win.c]
EnumWindows() and EnumTaskWindows() never enumerated any windows.
Fixed.
* [windows/*.c]
Fixed GetParent() to return correct values for owned windows.
* [windows/message.c]
Don't try to activate disabled top-level windows.
* [windows/nonclient.c]
Work around a bug in gcc-2.7.0.
* [tools/build.c] [include/stackframe.h] [memory/global.c]
[loader/task.c] [memory/selector.c]
Some Visual Basic programs (and possibly others, too) expect ES to be
preserved by a call to an API function, so we have to save it.
In GlobalFree() and FreeSelector(), we must clear CURRENT_STACK16->es
to prevent segfaults if ES contained the selector to be freed.
Sun Jul 9 20:21:20 1995 Jon Tombs <jon@gtex02.us.es>
* [*/*]
Added missing prototypes to header files and relevant includes
to reduce compile time warnings.
Sun Jul 9 18:32:56 1995 Michael Patra <micky@marie.physik.tu-berlin.de>
* [configure.in] [include/config.h] [*/Makefile.in]
New configuration scheme based on autoconf.
Sat Jul 8 14:12:45 1995 Morten Welinder <terra+@cs.cmu.edu>
* [miscemu/ioports.c]
Revamp to have only one in- and one out- variant, both really
implemented.
* [miscemu/instr.c]
INSTR_EmulateInstruction: Use new ioport interface. Implement
string io. Correct instruction pointer for 32-bit code.
* [include/miscemu.h]
Update port function prototypes.
* [include/registers.h]
Defined FS and GS.
Sat Jul 8 13:38:54 1995 Hans de Graaff <graaff@twi72.twi.tudelft.nl>
* [misc/dos_fs.c]
ChopOffSlash(): A path consisting off a single slash is left
intact, and multiple slashes are all removed.
----------------------------------------------------------------------
Wed Jul 5 19:06:35 1995 Alexandre Julliard <julliard@sunsite.unc.edu>
* [controls/scroll.c]
Fixed drawing bug that caused part of a non-client scroll bar

View File

@ -106,7 +106,6 @@ then
prompt "Where is COM1" CF_Com1 '/dev/cua0'
prompt "Where is COM2" CF_Com2 '/dev/cua1'
prompt "Where is LPT1" CF_Lpt1 '/dev/lp0'
prompt "Log messages to which file (CON = stdout)" CF_File 'CON'
echo
sed -n -e 's/^ *\"\(WM_[A-Z0-9]*\)\".*/\1/p' < misc/spy.c | \
@ -147,7 +146,6 @@ Com2=$CF_Com2
Lpt1=$CF_Lpt1
[spy]
File=$CF_File
Exclude=$CF_Exclude
EOF

View File

@ -7,13 +7,6 @@ CC = gcc -D__FreeBSD__
#endif
DEFINES = AutoDefines -DUSE_READLINE
#ifdef __ELF__
LD = /usr/i486-linuxaout/bin/ld -m i386linux
CDEBUGFLAGS = -O2 -Wall -b i486-linuxaout
ASFLAGS = -b i486-linuxaout
#else
CDEBUGFLAGS = -O2 -Wall
#endif
/*
* This is the second try at using Imakefiles. There are probably many
@ -33,6 +26,7 @@ CDEBUGFLAGS = -O2 -Wall
COMMONSUBDIRS = \
controls \
rc \
ipc \
loader \
misc \
multimedia \
@ -53,6 +47,7 @@ WINEDIR = $(LIBDIR)/wine
COMMONOBJS = \
controls/controls.o \
ipc/ipc.o \
loader/loader.o \
misc/misc.o \
multimedia/multimedia.o \
@ -122,4 +117,4 @@ etags::
distclean: clean
echo "/* autoconf.h generated automatically. Run Configure */" >autoconf.h
echo "#error You must run Configure before you can build the makefiles." >>autoconf.h
$(RM) `find . -name Makefile -print`
$(RM) config.* `find . -name Makefile -print`

87
Makefile.in Normal file
View File

@ -0,0 +1,87 @@
# This Makefile understands the following targets:
#
# all (default): build wine
# clean: remove all intermediate files
# distclean: also remove all files created by configure
# countryclean: remove all files which have to be remade if
# a different LANGuage is selected
# winelibclean: remove all files which differ for the emulator
# and the library
# depend: create the dependencies
#
# Author: Michael Patra <micky@marie.physik.tu-berlin.de>
# <patra@itp1.physik.tu-berlin.de>
CC = @CC@
CFLAGS = @CFLAGS@
XINCL = @x_includes@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
XPM_LIB = -lXpm
XLIB = -lXext -lX11
XDIR = -L@x_libraries@
LDLIBS = -lm
LD = @LD@
LANG = @LANG@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
COMMONSUBDIRS = controls rc ipc loader misc multimedia objects windows
EMUSUBDIRS = tools debugger if1632 memory miscemu
LIBSUBDIRS = toolkit
COMMONOBJS = controls/controls.o ipc/ipc.o loader/loader.o misc/misc.o \
multimedia/multimedia.o objects/objects.o rc/rc.o \
windows/windows.o
EMUOBJS = debugger/debugger.o if1632/if1632.o memory/memory.o miscemu/miscemu.o
LIBOBJS = toolkit/toolkit.o
SUBDIRS = $(COMMONSUBDIRS) $(EMUSUBDIRS)
OBJS = $(COMMONOBJS) $(EMUOBJS)
all:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)' 'LANG=$(LANG)'); \
done
$(CC) -o wine $(OBJS) $(LDOPTIONS) $(XDIR) $(XPM_LIB) $(XLIB) $(LDLIBS)
nm wine | grep -v _compiled | sort >wine.sym
depend:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) depend); \
done
clean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) clean); \
done
rm -f *.o \#*\# *~ wine wine.sym
distclean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) distclean); \
done
echo "/* autoconf.h generated automatically. Run Configure */" >autoconf.h
echo "#error You must run Configure before you can build the makefiles." >>autoconf.h
rm -f *.o \#*\# *~ wine wine.sym
rm -f stamp-config config.* include/config.h Makefile
countryclean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) countryclean); \
done
rm -f wine wine.sym
winelibclean:
for i in $(SUBDIRS); do \
( cd $(TOPSRC)/$$i; $(MAKE) winelibclean); \
done

3
autoconf.h.in Normal file
View File

@ -0,0 +1,3 @@
/* @configure_input@ */
#define WINE_INI_GLOBAL @WINE_INI_GLOBAL@
#define AutoDefines @LANG@

1752
configure vendored Executable file

File diff suppressed because it is too large Load Diff

148
configure.in Normal file
View File

@ -0,0 +1,148 @@
dnl Process this file with autoconf to produce a configure script.
dnl Author: Michael Patra <micky@marie.physik.tu-berlin.de>
dnl <patra@itp1.physik.tu-berlin.de>
AC_REVISION([configure.in 1.00])
AC_INIT(controls/edit.c)
AC_CONFIG_HEADER(include/config.h)
# We want these before the checks, so the checks can modify their values.
test -z "$CFLAGS" && CFLAGS="-g -O2 -Wall" AC_SUBST(CFLAGS)
test -z "$LDFLAGS" && LDFLAGS=-g AC_SUBST(LDFLAGS)
AC_PROG_MAKE_SET
AC_PROG_CC
AC_PATH_X
AC_PROG_YACC
AC_PROG_LEX
if test -n "$x_includes" ; then
x_includes="-I$x_includes"
fi
if test -n "$x_no" ; then
AXFILES='AXFILES='
fi
AC_SUBST(AXFILES)
AC_SUBST(x_includes)
AC_SUBST(x_libraries)
AC_SUBST(LIBOBJS)
LD=ld
LDCOMBINEFLAGS="-r"
AC_SUBST(LD)
AC_SUBST(LDCOMBINEFLAGS)
AC_CHECK_FUNCS(tcgetattr)
AC_CHECK_HEADERS(stdlib.h)
AC_HEADER_DIRENT()
AC_HEADER_STAT()
AC_C_CONST()
AC_TYPE_SIZE_T()
if test -z "${top_srcdir}"; then
TOP_SRCDIR="."
else
TOP_SRCDIR="${top_srcdir}"
fi
AC_MSG_CHECKING(for language in autoconf.h)
if test -f ${TOP_SRCDIR}/autoconf.h; then
LANG=`tr ' ' '\n' < ${TOP_SRCDIR}/autoconf.h | grep '\-ALANG' | head -1`
if test -n "${LANG}"; then
AC_MSG_RESULT(`echo "${LANG}" | cut -b9-10`)
fi
fi
if test -z "${LANG}"; then
AC_MSG_RESULT(no)
fi
AC_SUBST(LANG)
if test -z "${LANG}"; then
AC_MSG_CHECKING(for language through domainname)
DNAME=`domainname`
if test `echo "${DNAME}" | grep -c "\.no"` -ne 0; then
LANG="-ALANG\(No\)"
AC_MSG_RESULT(No)
fi
if test `echo "${DNAME}" | grep -c "\.de"` -ne 0; then
LANG="-ALANG\(De\)"
AC_MSG_RESULT(De)
fi
if test `echo "${DNAME}" | grep -c "\.uk"` -ne 0; then
LANG="-ALANG\(En\)"
AC_MSG_RESULT(En)
fi
if test `echo "${DNAME}" | grep -c "\.com"` -ne 0; then
LANG="-ALANG\(En\)"
AC_MSG_RESULT(En)
fi
if test `echo "${DNAME}" | grep -c "\.edu"` -ne 0; then
LANG="-ALANG\(En\)"
AC_MSG_RESULT(En)
fi
if test `echo "${DNAME}" | grep -c "\.gov"` -ne 0; then
LANG="-ALANG\(En\)"
AC_MSG_RESULT(En)
fi
if test -z "${LANG}"; then
AC_MSG_RESULT(no)
fi
fi
if test -z "${LANG}"; then
AC_MSG_CHECKING(for linux)
AC_EGREP_CPP(yes,
[#ifdef linux
yes
#endif
], AC_MSG_RESULT(yes)
AC_MSG_CHECKING(for language by examining keymap)
if test `dumpkeys | grep "keycode *26" | tr ' ' '\n' | grep -c udiaeresis` -ne 0; then
AC_MSG_RESULT(De)
LANG='-ALANG\(De\)'
else
AC_MSG_RESULT(no)
LANG='-ALANG\(En\)'
fi
,
AC_MSG_RESULT(no)
LANG='-ALANG\(En\)'
)
fi
AC_MSG_CHECKING(for wine.ini in autoconf.h)
if test -f ${TOP_SRCDIR}/autoconf.h; then
if test `grep -c WINE_INI_GLOBAL ${TOP_SRCDIR}/autoconf.h` -ne 0; then
WINE_INI_GLOBAL=`grep WINE_INI_GLOBAL ${TOP_SRCDIR}/autoconf.h | tr ' ' '\n' | tail -1`
AC_MSG_RESULT(${WINE_INI_GLOBAL})
fi
fi
if test -z "${WINE_INI_GLOBAL}"; then
AC_MSG_RESULT(no)
fi
if test -z "${WINE_INI_GLOBAL}"; then
AC_MSG_CHECKING(for /usr/local/etc/wine.conf)
if test -f /usr/local/etc/wine.conf; then
AC_MSG_RESULT(yes)
WINE_INI_GLOBAL='"/usr/local/etc/wine.conf"'
else
AC_MSG_RESULT(no)
WINE_INI_GLOBAL="\"${TOP_SRCDIR}/wine.ini\""
fi
fi
AC_SUBST(WINE_INI_GLOBAL)
test -z "$LDFLAGS" && LDFLAGS=-g AC_SUBST(LDFLAGS)
AC_OUTPUT(controls/Makefile ipc/Makefile loader/Makefile memory/Makefile misc/Makefile miscemu/Makefile multimedia/Makefile objects/Makefile windows/Makefile rc/Makefile debugger/Makefile debugger/readline/Makefile tools/Makefile if1632/Makefile Makefile autoconf.h, [touch stamp-config])
echo
echo "Configure finished. Do 'make depend; make' to compile Wine."
echo
dnl Local Variables:
dnl comment-start: "dnl "
dnl comment-end: ""
dnl comment-start-skip: "\\bdnl\\b\\s *"
dnl compile-command: "make configure config.h.in"
dnl End:

49
controls/Makefile.in Normal file
View File

@ -0,0 +1,49 @@
CC = @CC@
CFLAGS = @CFLAGS@
XINCL = @x_includes@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = controls
SRCS = button.c combo.c desktop.c edit.c listbox.c menu.c scroll.c \
static.c widgets.c
OBJS = $(SRCS:.c=.o)
.c.o:
$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
all: $(MODULE).o
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:

View File

@ -601,14 +601,12 @@ int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec)
}
strcpy(temp,filespec);
tstr = strrchr(temp, '\\');
if (tstr == NULL)
DOS_SetDefaultDrive( drive );
else {
*tstr = 0;
filespec = tstr + 1;
if (tstr != NULL) {
*(tstr+1) = 0;
filespec += tstr - temp + 1;
if (!DOS_ChangeDir( drive, temp )) return 0;
DOS_SetDefaultDrive( drive );
}
DOS_SetDefaultDrive( drive );
dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n",
drive+'A', temp, filespec);
}

View File

@ -1660,15 +1660,17 @@ BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt
HANDLE hNewItems;
MENUITEM *lpitem, *newItems;
LPPOPUPMENU menu;
if (IS_STRING_ITEM(wFlags))
{
dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, '%s') !\n",
hMenu, nPos, wFlags, wItemID, lpNewItem);
}
{
dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, '%s') !\n",
hMenu, nPos, wFlags, wItemID,
lpNewItem ? lpNewItem : "(null)");
if (!lpNewItem) return FALSE;
}
else
dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, %p) !\n",
hMenu, nPos, wFlags, wItemID, lpNewItem);
dprintf_menu(stddeb,"InsertMenu (%04X, %04X, %04X, %04X, %p) !\n",
hMenu, nPos, wFlags, wItemID, lpNewItem);
/* Find where to insert new item */
@ -1816,8 +1818,11 @@ BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewIt
{
LPMENUITEM lpitem;
if (IS_STRING_ITEM(wFlags))
{
dprintf_menu(stddeb,"ModifyMenu (%04X, %04X, %04X, %04X, '%s') !\n",
hMenu, nPos, wFlags, wItemID, lpNewItem);
hMenu, nPos, wFlags, wItemID, lpNewItem ? lpNewItem : "(null)");
if (!lpNewItem) return FALSE;
}
else
dprintf_menu(stddeb,"ModifyMenu (%04X, %04X, %04X, %04X, %p) !\n",
hMenu, nPos, wFlags, wItemID, lpNewItem);

68
debugger/Makefile.in Normal file
View File

@ -0,0 +1,68 @@
CC = @CC@
CFLAGS = @CFLAGS@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
BISON = @YACC@
FLEX = @LEX@
DIVDEFS = -DUSE_READLINE
COMPILE = $(CC) $(CFLAGS) $(DIVINCL) $(DIVDEFS)
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
@SET_MAKE@
MODULE = debugger
SRCS = break.c db_disasm.c hash.c info.c registers.c stack.c
OBJS = $(SRCS:.c=.o) dbg.tab.o lex.yy.o
all: $(MODULE).o dbg.tab.o lex.yy.o
dbg.tab.c: dbg.y
$(BISON) -b dbg -d dbg.y
dbg.tab.h: dbg.y
$(BISON) -b dbg -d dbg.y
lex.yy.c: debug.l dbg.tab.h dbg.tab.h
$(FLEX) -8 -I debug.l
.c.o:
$(COMPILE) -c -o $*.o $<
$(MODULE).o: $(OBJS)
(cd readline; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
$(LD) $(LDCOMBINEFLAGS) $(OBJS) readline/readline.o -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
clean:
(cd readline; $(MAKE) clean)
rm -f *.o \#*\# *~ dbg.tab.c dbg.tab.h lex.yy.c y.tab.c y.tab.h tmp_make
distclean: clean
(cd readline; $(MAKE) distclean)
rm Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dbg.tab.o: dbg.tab.c
lex.yy.o: lex.yy.c
dummy:
### Dependencies:

View File

@ -72,7 +72,8 @@ void mode_command(int);
| MODE NUM '\n' { mode_command($2); }
| ENABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, TRUE ); }
| DISABLE NUM '\n' { DEBUG_EnableBreakpoint( $2, FALSE ); }
| BREAK '*' expr { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
| BREAK '*' expr '\n' { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
| BREAK '*' expr ':' expr '\n' { DEBUG_AddBreakpoint( $3, $5); }
| BREAK '\n' { DEBUG_AddBreakpoint( 0xffffffff, EIP ); }
| DELETE BREAK NUM '\n' { DEBUG_DelBreakpoint( $3 ); }
| BACKTRACE '\n' { DEBUG_BackTrace(); }
@ -90,6 +91,9 @@ x_command:
EXAM expr '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
| EXAM FORMAT expr '\n' { examine_memory( 0xffffffff, $3,
$2 >> 8, $2 & 0xff ); }
| EXAM expr ':' expr '\n' { examine_memory( $2, $4, 1, 'x' ); }
| EXAM FORMAT expr ':' expr'\n' { examine_memory( $3, $5,
$2 >> 8, $2 & 0xff ); }
print_command:
PRINT expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1,'x'); }

View File

@ -37,7 +37,7 @@ IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
\n { syntax_error = 0; return '\n'; } /*Indicate end of command*/
[-+=()*] { return *yytext; }
[-+=()*:] { return *yytext; }
"0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval); return NUM; }
{DIGIT}+ { sscanf(yytext, "%d", &yylval); return NUM; }

View File

@ -10,11 +10,6 @@
extern char * find_nearest_symbol( unsigned int seg, unsigned int addr );
void application_not_running()
{
fprintf(stderr,"Application not running\n");
}
void print_address( unsigned int segment, unsigned int addr, int addrlen )
{
char *name = find_nearest_symbol( segment, addr );

View File

@ -2,12 +2,9 @@
MODULE = readline
YACC = yacc -b dbg -d
EXTRA_DEFINES= -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE -DUSE_DIRENT -DSYS_UNIX
EXTRA_DEFINES= -DANSI_ARROWS -DHAVE_TCGETATTR -DHIDE
SRCS = \
complete.c \
editline.c \
sysunix.c

View File

@ -0,0 +1,50 @@
CC = @CC@
CFLAGS = @CFLAGS@
XINCL = @x_includes@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
DIVDEFS = -DHIDE -DANSI_ARROWS
MODULE = readline
SRCS = editline.c sysunix.c
OBJS = $(SRCS:.c=.o)
.c.o:
$(CC) -c $(DIVDEFS) $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
all: $(MODULE).o
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:

View File

@ -1,222 +0,0 @@
/* $Revision: 1.3 $
**
** History and file completion functions for editline library.
*/
#include <stdlib.h>
#include "editline.h"
#if defined(NEED_STRDUP)
/*
** Return an allocated copy of a string.
*/
char *
strdup(p)
char *p;
{
char *new;
if ((new = NEW(char, strlen(p) + 1)) != NULL)
(void)strcpy(new, p);
return new;
}
#endif /* defined(NEED_STRDUP) */
/*
** strcmp-like sorting predicate for qsort.
*/
STATIC int
compare(p1, p2)
CONST void *p1;
CONST void *p2;
{
CONST char **v1;
CONST char **v2;
v1 = (CONST char **)p1;
v2 = (CONST char **)p2;
return strcmp(*v1, *v2);
}
/*
** Fill in *avp with an array of names that match file, up to its length.
** Ignore . and .. .
*/
STATIC int
FindMatches(dir, file, avp)
char *dir;
char *file;
char ***avp;
{
char **av;
char **new;
char *p;
DIR *dp;
DIRENTRY *ep;
SIZE_T ac;
SIZE_T len;
if ((dp = opendir(dir)) == NULL)
return 0;
av = NULL;
ac = 0;
len = strlen(file);
while ((ep = readdir(dp)) != NULL) {
p = ep->d_name;
if (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))
continue;
if (len && strncmp(p, file, len) != 0)
continue;
if ((ac % MEM_INC) == 0) {
if ((new = NEW(char*, ac + MEM_INC)) == NULL)
break;
if (ac) {
COPYFROMTO(new, av, ac * sizeof (char **));
DISPOSE(av);
}
*avp = av = new;
}
if ((av[ac] = strdup(p)) == NULL) {
if (ac == 0)
DISPOSE(av);
break;
}
ac++;
}
/* Clean up and return. */
(void)closedir(dp);
if (ac)
qsort(av, ac, sizeof (char **), compare);
return ac;
}
/*
** Split a pathname into allocated directory and trailing filename parts.
*/
STATIC int
SplitPath(path, dirpart, filepart)
char *path;
char **dirpart;
char **filepart;
{
static char DOT[] = ".";
char *dpart;
char *fpart;
if ((fpart = strrchr(path, '/')) == NULL) {
if ((dpart = strdup(DOT)) == NULL)
return -1;
if ((fpart = strdup(path)) == NULL) {
DISPOSE(dpart);
return -1;
}
}
else {
if ((dpart = strdup(path)) == NULL)
return -1;
dpart[fpart - path] = '\0';
if ((fpart = strdup(++fpart)) == NULL) {
DISPOSE(dpart);
return -1;
}
}
*dirpart = dpart;
*filepart = fpart;
return 0;
}
/*
** Attempt to complete the pathname, returning an allocated copy.
** Fill in *unique if we completed it, or set it to 0 if ambiguous.
*/
char *
rl_complete(pathname, unique)
char *pathname;
int *unique;
{
char **av;
char *dir;
char *file;
char *new;
char *p;
SIZE_T ac;
SIZE_T end;
SIZE_T i;
SIZE_T j;
SIZE_T len;
if (SplitPath(pathname, &dir, &file) < 0)
return NULL;
if ((ac = FindMatches(dir, file, &av)) == 0) {
DISPOSE(dir);
DISPOSE(file);
return NULL;
}
p = NULL;
len = strlen(file);
if (ac == 1) {
/* Exactly one match -- finish it off. */
*unique = 1;
j = strlen(av[0]) - len + 2;
if ((p = NEW(char, j + 1)) != NULL) {
COPYFROMTO(p, av[0] + len, j);
if ((new = NEW(char, strlen(dir) + strlen(av[0]) + 2)) != NULL) {
(void)strcpy(new, dir);
(void)strcat(new, "/");
(void)strcat(new, av[0]);
rl_add_slash(new, p);
DISPOSE(new);
}
}
}
else {
*unique = 0;
if (len) {
/* Find largest matching substring. */
for (i = len, end = strlen(av[0]); i < end; i++)
for (j = 1; j < ac; j++)
if (av[0][i] != av[j][i])
goto breakout;
breakout:
if (i > len) {
j = i - len + 1;
if ((p = NEW(char, j)) != NULL) {
COPYFROMTO(p, av[0] + len, j);
p[j - 1] = '\0';
}
}
}
}
/* Clean up and return. */
DISPOSE(dir);
DISPOSE(file);
for (i = 0; i < ac; i++)
DISPOSE(av[i]);
DISPOSE(av);
return p;
}
/*
** Return all possible completions.
*/
int
rl_list_possib(pathname, avp)
char *pathname;
char ***avp;
{
char *dir;
char *file;
int ac;
if (SplitPath(pathname, &dir, &file) < 0)
return 0;
ac = FindMatches(dir, file, avp);
DISPOSE(dir);
DISPOSE(file);
return ac;
}

View File

@ -78,8 +78,8 @@ STATIC int OldPoint;
STATIC int Point;
STATIC int PushBack;
STATIC int Pushed;
FORWARD KEYMAP Map[33];
FORWARD KEYMAP MetaMap[16];
STATIC KEYMAP Map[33];
STATIC KEYMAP MetaMap[16];
STATIC SIZE_T Length;
STATIC SIZE_T ScreenCount;
STATIC SIZE_T ScreenSize;
@ -243,41 +243,6 @@ TTYinfo()
}
/*
** Print an array of words in columns.
*/
STATIC void
columns(ac, av)
int ac;
CHAR **av;
{
CHAR *p;
int i;
int j;
int k;
int len;
int skip;
int longest;
int cols;
/* Find longest name, determine column count from that. */
for (longest = 0, i = 0; i < ac; i++)
if ((j = strlen((char *)av[i])) > longest)
longest = j;
cols = TTYwidth / (longest + 3);
TTYputs((CHAR *)NEWLINE);
for (skip = ac / cols + 1, i = 0; i < skip; i++) {
for (j = i; j < ac; j += skip) {
for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++)
TTYput(*p);
if (j + skip < ac)
while (++len < longest + 3)
TTYput(' ');
}
TTYputs((CHAR *)NEWLINE);
}
}
STATIC void
reposition()
@ -1026,71 +991,6 @@ end_line()
return CSstay;
}
/*
** Move back to the beginning of the current word and return an
** allocated copy of it.
*/
STATIC CHAR *
find_word()
{
static char SEPS[] = "#;&|^$=`'{}()<>\n\t ";
CHAR *p;
CHAR *new;
SIZE_T len;
for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--)
continue;
len = Point - (p - Line) + 1;
if ((new = NEW(CHAR, len)) == NULL)
return NULL;
COPYFROMTO(new, p, len);
new[len - 1] = '\0';
return new;
}
STATIC STATUS
c_complete()
{
CHAR *p;
CHAR *word;
int unique;
STATUS s;
word = find_word();
p = (CHAR *)rl_complete((char *)word, &unique);
if (word)
DISPOSE(word);
if (p && *p) {
s = insert_string(p);
if (!unique)
(void)ring_bell();
DISPOSE(p);
return s;
}
return ring_bell();
}
STATIC STATUS
c_possible()
{
CHAR **av;
CHAR *word;
int ac;
word = find_word();
ac = rl_list_possib((char *)word, (char ***)&av);
if (word)
DISPOSE(word);
if (ac) {
columns(ac, av);
while (--ac >= 0)
DISPOSE(av[ac]);
DISPOSE(av);
return CSmove;
}
return ring_bell();
}
STATIC STATUS
accept_line()
{
@ -1335,7 +1235,7 @@ STATIC KEYMAP Map[33] = {
{ CTL('F'), fd_char },
{ CTL('G'), ring_bell },
{ CTL('H'), bk_del_char },
{ CTL('I'), c_complete },
{ CTL('I'), ring_bell },
{ CTL('J'), accept_line },
{ CTL('K'), kill_line },
{ CTL('L'), redisplay },
@ -1367,7 +1267,7 @@ STATIC KEYMAP MetaMap[16]= {
{ '.', last_argument },
{ '<', h_first },
{ '>', h_last },
{ '?', c_possible },
{ '?', ring_bell },
{ 'b', bk_word },
{ 'd', fd_kill_word },
{ 'f', fd_word },

View File

@ -3,20 +3,17 @@
** Internal header file for editline library.
*/
#include <stdio.h>
#if defined(HAVE_STDLIB)
#include <stdlib.h>
#include <string.h>
#endif /* defined(HAVE_STDLIB) */
#if defined(SYS_UNIX)
#include "unix.h"
#endif /* defined(SYS_UNIX) */
#if defined(SYS_OS9)
#include "os9.h"
#endif /* defined(SYS_OS9) */
#include <sys/types.h>
#include <sys/stat.h>
#if !defined(SIZE_T)
#define SIZE_T unsigned int
#endif /* !defined(SIZE_T) */
#define CRLF "\r\n"
#define SIZE_T size_t
#define CONST const
typedef unsigned char CHAR;
@ -26,15 +23,6 @@ typedef unsigned char CHAR;
#define STATIC /* NULL */
#endif /* !defined(HIDE) */
#if !defined(CONST)
#if defined(__STDC__)
#define CONST const
#else
#define CONST
#endif /* defined(__STDC__) */
#endif /* !defined(CONST) */
#define MEM_INC 64
#define SCREEN_INC 256
@ -59,18 +47,3 @@ extern char *rl_complete();
extern int rl_list_possib();
extern void rl_ttyset();
extern void rl_add_slash();
#if !defined(HAVE_STDLIB)
extern char *getenv();
extern char *malloc();
extern char *realloc();
extern char *memcpy();
extern char *strcat();
extern char *strchr();
extern char *strrchr();
extern char *strcpy();
extern char *strdup();
extern int strcmp();
extern int strlen();
extern int strncmp();
#endif /* !defined(HAVE_STDLIB) */

View File

@ -3,6 +3,7 @@
** Unix system-dependant routines for editline library.
*/
#include "editline.h"
#include "config.h"
#if defined(HAVE_TCGETATTR)
#include <termios.h>

View File

@ -1,62 +0,0 @@
/* $Revision: 1.2 $
**
** A "micro-shell" to test editline library.
** If given any arguments, commands aren't executed.
*/
#include <stdio.h>
#if defined(HAVE_STDLIB)
#include <stdlib.h>
#endif /* defined(HAVE_STDLIB) */
const char version_string[] = "4.321";
extern char *readline();
extern void add_history();
#if !defined(HAVE_STDLIB)
extern int chdir();
extern int free();
extern int strncmp();
extern int system();
extern void exit();
#endif /* !defined(HAVE_STDLIB) */
#if defined(NEED_PERROR)
void
perror(s)
char *s;
{
extern int errno;
(voidf)printf(stderr, "%s: error %d\n", s, errno);
}
#endif /* defined(NEED_PERROR) */
/* ARGSUSED1 */
int
main(ac, av)
int ac;
char *av[];
{
char *p;
int doit;
doit = ac == 1;
while ((p = readline("testit> ")) != NULL) {
(void)printf("\t\t\t|%s|\n", p);
if (doit)
if (strncmp(p, "cd ", 3) == 0) {
if (chdir(&p[3]) < 0)
perror(&p[3]);
}
else if (system(p) != 0)
perror(p);
add_history(p);
free(p);
}
exit(0);
/* NOTREACHED */
}

View File

@ -1,22 +0,0 @@
/* $Revision: 1.1 $
**
** Editline system header file for Unix.
*/
#define CRLF "\r\n"
#define FORWARD STATIC
#include <sys/types.h>
#include <sys/stat.h>
#if defined(USE_DIRENT)
#include <dirent.h>
typedef struct dirent DIRENTRY;
#else
#include <sys/dir.h>
typedef struct direct DIRENTRY;
#endif /* defined(USE_DIRENT) */
#if !defined(S_ISDIR)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif /* !defined(S_ISDIR) */

88
if1632/Makefile.in Normal file
View File

@ -0,0 +1,88 @@
CC = @CC@
CFLAGS = @CFLAGS@
XINCL = @x_includes@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
BUILD = $(TOPSRC)/tools/build
@SET_MAKE@
MODULE = if1632
SRCS = callback.c relay.c relay32.c
DLLS16 = commdlg.spec compobj.spec ddeml.spec gdi.spec kernel.spec \
keyboard.spec mmsystem.spec mouse.spec ole2.spec ole2conv.spec \
ole2disp.spec ole2nls.spec ole2prox.spec olecli.spec olesvr.spec \
shell.spec sound.spec storage.spec stress.spec system.spec \
toolhelp.spec user.spec win87em.spec winprocs.spec winsock.spec
DLLS32 = gdi32.spec kernel32.spec shell32.spec user32.spec winprocs32.spec
OBJS = $(SRCS:.c=.o) $(DLLS16:.spec=.o) $(DLLS32:.spec=.o) call16.o call32.o
SFILES = $(DLLS16:.spec=.S)
.SUFFIXES: .spec
.c.o:
$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
.spec.S:
$(BUILD) -spec16 $< > $*.S
.S.o:
$(CC) -c -o $*.o $<
all: checkbuild $(MODULE).o
gdi32.c: gdi32.spec
$(BUILD) -spec32 gdi32.spec > gdi32.c
kernel32.c: kernel32.spec
$(BUILD) -spec32 kernel32.spec > kernel32.c
shell32.c: shell32.spec
$(BUILD) -spec32 shell32.spec > shell32.c
user32.c: user32.spec
$(BUILD) -spec32 user32.spec > user32.c
winprocs32.c: winprocs32.spec
$(BUILD) -spec32 winprocs32.spec > winprocs32.c
checkbuild:
(cd $(TOPSRC)/tools; $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'LD=$(LD)' 'LDCOMBINEFLAGS=$(LDCOMBINEFLAGS)')
call16.S: $(TOPSRC)/include/callback.h
$(TOPSRC)/tools/build -call16 `cat $(TOPSRC)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > call16.S
call32.S: $(SFILES)
$(BUILD) -call32 `cat $(SFILES) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM callback.c relay32.c relay.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
clean:
rm -f *.o \#*\# *~ *.S gdi32.c kernel32.c shell32.c user32.c winprocs32.c tmp_make
distclean: clean
rm Makefile
countryclean:
winelibclean:
dummy:
### Dependencies:

View File

@ -47,7 +47,7 @@ id 3
38 pascal Escape(word word word ptr ptr) Escape
39 pascal16 RestoreDC(word s_word) RestoreDC
40 pascal16 FillRgn(word word word) FillRgn
41 stub FrameRgn
41 pascal16 FrameRgn(word word word word word) FrameRgn
42 pascal16 InvertRgn(word word) InvertRgn
43 pascal16 PaintRgn(word word) PaintRgn
44 pascal16 SelectClipRgn(word word) SelectClipRgn

View File

@ -42,7 +42,7 @@ id 1
42 return DisableDos 0 0
45 pascal16 LoadModule(ptr ptr) LoadModule
46 pascal16 FreeModule(word) FreeModule
47 pascal16 GetModuleHandle(ptr) GetModuleHandle
47 pascal16 GetModuleHandle(segptr) WIN16_GetModuleHandle
48 pascal16 GetModuleUsage(word) GetModuleUsage
49 pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName
50 pascal GetProcAddress(word segptr) GetProcAddress
@ -82,7 +82,7 @@ id 1
84 pascal _llseek(word long word) _llseek
85 pascal16 _lopen(ptr word) _lopen
86 pascal16 _lwrite(word ptr word) _lwrite
87 stub RESERVED5
87 pascal16 RESERVED5(ptr ptr) lstrcmp
88 pascal lstrcpy(segptr segptr) lstrcpy
89 pascal lstrcat(segptr segptr) lstrcat
90 pascal16 lstrlen(ptr) lstrlen
@ -146,7 +146,7 @@ id 1
155 pascal16 GetTaskDS() GetTaskDS
156 stub LimitEMSPages
157 return GetCurPID 4 0
158 stub IsWinOldApTask
158 return IsWinOldApTask 2 0
159 stub GlobalHandleNoRIP
160 stub EMSCopy
161 pascal16 LocalCountFree() LocalCountFree

View File

@ -4,21 +4,21 @@ id 7
#1 pascal Inquire
#2 pascal Enable
#3 pascal Disable
4 pascal ToAscii(word word ptr ptr word) ToAscii
5 pascal AnsiToOem(ptr ptr) AnsiToOem
6 pascal OemToAnsi(ptr ptr) OemToAnsi
4 pascal16 ToAscii(word word ptr ptr word) ToAscii
5 pascal16 AnsiToOem(ptr ptr) AnsiToOem
6 pascal16 OemToAnsi(ptr ptr) OemToAnsi
#7 pascal SetSpeed
#100 pascal ScreenSwitchEnable
#126 pascal GetTableSeg
#127 pascal NewTable
128 pascal OemKeyScan(word) OemKeyScan
129 pascal VkKeyScan(byte) VkKeyScan
130 pascal GetKeyboardType(byte) GetKeyboardType
131 pascal MapVirtualKey(word word) MapVirtualKey
132 pascal GetKbCodePage() GetKbCodePage
133 pascal GetKeyNameText(long ptr word) GetKeyNameText
134 pascal AnsiToOemBuff(ptr ptr word) AnsiToOemBuff
135 pascal OemToAnsiBuff(ptr ptr word) OemToAnsiBuff
128 pascal OemKeyScan(word) OemKeyScan
129 pascal16 VkKeyScan(byte) VkKeyScan
130 pascal16 GetKeyboardType(byte) GetKeyboardType
131 pascal16 MapVirtualKey(word word) MapVirtualKey
132 pascal16 GetKbCodePage() GetKbCodePage
133 pascal16 GetKeyNameText(long ptr word) GetKeyNameText
134 pascal16 AnsiToOemBuff(ptr ptr word) AnsiToOemBuff
135 pascal16 OemToAnsiBuff(ptr ptr word) OemToAnsiBuff
#136 pascal EnableKbSysReq
#137 pascal GetBiosKeyProc

View File

@ -6,5 +6,6 @@ id 13
3 stub DISABLE
4 stub MOUSEGETINTVECT
5 stub GETSETMOUSEDATA
6 stub CPLAPPLET
#Control Panel thinks this is implemented if it is available
#6 stub CPLAPPLET
7 stub POWEREVENTPROC

View File

@ -8,6 +8,7 @@
#include "dlls.h"
#include "global.h"
#include "module.h"
#include "registers.h"
#include "stackframe.h"
#include "stddebug.h"
/* #define DEBUG_RELAY */
@ -80,7 +81,7 @@ BOOL RELAY_Init(void)
codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALL16_Start,
(int)CALL16_End - (int)CALL16_Start,
0, TRUE, TRUE, FALSE );
0, TRUE, TRUE, FALSE, NULL );
if (!codesel) return FALSE;
/* Patch the return addresses for CallTo16 routines */
@ -97,7 +98,7 @@ BOOL RELAY_Init(void)
/***********************************************************************
* RELAY_DebugCall32
*/
void RELAY_DebugCall32( char *args )
void RELAY_DebugCall32( int func_type, char *args )
{
STACK16FRAME *frame;
struct dll_table_s *table;
@ -150,6 +151,13 @@ void RELAY_DebugCall32( char *args )
if (*args) printf( "," );
}
printf( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
if (func_type == 2) /* register function */
{
struct sigcontext_struct *context = (struct sigcontext_struct *)args16;
printf( " AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
AX, BX, CX, DX, SI, DI, ES, EFL );
}
}
@ -162,6 +170,9 @@ void RELAY_DebugReturn( int func_type, int ret_val )
struct dll_table_s *table;
char *name;
if (*(DWORD *)PTR_SEG_TO_LIN(IF1632_Stack32_base) != 0xDEADBEEF) {
fprintf(stderr, "Wine wrote past the end of the 32 bit stack. Please report this.\n");
}
if (!debugging_relay) return;
frame = CURRENT_STACK16;

View File

@ -253,7 +253,7 @@ id 2
250 pascal16 GetMenuState(word word word) GetMenuState
251 pascal SendDriverMessage(word word long long) SendDriverMessage
252 pascal16 OpenDriver(ptr ptr long) OpenDriver
253 pascal CloseDriver(word word long) CloseDriver
253 pascal CloseDriver(word long long) CloseDriver
254 pascal16 GetDriverModuleHandle(word) GetDriverModuleHandle
255 pascal DefDriverProc(long word word long long) DefDriverProc
256 pascal16 GetDriverInfo(word ptr) GetDriverInfo
@ -266,7 +266,7 @@ id 2
262 pascal16 GetWindow(word word) GetWindow
263 pascal16 GetMenuItemCount(word) GetMenuItemCount
264 pascal16 GetMenuItemID(word word) GetMenuItemID
265 stub ShowOwnedPopups
265 pascal16 ShowOwnedPopups(word word) ShowOwnedPopups
266 pascal16 SetMessageQueue(word) SetMessageQueue
267 pascal16 ShowScrollBar(word word word) ShowScrollBar
268 pascal16 GlobalAddAtom(ptr) GlobalAddAtom
@ -371,7 +371,7 @@ id 2
word word word segptr) CreateWindowEx
454 pascal16 AdjustWindowRectEx(ptr long word long) AdjustWindowRectEx
455 stub GetIconId
456 stub LoadIconHandler
456 pascal16 LoadIconHandler(word word) LoadIconHandler
457 pascal16 DestroyIcon(word) DestroyIcon
458 pascal16 DestroyCursor(word) DestroyCursor
459 pascal DumpIcon(ptr ptr ptr ptr) DumpIcon

View File

@ -25,23 +25,265 @@ id 24
22 pascal ComboLBoxWndProc(word word word long) ComboLBoxWndProc
23 pascal16 CARET_Callback(word word word long) CARET_Callback
24 pascal16 TASK_Reschedule() TASK_Reschedule
25 pascal MMSysTimeCallback(word word word long) MMSysTimeCallback
# Interrupt vectors 0-255 are ordinals 100-355
# Undefined functions are mapped to the dummy handler (ordinal 356)
# The 'word' parameter are the flags pushed on the stack by the interrupt
100 register INT_Int00Handler(word) INT_DummyHandler
101 register INT_Int01Handler(word) INT_DummyHandler
102 register INT_Int02Handler(word) INT_DummyHandler
103 register INT_Int03Handler(word) INT_DummyHandler
104 register INT_Int04Handler(word) INT_DummyHandler
105 register INT_Int05Handler(word) INT_DummyHandler
106 register INT_Int06Handler(word) INT_DummyHandler
107 register INT_Int07Handler(word) INT_DummyHandler
108 register INT_Int08Handler(word) INT_DummyHandler
109 register INT_Int09Handler(word) INT_DummyHandler
110 register INT_Int0aHandler(word) INT_DummyHandler
111 register INT_Int0bHandler(word) INT_DummyHandler
112 register INT_Int0cHandler(word) INT_DummyHandler
113 register INT_Int0dHandler(word) INT_DummyHandler
114 register INT_Int0eHandler(word) INT_DummyHandler
115 register INT_Int0fHandler(word) INT_DummyHandler
116 register INT_Int10Handler(word) INT_Int10Handler
117 register INT_Int11Handler(word) INT_Int11Handler
118 register INT_Int12Handler(word) INT_Int12Handler
119 register INT_Int13Handler(word) INT_Int13Handler
120 register INT_Int14Handler(word) INT_DummyHandler
121 register INT_Int15Handler(word) INT_Int15Handler
122 register INT_Int16Handler(word) INT_Int16Handler
123 register INT_Int17Handler(word) INT_DummyHandler
124 register INT_Int18Handler(word) INT_DummyHandler
125 register INT_Int19Handler(word) INT_DummyHandler
126 register INT_Int1aHandler(word) INT_Int1aHandler
133 register INT_Int21Handler(word) INT_Int21Handler
137 register INT_Int25Handler(word) INT_Int25Handler
138 register INT_Int26Handler(word) INT_Int26Handler
127 register INT_Int1bHandler(word) INT_DummyHandler
128 register INT_Int1cHandler(word) INT_DummyHandler
129 register INT_Int1dHandler(word) INT_DummyHandler
130 register INT_Int1eHandler(word) INT_DummyHandler
131 register INT_Int1fHandler(word) INT_DummyHandler
132 register INT_Int20Handler(word) INT_DummyHandler
133 register INT_Int21Handler(word) DOS3Call
134 register INT_Int22Handler(word) INT_DummyHandler
135 register INT_Int23Handler(word) INT_DummyHandler
136 register INT_Int24Handler(word) INT_DummyHandler
# Note: int 25 and 26 don't pop the flags from the stack
137 register INT_Int25Handler() INT_Int25Handler
138 register INT_Int26Handler() INT_Int26Handler
139 register INT_Int27Handler(word) INT_DummyHandler
140 register INT_Int28Handler(word) INT_DummyHandler
141 register INT_Int29Handler(word) INT_DummyHandler
142 register INT_Int2aHandler(word) INT_Int2aHandler
143 register INT_Int2bHandler(word) INT_DummyHandler
144 register INT_Int2cHandler(word) INT_DummyHandler
145 register INT_Int2dHandler(word) INT_DummyHandler
146 register INT_Int2eHandler(word) INT_DummyHandler
147 register INT_Int2fHandler(word) INT_Int2fHandler
148 register INT_Int30Handler(word) INT_DummyHandler
149 register INT_Int31Handler(word) INT_Int31Handler
192 register INT_Int5cHandler(word) INT_Int5cHandler
150 register INT_Int32Handler(word) INT_DummyHandler
151 register INT_Int33Handler(word) INT_DummyHandler
152 register INT_Int34Handler(word) INT_DummyHandler
153 register INT_Int35Handler(word) INT_DummyHandler
154 register INT_Int36Handler(word) INT_DummyHandler
155 register INT_Int37Handler(word) INT_DummyHandler
156 register INT_Int38Handler(word) INT_DummyHandler
157 register INT_Int39Handler(word) INT_DummyHandler
158 register INT_Int3aHandler(word) INT_DummyHandler
159 register INT_Int3bHandler(word) INT_DummyHandler
160 register INT_Int3cHandler(word) INT_DummyHandler
161 register INT_Int3dHandler(word) INT_DummyHandler
162 register INT_Int3eHandler(word) INT_DummyHandler
163 register INT_Int3fHandler(word) INT_DummyHandler
164 register INT_Int40Handler(word) INT_DummyHandler
165 register INT_Int41Handler(word) INT_DummyHandler
166 register INT_Int42Handler(word) INT_DummyHandler
167 register INT_Int43Handler(word) INT_DummyHandler
168 register INT_Int44Handler(word) INT_DummyHandler
169 register INT_Int45Handler(word) INT_DummyHandler
170 register INT_Int46Handler(word) INT_DummyHandler
171 register INT_Int47Handler(word) INT_DummyHandler
172 register INT_Int48Handler(word) INT_DummyHandler
173 register INT_Int49Handler(word) INT_DummyHandler
174 register INT_Int4aHandler(word) INT_DummyHandler
175 register INT_Int4bHandler(word) INT_DummyHandler
176 register INT_Int4cHandler(word) INT_DummyHandler
177 register INT_Int4dHandler(word) INT_DummyHandler
178 register INT_Int4eHandler(word) INT_DummyHandler
179 register INT_Int4fHandler(word) INT_DummyHandler
180 register INT_Int50Handler(word) INT_DummyHandler
181 register INT_Int51Handler(word) INT_DummyHandler
182 register INT_Int52Handler(word) INT_DummyHandler
183 register INT_Int53Handler(word) INT_DummyHandler
184 register INT_Int54Handler(word) INT_DummyHandler
185 register INT_Int55Handler(word) INT_DummyHandler
186 register INT_Int56Handler(word) INT_DummyHandler
187 register INT_Int57Handler(word) INT_DummyHandler
188 register INT_Int58Handler(word) INT_DummyHandler
189 register INT_Int59Handler(word) INT_DummyHandler
190 register INT_Int5aHandler(word) INT_DummyHandler
191 register INT_Int5bHandler(word) INT_DummyHandler
192 register INT_Int5cHandler(word) NetBIOSCall
193 register INT_Int5dHandler(word) INT_DummyHandler
194 register INT_Int5eHandler(word) INT_DummyHandler
195 register INT_Int5fHandler(word) INT_DummyHandler
196 register INT_Int60Handler(word) INT_DummyHandler
197 register INT_Int61Handler(word) INT_DummyHandler
198 register INT_Int62Handler(word) INT_DummyHandler
199 register INT_Int63Handler(word) INT_DummyHandler
200 register INT_Int64Handler(word) INT_DummyHandler
201 register INT_Int65Handler(word) INT_DummyHandler
202 register INT_Int66Handler(word) INT_DummyHandler
203 register INT_Int67Handler(word) INT_DummyHandler
204 register INT_Int68Handler(word) INT_DummyHandler
205 register INT_Int69Handler(word) INT_DummyHandler
206 register INT_Int6aHandler(word) INT_DummyHandler
207 register INT_Int6bHandler(word) INT_DummyHandler
208 register INT_Int6cHandler(word) INT_DummyHandler
209 register INT_Int6dHandler(word) INT_DummyHandler
210 register INT_Int6eHandler(word) INT_DummyHandler
211 register INT_Int6fHandler(word) INT_DummyHandler
212 register INT_Int70Handler(word) INT_DummyHandler
213 register INT_Int71Handler(word) INT_DummyHandler
214 register INT_Int72Handler(word) INT_DummyHandler
215 register INT_Int73Handler(word) INT_DummyHandler
216 register INT_Int74Handler(word) INT_DummyHandler
217 register INT_Int75Handler(word) INT_DummyHandler
218 register INT_Int76Handler(word) INT_DummyHandler
219 register INT_Int77Handler(word) INT_DummyHandler
220 register INT_Int78Handler(word) INT_DummyHandler
221 register INT_Int79Handler(word) INT_DummyHandler
222 register INT_Int7aHandler(word) INT_DummyHandler
223 register INT_Int7bHandler(word) INT_DummyHandler
224 register INT_Int7cHandler(word) INT_DummyHandler
225 register INT_Int7dHandler(word) INT_DummyHandler
226 register INT_Int7eHandler(word) INT_DummyHandler
227 register INT_Int7fHandler(word) INT_DummyHandler
228 register INT_Int80Handler(word) INT_DummyHandler
229 register INT_Int81Handler(word) INT_DummyHandler
230 register INT_Int82Handler(word) INT_DummyHandler
231 register INT_Int83Handler(word) INT_DummyHandler
232 register INT_Int84Handler(word) INT_DummyHandler
233 register INT_Int85Handler(word) INT_DummyHandler
234 register INT_Int86Handler(word) INT_DummyHandler
235 register INT_Int87Handler(word) INT_DummyHandler
236 register INT_Int88Handler(word) INT_DummyHandler
237 register INT_Int89Handler(word) INT_DummyHandler
238 register INT_Int8aHandler(word) INT_DummyHandler
239 register INT_Int8bHandler(word) INT_DummyHandler
240 register INT_Int8cHandler(word) INT_DummyHandler
241 register INT_Int8dHandler(word) INT_DummyHandler
242 register INT_Int8eHandler(word) INT_DummyHandler
243 register INT_Int8fHandler(word) INT_DummyHandler
244 register INT_Int90Handler(word) INT_DummyHandler
245 register INT_Int91Handler(word) INT_DummyHandler
246 register INT_Int92Handler(word) INT_DummyHandler
247 register INT_Int93Handler(word) INT_DummyHandler
248 register INT_Int94Handler(word) INT_DummyHandler
249 register INT_Int95Handler(word) INT_DummyHandler
250 register INT_Int96Handler(word) INT_DummyHandler
251 register INT_Int97Handler(word) INT_DummyHandler
252 register INT_Int98Handler(word) INT_DummyHandler
253 register INT_Int99Handler(word) INT_DummyHandler
254 register INT_Int9aHandler(word) INT_DummyHandler
255 register INT_Int9bHandler(word) INT_DummyHandler
256 register INT_Int9cHandler(word) INT_DummyHandler
257 register INT_Int9dHandler(word) INT_DummyHandler
258 register INT_Int9eHandler(word) INT_DummyHandler
259 register INT_Int9fHandler(word) INT_DummyHandler
260 register INT_Inta0Handler(word) INT_DummyHandler
261 register INT_Inta1Handler(word) INT_DummyHandler
262 register INT_Inta2Handler(word) INT_DummyHandler
263 register INT_Inta3Handler(word) INT_DummyHandler
264 register INT_Inta4Handler(word) INT_DummyHandler
265 register INT_Inta5Handler(word) INT_DummyHandler
266 register INT_Inta6Handler(word) INT_DummyHandler
267 register INT_Inta7Handler(word) INT_DummyHandler
268 register INT_Inta8Handler(word) INT_DummyHandler
269 register INT_Inta9Handler(word) INT_DummyHandler
270 register INT_IntaaHandler(word) INT_DummyHandler
271 register INT_IntabHandler(word) INT_DummyHandler
272 register INT_IntacHandler(word) INT_DummyHandler
273 register INT_IntadHandler(word) INT_DummyHandler
274 register INT_IntaeHandler(word) INT_DummyHandler
275 register INT_IntafHandler(word) INT_DummyHandler
276 register INT_Intb0Handler(word) INT_DummyHandler
277 register INT_Intb1Handler(word) INT_DummyHandler
278 register INT_Intb2Handler(word) INT_DummyHandler
279 register INT_Intb3Handler(word) INT_DummyHandler
280 register INT_Intb4Handler(word) INT_DummyHandler
281 register INT_Intb5Handler(word) INT_DummyHandler
282 register INT_Intb6Handler(word) INT_DummyHandler
283 register INT_Intb7Handler(word) INT_DummyHandler
284 register INT_Intb8Handler(word) INT_DummyHandler
285 register INT_Intb9Handler(word) INT_DummyHandler
286 register INT_IntbaHandler(word) INT_DummyHandler
287 register INT_IntbbHandler(word) INT_DummyHandler
288 register INT_IntbcHandler(word) INT_DummyHandler
289 register INT_IntbdHandler(word) INT_DummyHandler
290 register INT_IntbeHandler(word) INT_DummyHandler
291 register INT_IntbfHandler(word) INT_DummyHandler
292 register INT_Intc0Handler(word) INT_DummyHandler
293 register INT_Intc1Handler(word) INT_DummyHandler
294 register INT_Intc2Handler(word) INT_DummyHandler
295 register INT_Intc3Handler(word) INT_DummyHandler
296 register INT_Intc4Handler(word) INT_DummyHandler
297 register INT_Intc5Handler(word) INT_DummyHandler
298 register INT_Intc6Handler(word) INT_DummyHandler
299 register INT_Intc7Handler(word) INT_DummyHandler
300 register INT_Intc8Handler(word) INT_DummyHandler
301 register INT_Intc9Handler(word) INT_DummyHandler
302 register INT_IntcaHandler(word) INT_DummyHandler
303 register INT_IntcbHandler(word) INT_DummyHandler
304 register INT_IntccHandler(word) INT_DummyHandler
305 register INT_IntcdHandler(word) INT_DummyHandler
306 register INT_IntceHandler(word) INT_DummyHandler
307 register INT_IntcfHandler(word) INT_DummyHandler
308 register INT_Intd0Handler(word) INT_DummyHandler
309 register INT_Intd1Handler(word) INT_DummyHandler
310 register INT_Intd2Handler(word) INT_DummyHandler
311 register INT_Intd3Handler(word) INT_DummyHandler
312 register INT_Intd4Handler(word) INT_DummyHandler
313 register INT_Intd5Handler(word) INT_DummyHandler
314 register INT_Intd6Handler(word) INT_DummyHandler
315 register INT_Intd7Handler(word) INT_DummyHandler
316 register INT_Intd8Handler(word) INT_DummyHandler
317 register INT_Intd9Handler(word) INT_DummyHandler
318 register INT_IntdaHandler(word) INT_DummyHandler
319 register INT_IntdbHandler(word) INT_DummyHandler
320 register INT_IntdcHandler(word) INT_DummyHandler
321 register INT_IntddHandler(word) INT_DummyHandler
322 register INT_IntdeHandler(word) INT_DummyHandler
323 register INT_IntdfHandler(word) INT_DummyHandler
324 register INT_Inte0Handler(word) INT_DummyHandler
325 register INT_Inte1Handler(word) INT_DummyHandler
326 register INT_Inte2Handler(word) INT_DummyHandler
327 register INT_Inte3Handler(word) INT_DummyHandler
328 register INT_Inte4Handler(word) INT_DummyHandler
329 register INT_Inte5Handler(word) INT_DummyHandler
330 register INT_Inte6Handler(word) INT_DummyHandler
331 register INT_Inte7Handler(word) INT_DummyHandler
332 register INT_Inte8Handler(word) INT_DummyHandler
333 register INT_Inte9Handler(word) INT_DummyHandler
334 register INT_InteaHandler(word) INT_DummyHandler
335 register INT_IntebHandler(word) INT_DummyHandler
336 register INT_IntecHandler(word) INT_DummyHandler
337 register INT_IntedHandler(word) INT_DummyHandler
338 register INT_InteeHandler(word) INT_DummyHandler
339 register INT_IntefHandler(word) INT_DummyHandler
340 register INT_Intf0Handler(word) INT_DummyHandler
341 register INT_Intf1Handler(word) INT_DummyHandler
342 register INT_Intf2Handler(word) INT_DummyHandler
343 register INT_Intf3Handler(word) INT_DummyHandler
344 register INT_Intf4Handler(word) INT_DummyHandler
345 register INT_Intf5Handler(word) INT_DummyHandler
346 register INT_Intf6Handler(word) INT_DummyHandler
347 register INT_Intf7Handler(word) INT_DummyHandler
348 register INT_Intf8Handler(word) INT_DummyHandler
349 register INT_Intf9Handler(word) INT_DummyHandler
350 register INT_IntfaHandler(word) INT_DummyHandler
351 register INT_IntfbHandler(word) INT_DummyHandler
352 register INT_IntfcHandler(word) INT_DummyHandler
353 register INT_IntfdHandler(word) INT_DummyHandler
354 register INT_IntfeHandler(word) INT_DummyHandler
355 register INT_IntffHandler(word) INT_DummyHandler
# Dummy interrupt vector
356 register INT_DummyHandler(word) INT_DummyHandler

View File

@ -15,7 +15,7 @@ id 8
7 pascal16 getsockopt(word word word ptr ptr) WINSOCK_getsockopt
8 pascal htonl(long) WINSOCK_htonl
9 pascal16 htons(word) WINSOCK_htons
10 pascal inet_addr(long) WINSOCK_inet_addr
10 pascal inet_addr(ptr) WINSOCK_inet_addr
11 pascal inet_ntoa(long) WINSOCK_inet_ntoa
12 pascal16 ioctlsocket(word long ptr) WINSOCK_ioctlsocket
13 pascal16 listen(word word) WINSOCK_listen
@ -23,7 +23,7 @@ id 8
15 pascal16 ntohs(word) WINSOCK_ntohs
16 pascal16 recv(word ptr word word) WINSOCK_recv
17 pascal16 recvfrom(word ptr word word ptr ptr) WINSOCK_recvfrom
18 pascal16 select(word ptr ptr ptr ptr word) WINSOCK_select
18 pascal16 select(word ptr ptr ptr ptr ptr) WINSOCK_select
19 pascal16 send(word ptr word word) WINSOCK_send
20 pascal16 sendto(word ptr word word ptr ptr) WINSOCK_sendto
21 pascal16 setsockopt(word word word ptr word) WINSOCK_setsockopt

View File

@ -31,4 +31,14 @@ typedef struct
#define LocalAlign(flags,bytes) LocalAlloc((flags),(bytes))
#endif
ATOM LocalAddAtom( LPCSTR str );
ATOM LocalDeleteAtom( ATOM atom );
ATOM LocalFindAtom( LPCSTR str );
WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
ATOM LocalAddAtom( LPCSTR str );
ATOM LocalDeleteAtom( ATOM atom );
ATOM LocalFindAtom( LPCSTR str );
WORD LocalGetAtomName( ATOM atom, LPSTR buffer, short count );
#endif /* ATOM_H */

53
include/bit_array.h Normal file
View File

@ -0,0 +1,53 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: bit_array.h
* Purpose : manipulate array of bits,
* Important: operations may be considered atomic.
*
***************************************************************************
*/
#ifndef __WINE_BIT_ARRAY_H
#define __WINE_BIT_ARRAY_H
#define BITS_PER_BYTE (8)
#define BITS_PER_INT (sizeof(int)*BITS_PER_BYTE) /* must be power of 2 */
#define BYTE_LOG2 (3)
#if defined(INT_LOG2)
/* nothing to do, IN_LOG2 is ok */
#elif defined(__i386__)
# define INT_LOG2 (5)
#else
# error "Can't find log2 of BITS_PER_INT, please code it manualy"
#endif
typedef struct bit_array {
int bits; /* number of bits in the array */
unsigned int *array; /* Actual array data (Never NULL) */
} bit_array ;
bit_array *AssembleArray(bit_array *new_array, unsigned int *buff, int bits);
int ResetArray(bit_array *bits);
/* Return index of first free bit, or -1 on failure */
int VacantBit(bit_array *bits);
/* Return the value of bit 'i' */
int SampleBit(bit_array *bits, int i);
/* Assign 'val' to a bit no. 'i'. Return: old bit's value */
int AssignBit(bit_array *bits, int i, int val);
/*
** Allocate a free bit (==0) and make it used (==1).
** Return: allocated bit index, or -1 on failure.
*/
int AllocateBit(bit_array *bits);
#endif /* __WINE_BIT_ARRAY_H */

6
include/config.h.in Normal file
View File

@ -0,0 +1,6 @@
#undef HAVE_STDLIB_H
#undef HAVE_TCGETATTR
#undef HAVE_DIRENT_H
#undef HAVE_SYS_NDIR_H
#undef HAVE_NDIR_H
#undef STAT_MACROS_BROKEN

61
include/dde.h Normal file
View File

@ -0,0 +1,61 @@
/*****************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde.h
* Purpose: dde declarations
*
*****************************************************************************
*/
#ifndef __WINE_DDE_H
#define __WINE_DDE_H
#include "wintypes.h"
#include "dde_proc.h"
#define WM_DDE_INITIATE 0x3E0
#define WM_DDE_TERMINATE 0x3E1
#define WM_DDE_ADVISE 0x3E2
#define WM_DDE_UNADVISE 0x3E3
#define WM_DDE_ACK 0x3E4
#define WM_DDE_DATA 0x3E5
#define WM_DDE_REQUEST 0x3E6
#define WM_DDE_POKE 0x3E7
#define WM_DDE_EXECUTE 0x3E8
#define WM_DDE_LAST WM_DDE_EXECUTE
#define WM_DDE_FIRST WM_DDE_INITIATE
/* DDEACK: wStatus in WM_DDE_ACK message */
struct tagDDEACK
{
WORD bAppReturnCode:8, reserved:6, fBusy:1, fAck:1;
};
typedef struct tagDDEACK DDEACK;
/* DDEDATA: hData in WM_DDE_DATA message */
struct tagDDEDATA
{
WORD unused:12, fResponse:1, fRelease:1, reserved:1, fAckReq:1,
cfFormat:16;
BYTE Value[1]; /* undetermined array */
};
typedef struct tagDDEDATA DDEDATA;
/* DDEADVISE: hOptions in WM_DDE_ADVISE message */
struct tagDDEADVISE
{
WORD reserved:14, fDeferUpd:1, fAckReq:1, cfFormat:16;
};
typedef struct tagDDEADVISE DDEADVISE;
/* DDEPOKE: hData in WM_DDE_POKE message. */
struct tagDDEPOKE
{
WORD unused:13, fRelease:1, fReserved:2, cfFormat:16;
BYTE Value[1]; /* undetermined array */
};
typedef struct tagDDEPOKE DDEPOKE;
#endif /* __WINE_DDE_H */

23
include/dde_atom.h Normal file
View File

@ -0,0 +1,23 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_atom.h
* Purpose : atom functionality for DDE
***************************************************************************
*/
#ifndef __WINE_DDE_ATOM_H
#define __WINE_DDE_ATOM_H
#include "windows.h"
#define DDE_ATOMS 157 /* a prime number for hashing */
void ATOM_GlobalInit(void);
/*
ATOM GlobalAddAtom( LPCSTR str );
ATOM GlobalDeleteAtom( ATOM atom );
ATOM GlobalFindAtom( LPCSTR str );
WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
*/
#endif __WINE_DDE_ATOM_H

34
include/dde_mem.h Normal file
View File

@ -0,0 +1,34 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_mem.h
* Purpose : shared DDE memory functionality for DDE
***************************************************************************
*/
#ifndef __WINE_DDE_MEM_H
#define __WINE_DDE_MEM_H
#include "wintypes.h"
#include "global.h"
#include "shm_block.h"
#define DDE_HANDLES 0x0400
#define is_dde_handle(block) ( (block) >= (1<<15) && (block) < (1<<15)+DDE_HANDLES )
typedef struct {
int shmid;
REL_PTR rel;
}DDE_HWND;
WORD DDE_SyncHandle(HGLOBAL handle, WORD sel);
void *DDE_malloc(unsigned int flags,unsigned long size, SHMDATA *shmdata);
HANDLE DDE_GlobalReAlloc(WORD,long,WORD);
HANDLE DDE_GlobalFree(WORD block);
void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr);
WORD DDE_GlobalHandleToSel( HGLOBAL handle );
int DDE_GlobalUnlock(int);
HANDLE DDE_GlobalSize(WORD);
HANDLE DDE_GlobalHandle(WORD);
HANDLE DDE_GlobalFlags(WORD);
#endif /* __WINE_DDE_MEM_H */

57
include/dde_proc.h Normal file
View File

@ -0,0 +1,57 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_proc.h
* Purpose : DDE signals and processes functionality for DDE
***************************************************************************
*/
#ifndef __WINE_DDE_PROC_H
#define __WINE_DDE_PROC_H
#include <setjmp.h>
#include "wintypes.h"
#include "windows.h"
#define DDE_PROCS 64
#define DDE_WINDOWS 64
struct _dde_proc {
int msg; /* message queue for this process */
int shmid; /* first shared memory block id. */
int sem; /* semaphore for fragment allocation */
int pid;
} ;
typedef struct _dde_proc *dde_proc;
extern sigjmp_buf env_wait_x;
enum stop_wait_op { /* The action to be taken upon SIGUSR2 */
CONT, /* Don't do anything */
STOP_WAIT_ACK, /* Use siglongjmp to stop wait_ack() */
STOP_WAIT_X /* siglongjmp to stop MSG_WaitXEvent() */
};
typedef struct {
WORD proc_idx; /* index into wine's process table */
HWND wnd; /* Window on the local proccess */
} WND_DATA;
extern enum stop_wait_op stop_wait_op;
extern int had_SIGUSR2;
extern int curr_proc_idx;
void stop_wait(int a); /* signal handler for SIGUSR2
(interrupts "select" system call) */
void dde_proc_init(dde_proc proc); /* init proc array */
void dde_proc_done(dde_proc proc); /* delete a proc entry */
void dde_proc_refresh(dde_proc proc); /* delete entry, if old junk */
void dde_proc_add(dde_proc proc); /* Add current proc to proc array */
void dde_msg_setup(int *msg_ptr);
int dde_reschedule();
void dde_wnd_setup(); /* setup Data structure of DDE windows */
/* Send ack. to hnd indicating that posted/sent msg. got to destination*/
void dde_proc_send_ack(HWND wnd, BOOL val);
BOOL DDE_PostMessage( MSG *msg);
BOOL DDE_SendMessage( MSG *msg);
int DDE_GetRemoteMessage();
void DDE_DestroyWindow(HWND hwnd); /* delete DDE info regarding hwnd */
void DDE_TestDDE(HWND hwnd); /* do we have dde handling in the window ?*/
#endif /* __WINE_DDE_PROC_H */

View File

@ -17,6 +17,7 @@
#ifdef DEBUG_NONE_EXT
#undef DEBUG_ACCEL
#undef DEBUG_ATOM
#undef DEBUG_BITBLT
#undef DEBUG_BITMAP
#undef DEBUG_CARET
@ -29,6 +30,7 @@
#undef DEBUG_COMM
#undef DEBUG_CURSOR
#undef DEBUG_DC
#undef DEBUG_DDE
#undef DEBUG_DIALOG
#undef DEBUG_DLL
#undef DEBUG_DOSFS
@ -77,6 +79,9 @@
#undef DEBUG_SCROLL
#undef DEBUG_SELECTOR
#undef DEBUG_SELECTORS
#undef DEBUG_SEM
#undef DEBUG_SHM
#undef DEBUG_SPY
#undef DEBUG_STRESS
#undef DEBUG_SYSCOLOR
#undef DEBUG_TASK
@ -90,6 +95,7 @@
#ifdef DEBUG_ALL_EXT
#define DEBUG_ACCEL
#define DEBUG_ATOM
#define DEBUG_BITBLT
#define DEBUG_BITMAP
#define DEBUG_CARET
@ -102,6 +108,7 @@
#define DEBUG_COMM
#define DEBUG_CURSOR
#define DEBUG_DC
#define DEBUG_DDE
#define DEBUG_DIALOG
#define DEBUG_DLL
#define DEBUG_DOSFS
@ -150,6 +157,9 @@
#define DEBUG_SCROLL
#define DEBUG_SELECTOR
#define DEBUG_SELECTORS
#define DEBUG_SEM
#define DEBUG_SHM
#define DEBUG_SPY
#define DEBUG_STRESS
#define DEBUG_SYSCOLOR
#define DEBUG_TASK
@ -169,6 +179,11 @@ short debug_msg_enabled[]={
#else
0,
#endif
#ifdef DEBUG_ATOM
1,
#else
0,
#endif
#ifdef DEBUG_BITBLT
1,
#else
@ -229,6 +244,11 @@ short debug_msg_enabled[]={
#else
0,
#endif
#ifdef DEBUG_DDE
1,
#else
0,
#endif
#ifdef DEBUG_DIALOG
1,
#else
@ -469,6 +489,21 @@ short debug_msg_enabled[]={
#else
0,
#endif
#ifdef DEBUG_SEM
1,
#else
0,
#endif
#ifdef DEBUG_SHM
1,
#else
0,
#endif
#ifdef DEBUG_SPY
1,
#else
0,
#endif
#ifdef DEBUG_STRESS
1,
#else
@ -535,8 +570,21 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_bitblt if(!debug_msg_enabled[1]) ; else fprintf
#define debugging_bitblt debug_msg_enabled[1]
#define dprintf_atom if(!debug_msg_enabled[1]) ; else fprintf
#define debugging_atom debug_msg_enabled[1]
#else
#ifdef DEBUG_ATOM
#define dprintf_atom fprintf
#define debugging_atom 1
#else
#define dprintf_atom while(0) fprintf
#define debugging_atom 0
#endif
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_bitblt if(!debug_msg_enabled[2]) ; else fprintf
#define debugging_bitblt debug_msg_enabled[2]
#else
#ifdef DEBUG_BITBLT
#define dprintf_bitblt fprintf
@ -548,8 +596,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_bitmap if(!debug_msg_enabled[2]) ; else fprintf
#define debugging_bitmap debug_msg_enabled[2]
#define dprintf_bitmap if(!debug_msg_enabled[3]) ; else fprintf
#define debugging_bitmap debug_msg_enabled[3]
#else
#ifdef DEBUG_BITMAP
#define dprintf_bitmap fprintf
@ -561,8 +609,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_caret if(!debug_msg_enabled[3]) ; else fprintf
#define debugging_caret debug_msg_enabled[3]
#define dprintf_caret if(!debug_msg_enabled[4]) ; else fprintf
#define debugging_caret debug_msg_enabled[4]
#else
#ifdef DEBUG_CARET
#define dprintf_caret fprintf
@ -574,8 +622,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_catch if(!debug_msg_enabled[4]) ; else fprintf
#define debugging_catch debug_msg_enabled[4]
#define dprintf_catch if(!debug_msg_enabled[5]) ; else fprintf
#define debugging_catch debug_msg_enabled[5]
#else
#ifdef DEBUG_CATCH
#define dprintf_catch fprintf
@ -587,8 +635,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_cdaudio if(!debug_msg_enabled[5]) ; else fprintf
#define debugging_cdaudio debug_msg_enabled[5]
#define dprintf_cdaudio if(!debug_msg_enabled[6]) ; else fprintf
#define debugging_cdaudio debug_msg_enabled[6]
#else
#ifdef DEBUG_CDAUDIO
#define dprintf_cdaudio fprintf
@ -600,8 +648,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_class if(!debug_msg_enabled[6]) ; else fprintf
#define debugging_class debug_msg_enabled[6]
#define dprintf_class if(!debug_msg_enabled[7]) ; else fprintf
#define debugging_class debug_msg_enabled[7]
#else
#ifdef DEBUG_CLASS
#define dprintf_class fprintf
@ -613,8 +661,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_clipboard if(!debug_msg_enabled[7]) ; else fprintf
#define debugging_clipboard debug_msg_enabled[7]
#define dprintf_clipboard if(!debug_msg_enabled[8]) ; else fprintf
#define debugging_clipboard debug_msg_enabled[8]
#else
#ifdef DEBUG_CLIPBOARD
#define dprintf_clipboard fprintf
@ -626,8 +674,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_clipping if(!debug_msg_enabled[8]) ; else fprintf
#define debugging_clipping debug_msg_enabled[8]
#define dprintf_clipping if(!debug_msg_enabled[9]) ; else fprintf
#define debugging_clipping debug_msg_enabled[9]
#else
#ifdef DEBUG_CLIPPING
#define dprintf_clipping fprintf
@ -639,8 +687,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_combo if(!debug_msg_enabled[9]) ; else fprintf
#define debugging_combo debug_msg_enabled[9]
#define dprintf_combo if(!debug_msg_enabled[10]) ; else fprintf
#define debugging_combo debug_msg_enabled[10]
#else
#ifdef DEBUG_COMBO
#define dprintf_combo fprintf
@ -652,8 +700,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_comm if(!debug_msg_enabled[10]) ; else fprintf
#define debugging_comm debug_msg_enabled[10]
#define dprintf_comm if(!debug_msg_enabled[11]) ; else fprintf
#define debugging_comm debug_msg_enabled[11]
#else
#ifdef DEBUG_COMM
#define dprintf_comm fprintf
@ -665,8 +713,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_cursor if(!debug_msg_enabled[11]) ; else fprintf
#define debugging_cursor debug_msg_enabled[11]
#define dprintf_cursor if(!debug_msg_enabled[12]) ; else fprintf
#define debugging_cursor debug_msg_enabled[12]
#else
#ifdef DEBUG_CURSOR
#define dprintf_cursor fprintf
@ -678,8 +726,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_dc if(!debug_msg_enabled[12]) ; else fprintf
#define debugging_dc debug_msg_enabled[12]
#define dprintf_dc if(!debug_msg_enabled[13]) ; else fprintf
#define debugging_dc debug_msg_enabled[13]
#else
#ifdef DEBUG_DC
#define dprintf_dc fprintf
@ -691,8 +739,21 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_dialog if(!debug_msg_enabled[13]) ; else fprintf
#define debugging_dialog debug_msg_enabled[13]
#define dprintf_dde if(!debug_msg_enabled[14]) ; else fprintf
#define debugging_dde debug_msg_enabled[14]
#else
#ifdef DEBUG_DDE
#define dprintf_dde fprintf
#define debugging_dde 1
#else
#define dprintf_dde while(0) fprintf
#define debugging_dde 0
#endif
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_dialog if(!debug_msg_enabled[15]) ; else fprintf
#define debugging_dialog debug_msg_enabled[15]
#else
#ifdef DEBUG_DIALOG
#define dprintf_dialog fprintf
@ -704,8 +765,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_dll if(!debug_msg_enabled[14]) ; else fprintf
#define debugging_dll debug_msg_enabled[14]
#define dprintf_dll if(!debug_msg_enabled[16]) ; else fprintf
#define debugging_dll debug_msg_enabled[16]
#else
#ifdef DEBUG_DLL
#define dprintf_dll fprintf
@ -717,8 +778,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_dosfs if(!debug_msg_enabled[15]) ; else fprintf
#define debugging_dosfs debug_msg_enabled[15]
#define dprintf_dosfs if(!debug_msg_enabled[17]) ; else fprintf
#define debugging_dosfs debug_msg_enabled[17]
#else
#ifdef DEBUG_DOSFS
#define dprintf_dosfs fprintf
@ -730,8 +791,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_driver if(!debug_msg_enabled[16]) ; else fprintf
#define debugging_driver debug_msg_enabled[16]
#define dprintf_driver if(!debug_msg_enabled[18]) ; else fprintf
#define debugging_driver debug_msg_enabled[18]
#else
#ifdef DEBUG_DRIVER
#define dprintf_driver fprintf
@ -743,8 +804,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_edit if(!debug_msg_enabled[17]) ; else fprintf
#define debugging_edit debug_msg_enabled[17]
#define dprintf_edit if(!debug_msg_enabled[19]) ; else fprintf
#define debugging_edit debug_msg_enabled[19]
#else
#ifdef DEBUG_EDIT
#define dprintf_edit fprintf
@ -756,8 +817,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_enum if(!debug_msg_enabled[18]) ; else fprintf
#define debugging_enum debug_msg_enabled[18]
#define dprintf_enum if(!debug_msg_enabled[20]) ; else fprintf
#define debugging_enum debug_msg_enabled[20]
#else
#ifdef DEBUG_ENUM
#define dprintf_enum fprintf
@ -769,8 +830,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_event if(!debug_msg_enabled[19]) ; else fprintf
#define debugging_event debug_msg_enabled[19]
#define dprintf_event if(!debug_msg_enabled[21]) ; else fprintf
#define debugging_event debug_msg_enabled[21]
#else
#ifdef DEBUG_EVENT
#define dprintf_event fprintf
@ -782,8 +843,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_exec if(!debug_msg_enabled[20]) ; else fprintf
#define debugging_exec debug_msg_enabled[20]
#define dprintf_exec if(!debug_msg_enabled[22]) ; else fprintf
#define debugging_exec debug_msg_enabled[22]
#else
#ifdef DEBUG_EXEC
#define dprintf_exec fprintf
@ -795,8 +856,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_file if(!debug_msg_enabled[21]) ; else fprintf
#define debugging_file debug_msg_enabled[21]
#define dprintf_file if(!debug_msg_enabled[23]) ; else fprintf
#define debugging_file debug_msg_enabled[23]
#else
#ifdef DEBUG_FILE
#define dprintf_file fprintf
@ -808,8 +869,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_fixup if(!debug_msg_enabled[22]) ; else fprintf
#define debugging_fixup debug_msg_enabled[22]
#define dprintf_fixup if(!debug_msg_enabled[24]) ; else fprintf
#define debugging_fixup debug_msg_enabled[24]
#else
#ifdef DEBUG_FIXUP
#define dprintf_fixup fprintf
@ -821,8 +882,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_font if(!debug_msg_enabled[23]) ; else fprintf
#define debugging_font debug_msg_enabled[23]
#define dprintf_font if(!debug_msg_enabled[25]) ; else fprintf
#define debugging_font debug_msg_enabled[25]
#else
#ifdef DEBUG_FONT
#define dprintf_font fprintf
@ -834,8 +895,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_gdi if(!debug_msg_enabled[24]) ; else fprintf
#define debugging_gdi debug_msg_enabled[24]
#define dprintf_gdi if(!debug_msg_enabled[26]) ; else fprintf
#define debugging_gdi debug_msg_enabled[26]
#else
#ifdef DEBUG_GDI
#define dprintf_gdi fprintf
@ -847,8 +908,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_global if(!debug_msg_enabled[25]) ; else fprintf
#define debugging_global debug_msg_enabled[25]
#define dprintf_global if(!debug_msg_enabled[27]) ; else fprintf
#define debugging_global debug_msg_enabled[27]
#else
#ifdef DEBUG_GLOBAL
#define dprintf_global fprintf
@ -860,8 +921,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_graphics if(!debug_msg_enabled[26]) ; else fprintf
#define debugging_graphics debug_msg_enabled[26]
#define dprintf_graphics if(!debug_msg_enabled[28]) ; else fprintf
#define debugging_graphics debug_msg_enabled[28]
#else
#ifdef DEBUG_GRAPHICS
#define dprintf_graphics fprintf
@ -873,8 +934,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_icon if(!debug_msg_enabled[27]) ; else fprintf
#define debugging_icon debug_msg_enabled[27]
#define dprintf_icon if(!debug_msg_enabled[29]) ; else fprintf
#define debugging_icon debug_msg_enabled[29]
#else
#ifdef DEBUG_ICON
#define dprintf_icon fprintf
@ -886,8 +947,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_int if(!debug_msg_enabled[28]) ; else fprintf
#define debugging_int debug_msg_enabled[28]
#define dprintf_int if(!debug_msg_enabled[30]) ; else fprintf
#define debugging_int debug_msg_enabled[30]
#else
#ifdef DEBUG_INT
#define dprintf_int fprintf
@ -899,8 +960,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_key if(!debug_msg_enabled[29]) ; else fprintf
#define debugging_key debug_msg_enabled[29]
#define dprintf_key if(!debug_msg_enabled[31]) ; else fprintf
#define debugging_key debug_msg_enabled[31]
#else
#ifdef DEBUG_KEY
#define dprintf_key fprintf
@ -912,8 +973,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_keyboard if(!debug_msg_enabled[30]) ; else fprintf
#define debugging_keyboard debug_msg_enabled[30]
#define dprintf_keyboard if(!debug_msg_enabled[32]) ; else fprintf
#define debugging_keyboard debug_msg_enabled[32]
#else
#ifdef DEBUG_KEYBOARD
#define dprintf_keyboard fprintf
@ -925,8 +986,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_ldt if(!debug_msg_enabled[31]) ; else fprintf
#define debugging_ldt debug_msg_enabled[31]
#define dprintf_ldt if(!debug_msg_enabled[33]) ; else fprintf
#define debugging_ldt debug_msg_enabled[33]
#else
#ifdef DEBUG_LDT
#define dprintf_ldt fprintf
@ -938,8 +999,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_listbox if(!debug_msg_enabled[32]) ; else fprintf
#define debugging_listbox debug_msg_enabled[32]
#define dprintf_listbox if(!debug_msg_enabled[34]) ; else fprintf
#define debugging_listbox debug_msg_enabled[34]
#else
#ifdef DEBUG_LISTBOX
#define dprintf_listbox fprintf
@ -951,8 +1012,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_local if(!debug_msg_enabled[33]) ; else fprintf
#define debugging_local debug_msg_enabled[33]
#define dprintf_local if(!debug_msg_enabled[35]) ; else fprintf
#define debugging_local debug_msg_enabled[35]
#else
#ifdef DEBUG_LOCAL
#define dprintf_local fprintf
@ -964,8 +1025,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_malloc if(!debug_msg_enabled[34]) ; else fprintf
#define debugging_malloc debug_msg_enabled[34]
#define dprintf_malloc if(!debug_msg_enabled[36]) ; else fprintf
#define debugging_malloc debug_msg_enabled[36]
#else
#ifdef DEBUG_MALLOC
#define dprintf_malloc fprintf
@ -977,8 +1038,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_mci if(!debug_msg_enabled[35]) ; else fprintf
#define debugging_mci debug_msg_enabled[35]
#define dprintf_mci if(!debug_msg_enabled[37]) ; else fprintf
#define debugging_mci debug_msg_enabled[37]
#else
#ifdef DEBUG_MCI
#define dprintf_mci fprintf
@ -990,8 +1051,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_mcianim if(!debug_msg_enabled[36]) ; else fprintf
#define debugging_mcianim debug_msg_enabled[36]
#define dprintf_mcianim if(!debug_msg_enabled[38]) ; else fprintf
#define debugging_mcianim debug_msg_enabled[38]
#else
#ifdef DEBUG_MCIANIM
#define dprintf_mcianim fprintf
@ -1003,8 +1064,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_mciwave if(!debug_msg_enabled[37]) ; else fprintf
#define debugging_mciwave debug_msg_enabled[37]
#define dprintf_mciwave if(!debug_msg_enabled[39]) ; else fprintf
#define debugging_mciwave debug_msg_enabled[39]
#else
#ifdef DEBUG_MCIWAVE
#define dprintf_mciwave fprintf
@ -1016,8 +1077,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_mdi if(!debug_msg_enabled[38]) ; else fprintf
#define debugging_mdi debug_msg_enabled[38]
#define dprintf_mdi if(!debug_msg_enabled[40]) ; else fprintf
#define debugging_mdi debug_msg_enabled[40]
#else
#ifdef DEBUG_MDI
#define dprintf_mdi fprintf
@ -1029,8 +1090,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_menu if(!debug_msg_enabled[39]) ; else fprintf
#define debugging_menu debug_msg_enabled[39]
#define dprintf_menu if(!debug_msg_enabled[41]) ; else fprintf
#define debugging_menu debug_msg_enabled[41]
#else
#ifdef DEBUG_MENU
#define dprintf_menu fprintf
@ -1042,8 +1103,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_menucalc if(!debug_msg_enabled[40]) ; else fprintf
#define debugging_menucalc debug_msg_enabled[40]
#define dprintf_menucalc if(!debug_msg_enabled[42]) ; else fprintf
#define debugging_menucalc debug_msg_enabled[42]
#else
#ifdef DEBUG_MENUCALC
#define dprintf_menucalc fprintf
@ -1055,8 +1116,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_message if(!debug_msg_enabled[41]) ; else fprintf
#define debugging_message debug_msg_enabled[41]
#define dprintf_message if(!debug_msg_enabled[43]) ; else fprintf
#define debugging_message debug_msg_enabled[43]
#else
#ifdef DEBUG_MESSAGE
#define dprintf_message fprintf
@ -1068,8 +1129,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_metafile if(!debug_msg_enabled[42]) ; else fprintf
#define debugging_metafile debug_msg_enabled[42]
#define dprintf_metafile if(!debug_msg_enabled[44]) ; else fprintf
#define debugging_metafile debug_msg_enabled[44]
#else
#ifdef DEBUG_METAFILE
#define dprintf_metafile fprintf
@ -1081,8 +1142,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_midi if(!debug_msg_enabled[43]) ; else fprintf
#define debugging_midi debug_msg_enabled[43]
#define dprintf_midi if(!debug_msg_enabled[45]) ; else fprintf
#define debugging_midi debug_msg_enabled[45]
#else
#ifdef DEBUG_MIDI
#define dprintf_midi fprintf
@ -1094,8 +1155,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_mmio if(!debug_msg_enabled[44]) ; else fprintf
#define debugging_mmio debug_msg_enabled[44]
#define dprintf_mmio if(!debug_msg_enabled[46]) ; else fprintf
#define debugging_mmio debug_msg_enabled[46]
#else
#ifdef DEBUG_MMIO
#define dprintf_mmio fprintf
@ -1107,8 +1168,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_mmsys if(!debug_msg_enabled[45]) ; else fprintf
#define debugging_mmsys debug_msg_enabled[45]
#define dprintf_mmsys if(!debug_msg_enabled[47]) ; else fprintf
#define debugging_mmsys debug_msg_enabled[47]
#else
#ifdef DEBUG_MMSYS
#define dprintf_mmsys fprintf
@ -1120,8 +1181,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_mmtime if(!debug_msg_enabled[46]) ; else fprintf
#define debugging_mmtime debug_msg_enabled[46]
#define dprintf_mmtime if(!debug_msg_enabled[48]) ; else fprintf
#define debugging_mmtime debug_msg_enabled[48]
#else
#ifdef DEBUG_MMTIME
#define dprintf_mmtime fprintf
@ -1133,8 +1194,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_module if(!debug_msg_enabled[47]) ; else fprintf
#define debugging_module debug_msg_enabled[47]
#define dprintf_module if(!debug_msg_enabled[49]) ; else fprintf
#define debugging_module debug_msg_enabled[49]
#else
#ifdef DEBUG_MODULE
#define dprintf_module fprintf
@ -1146,8 +1207,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_msg if(!debug_msg_enabled[48]) ; else fprintf
#define debugging_msg debug_msg_enabled[48]
#define dprintf_msg if(!debug_msg_enabled[50]) ; else fprintf
#define debugging_msg debug_msg_enabled[50]
#else
#ifdef DEBUG_MSG
#define dprintf_msg fprintf
@ -1159,8 +1220,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_nonclient if(!debug_msg_enabled[49]) ; else fprintf
#define debugging_nonclient debug_msg_enabled[49]
#define dprintf_nonclient if(!debug_msg_enabled[51]) ; else fprintf
#define debugging_nonclient debug_msg_enabled[51]
#else
#ifdef DEBUG_NONCLIENT
#define dprintf_nonclient fprintf
@ -1172,8 +1233,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_ole if(!debug_msg_enabled[50]) ; else fprintf
#define debugging_ole debug_msg_enabled[50]
#define dprintf_ole if(!debug_msg_enabled[52]) ; else fprintf
#define debugging_ole debug_msg_enabled[52]
#else
#ifdef DEBUG_OLE
#define dprintf_ole fprintf
@ -1185,8 +1246,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_palette if(!debug_msg_enabled[51]) ; else fprintf
#define debugging_palette debug_msg_enabled[51]
#define dprintf_palette if(!debug_msg_enabled[53]) ; else fprintf
#define debugging_palette debug_msg_enabled[53]
#else
#ifdef DEBUG_PALETTE
#define dprintf_palette fprintf
@ -1198,8 +1259,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_profile if(!debug_msg_enabled[52]) ; else fprintf
#define debugging_profile debug_msg_enabled[52]
#define dprintf_profile if(!debug_msg_enabled[54]) ; else fprintf
#define debugging_profile debug_msg_enabled[54]
#else
#ifdef DEBUG_PROFILE
#define dprintf_profile fprintf
@ -1211,8 +1272,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_prop if(!debug_msg_enabled[53]) ; else fprintf
#define debugging_prop debug_msg_enabled[53]
#define dprintf_prop if(!debug_msg_enabled[55]) ; else fprintf
#define debugging_prop debug_msg_enabled[55]
#else
#ifdef DEBUG_PROP
#define dprintf_prop fprintf
@ -1224,8 +1285,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_reg if(!debug_msg_enabled[54]) ; else fprintf
#define debugging_reg debug_msg_enabled[54]
#define dprintf_reg if(!debug_msg_enabled[56]) ; else fprintf
#define debugging_reg debug_msg_enabled[56]
#else
#ifdef DEBUG_REG
#define dprintf_reg fprintf
@ -1237,8 +1298,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_region if(!debug_msg_enabled[55]) ; else fprintf
#define debugging_region debug_msg_enabled[55]
#define dprintf_region if(!debug_msg_enabled[57]) ; else fprintf
#define debugging_region debug_msg_enabled[57]
#else
#ifdef DEBUG_REGION
#define dprintf_region fprintf
@ -1250,8 +1311,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_relay if(!debug_msg_enabled[56]) ; else fprintf
#define debugging_relay debug_msg_enabled[56]
#define dprintf_relay if(!debug_msg_enabled[58]) ; else fprintf
#define debugging_relay debug_msg_enabled[58]
#else
#ifdef DEBUG_RELAY
#define dprintf_relay fprintf
@ -1263,8 +1324,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_resource if(!debug_msg_enabled[57]) ; else fprintf
#define debugging_resource debug_msg_enabled[57]
#define dprintf_resource if(!debug_msg_enabled[59]) ; else fprintf
#define debugging_resource debug_msg_enabled[59]
#else
#ifdef DEBUG_RESOURCE
#define dprintf_resource fprintf
@ -1276,8 +1337,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_scroll if(!debug_msg_enabled[58]) ; else fprintf
#define debugging_scroll debug_msg_enabled[58]
#define dprintf_scroll if(!debug_msg_enabled[60]) ; else fprintf
#define debugging_scroll debug_msg_enabled[60]
#else
#ifdef DEBUG_SCROLL
#define dprintf_scroll fprintf
@ -1289,8 +1350,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_selector if(!debug_msg_enabled[59]) ; else fprintf
#define debugging_selector debug_msg_enabled[59]
#define dprintf_selector if(!debug_msg_enabled[61]) ; else fprintf
#define debugging_selector debug_msg_enabled[61]
#else
#ifdef DEBUG_SELECTOR
#define dprintf_selector fprintf
@ -1302,8 +1363,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_selectors if(!debug_msg_enabled[60]) ; else fprintf
#define debugging_selectors debug_msg_enabled[60]
#define dprintf_selectors if(!debug_msg_enabled[62]) ; else fprintf
#define debugging_selectors debug_msg_enabled[62]
#else
#ifdef DEBUG_SELECTORS
#define dprintf_selectors fprintf
@ -1315,8 +1376,47 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_stress if(!debug_msg_enabled[61]) ; else fprintf
#define debugging_stress debug_msg_enabled[61]
#define dprintf_sem if(!debug_msg_enabled[63]) ; else fprintf
#define debugging_sem debug_msg_enabled[63]
#else
#ifdef DEBUG_SEM
#define dprintf_sem fprintf
#define debugging_sem 1
#else
#define dprintf_sem while(0) fprintf
#define debugging_sem 0
#endif
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_shm if(!debug_msg_enabled[64]) ; else fprintf
#define debugging_shm debug_msg_enabled[64]
#else
#ifdef DEBUG_SHM
#define dprintf_shm fprintf
#define debugging_shm 1
#else
#define dprintf_shm while(0) fprintf
#define debugging_shm 0
#endif
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_spy if(!debug_msg_enabled[65]) ; else fprintf
#define debugging_spy debug_msg_enabled[65]
#else
#ifdef DEBUG_SPY
#define dprintf_spy fprintf
#define debugging_spy 1
#else
#define dprintf_spy while(0) fprintf
#define debugging_spy 0
#endif
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_stress if(!debug_msg_enabled[66]) ; else fprintf
#define debugging_stress debug_msg_enabled[66]
#else
#ifdef DEBUG_STRESS
#define dprintf_stress fprintf
@ -1328,8 +1428,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_syscolor if(!debug_msg_enabled[62]) ; else fprintf
#define debugging_syscolor debug_msg_enabled[62]
#define dprintf_syscolor if(!debug_msg_enabled[67]) ; else fprintf
#define debugging_syscolor debug_msg_enabled[67]
#else
#ifdef DEBUG_SYSCOLOR
#define dprintf_syscolor fprintf
@ -1341,8 +1441,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_task if(!debug_msg_enabled[63]) ; else fprintf
#define debugging_task debug_msg_enabled[63]
#define dprintf_task if(!debug_msg_enabled[68]) ; else fprintf
#define debugging_task debug_msg_enabled[68]
#else
#ifdef DEBUG_TASK
#define dprintf_task fprintf
@ -1354,8 +1454,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_text if(!debug_msg_enabled[64]) ; else fprintf
#define debugging_text debug_msg_enabled[64]
#define dprintf_text if(!debug_msg_enabled[69]) ; else fprintf
#define debugging_text debug_msg_enabled[69]
#else
#ifdef DEBUG_TEXT
#define dprintf_text fprintf
@ -1367,8 +1467,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_timer if(!debug_msg_enabled[65]) ; else fprintf
#define debugging_timer debug_msg_enabled[65]
#define dprintf_timer if(!debug_msg_enabled[70]) ; else fprintf
#define debugging_timer debug_msg_enabled[70]
#else
#ifdef DEBUG_TIMER
#define dprintf_timer fprintf
@ -1380,8 +1480,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_toolhelp if(!debug_msg_enabled[66]) ; else fprintf
#define debugging_toolhelp debug_msg_enabled[66]
#define dprintf_toolhelp if(!debug_msg_enabled[71]) ; else fprintf
#define debugging_toolhelp debug_msg_enabled[71]
#else
#ifdef DEBUG_TOOLHELP
#define dprintf_toolhelp fprintf
@ -1393,8 +1493,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_utility if(!debug_msg_enabled[67]) ; else fprintf
#define debugging_utility debug_msg_enabled[67]
#define dprintf_utility if(!debug_msg_enabled[72]) ; else fprintf
#define debugging_utility debug_msg_enabled[72]
#else
#ifdef DEBUG_UTILITY
#define dprintf_utility fprintf
@ -1406,8 +1506,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_win if(!debug_msg_enabled[68]) ; else fprintf
#define debugging_win debug_msg_enabled[68]
#define dprintf_win if(!debug_msg_enabled[73]) ; else fprintf
#define debugging_win debug_msg_enabled[73]
#else
#ifdef DEBUG_WIN
#define dprintf_win fprintf
@ -1419,8 +1519,8 @@ extern short debug_msg_enabled[];
#endif
#ifdef DEBUG_RUNTIME
#define dprintf_winsock if(!debug_msg_enabled[69]) ; else fprintf
#define debugging_winsock debug_msg_enabled[69]
#define dprintf_winsock if(!debug_msg_enabled[74]) ; else fprintf
#define debugging_winsock debug_msg_enabled[74]
#else
#ifdef DEBUG_WINSOCK
#define dprintf_winsock fprintf
@ -1436,6 +1536,7 @@ extern short debug_msg_enabled[];
#ifdef DEBUG_DEFINE_VARIABLES
static char *debug_msg_name[] = {
"accel",
"atom",
"bitblt",
"bitmap",
"caret",
@ -1448,6 +1549,7 @@ static char *debug_msg_name[] = {
"comm",
"cursor",
"dc",
"dde",
"dialog",
"dll",
"dosfs",
@ -1496,6 +1598,9 @@ static char *debug_msg_name[] = {
"scroll",
"selector",
"selectors",
"sem",
"shm",
"spy",
"stress",
"syscolor",
"task",

View File

@ -10,10 +10,9 @@ extern int DOS_GetDefaultDrive(void);
extern void DOS_SetDefaultDrive(int drive);
extern void ToUnix(char *s);
extern void ToDos(char *s);
extern void ChopOffSlash(char *string);
extern int DOS_DisableDrive(int drive);
extern int DOS_EnableDrive(int drive);
extern char *DOS_GetUnixFileName(char *dosfilename);
extern char *DOS_GetUnixFileName(const char *dosfilename);
extern char *DOS_GetDosFileName(char *unixfilename);
extern char *DOS_GetCurrentDir(int drive);
extern int DOS_ChangeDir(int drive, char *dirname);
@ -29,8 +28,6 @@ extern char *WinIniFileName(void);
extern struct dosdirent *DOS_opendir(char *dosdirname);
extern struct dosdirent *DOS_readdir(struct dosdirent *de);
extern void DOS_closedir(struct dosdirent *de);
extern void DOS_ExpandToFullPath(char *filename, int drive);
extern void DOS_ExpandToFullUnixPath(char *filename);
extern char *DOS_GetRedirectedDir(int drive);
extern void errno_to_doserr(void);

View File

@ -9,9 +9,17 @@
#include "wintypes.h"
typedef struct
{
HGLOBAL handle;
WORD sel;
int shmid;
} SHMDATA;
extern HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
HGLOBAL hOwner, BOOL isCode,
BOOL is32Bit, BOOL isReadOnly );
BOOL is32Bit, BOOL isReadOnly,
SHMDATA *shmdata);
extern BOOL GLOBAL_FreeBlock( HGLOBAL handle );
extern HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
BOOL isCode, BOOL is32Bit, BOOL isReadOnly );

View File

@ -44,13 +44,13 @@ typedef struct
extern ldt_copy_entry ldt_copy[LDT_SIZE];
#define __AHSHIFT 3
#define __AHSHIFT 3 /* don't change! */
#define __AHINCR (1 << __AHSHIFT)
#ifndef WINELIB
#define SELECTOR_TO_ENTRY(sel) (((int)(sel) & 0xffff) >> __AHSHIFT)
#define ENTRY_TO_SELECTOR(i) ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0)
#define IS_LDT_ENTRY_FREE(i) (!(ldt_copy[(i)].base || ldt_copy[(i)].limit))
#define IS_LDT_ENTRY_FREE(i) (!(ldt_flags_copy[(i)] & LDT_FLAGS_ALLOCATED))
#define IS_SELECTOR_FREE(sel) (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)))
#define GET_SEL_BASE(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
#define GET_SEL_LIMIT(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
@ -59,6 +59,7 @@ extern ldt_copy_entry ldt_copy[LDT_SIZE];
#define SELECTOR_TO_ENTRY(sel) error.error
#define ENTRY_TO_SELECTOR(i) error.error
#define IS_LDT_ENTRY_FREE(i) error.error
#define IS_SELECTOR_FREE(sel) error.error
#define GET_SEL_BASE(sel) error.error
#define GET_SEL_LIMIT(sel) error.error
#endif
@ -83,6 +84,7 @@ extern unsigned char ldt_flags_copy[LDT_SIZE];
#define LDT_FLAGS_EXECONLY 0x04 /* Segment is execute-only (code) */
#define LDT_FLAGS_32BIT 0x08 /* Segment is 32-bit (code or stack) */
#define LDT_FLAGS_BIG 0x10 /* Segment is big (limit is in pages) */
#define LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
#define GET_SEL_FLAGS(sel) (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)])

View File

@ -4,31 +4,10 @@
#include "wintypes.h"
#include "wine.h"
extern BOOL INSTR_HandleInstruction( struct sigcontext_struct *context );
extern BOOL INSTR_EmulateInstruction( struct sigcontext_struct *context );
extern int do_int10(struct sigcontext_struct *);
extern int do_int13(struct sigcontext_struct *);
extern int do_int15(struct sigcontext_struct *);
extern int do_int16(struct sigcontext_struct *);
extern int do_int1a(struct sigcontext_struct *);
extern int do_int21(struct sigcontext_struct *);
extern int do_int25(struct sigcontext_struct *);
extern int do_int26(struct sigcontext_struct *);
extern int do_int2a(struct sigcontext_struct *);
extern int do_int2f(struct sigcontext_struct *);
extern int do_int31(struct sigcontext_struct *);
extern int do_int5c(struct sigcontext_struct *);
extern void inportb( struct sigcontext_struct *context );
extern void inport( struct sigcontext_struct *context, int long_op );
extern void outportb( struct sigcontext_struct *context );
extern void outport( struct sigcontext_struct *context, int long_op );
extern void inportb_abs( struct sigcontext_struct *context);
extern void inport_abs( struct sigcontext_struct *context, int long_op );
extern void outportb_abs( struct sigcontext_struct *context );
extern void outport_abs( struct sigcontext_struct *context, int long_op );
extern void IntBarf(int i, struct sigcontext_struct *context);
extern DWORD inport( int port, int count );
extern void outport( int port, int count, DWORD value );
extern BOOL INT_Init(void);
extern SEGPTR INT_GetHandler( BYTE intnum );
@ -36,4 +15,11 @@ extern void INT_SetHandler( BYTE intnum, SEGPTR handler );
extern void INT21_Init(void);
#define INT_BARF(num) \
fprintf( stderr, "int%x: unknown/not implemented parameters:\n" \
"int%x: AX %04x, BX %04x, CX %04x, DX %04x, " \
"SI %04x, DI %04x, DS %04x, ES %04x\n", \
(num), (num), AX, BX, CX, DX, SI, DI, DS, ES )
#endif /* __WINE_MISCEMU_H */

View File

@ -40,21 +40,23 @@ extern WORD ExtendedError;
extern struct DosDeviceStruct COM[MAX_PORTS];
extern struct DosDeviceStruct LPT[MAX_PORTS];
#define setword(a,b) *(BYTE*)(a) = (b) & 0xff; \
*((BYTE*)((a)+1)) = ((b)>>8) & 0xff;
#define setword(a,b) do { *(BYTE*)(a) = (b) & 0xff; \
*((BYTE*)((a)+1)) = ((b)>>8) & 0xff;\
} while(0)
#define setdword(a,b) *(BYTE*)(a) = (b) & 0xff; \
*((BYTE*)(a)+1) = ((b)>>8) & 0xff; \
*((BYTE*)(a)+2) = ((b)>>16) & 0xff; \
*((BYTE*)(a)+3) = ((b)>>24) & 0xff;
#define setdword(a,b) do { *(BYTE*)(a) = (b) & 0xff; \
*((BYTE*)(a)+1) = ((b)>>8) & 0xff; \
*((BYTE*)(a)+2) = ((b)>>16) & 0xff; \
*((BYTE*)(a)+3) = ((b)>>24) & 0xff; \
} while(0)
#define getword(a) (WORD) *(BYTE*)(a) + \
(*((BYTE*)(a) + 1) << 8)
#define getword(a) ( (WORD)*(BYTE*)(a) + \
((WORD)*((BYTE*)(a) + 1) << 8))
#define getdword(a) (DWORD) (*(BYTE*)(a) + \
(*((BYTE*)(a) + 1) << 8) + \
(*((BYTE*)(a) + 2) << 16) + \
(*((BYTE*)(a) + 3) << 24))
#define getdword(a) ( (DWORD)*(BYTE*)(a) + \
(DWORD)(*((BYTE*)(a) + 1) << 8) + \
(DWORD)(*((BYTE*)(a) + 2) << 16) + \
(DWORD)(*((BYTE*)(a) + 3) << 24))
/* dos file attributes */

View File

@ -9,7 +9,6 @@
struct options
{
char * spyFilename;
char * desktopGeometry; /* NULL when no desktop */
char * programName; /* To use when loading resources */
int usePrivateMap;

View File

@ -1,6 +1,7 @@
#ifndef __WINE_PE_IMAGE_H
#define __WINE_PE_IMAGE_H
extern void *RELAY32_GetEntryPoint(char *dll_name, char *item, int hint);
extern int PE_unloadImage(struct w_files *wpnt);
extern int PE_StartProgram(struct w_files *wpnt);
extern void PE_InitDLL(struct w_files *wpnt);

View File

@ -1,33 +0,0 @@
/* $Id: prototypes.h,v 1.3 1993/07/04 04:04:21 root Exp root $
*/
/*
* Copyright Robert J. Amstadt, 1993
*/
#ifndef _WINE_PROTOTYPES_H
#define _WINE_PROTOTYPES_H
#include <sys/types.h>
#include "windows.h"
#ifndef WINELIB
/* loader/resource.c */
extern HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image );
extern HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image );
/* loader/signal.c */
extern void init_wine_signals(void);
/* loader/wine.c */
extern int _WinMain(int argc, char **argv);
/* misc/spy.c */
extern void SpyInit(void);
#endif /* WINELIB */
#endif /* _WINE_PROTOTYPES_H */

View File

@ -18,5 +18,6 @@ typedef struct
extern BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj );
extern BOOL REGION_FrameRgn(HRGN dest,HRGN src,int x,int y);
#endif /* __WINE_REGION_H */

View File

@ -37,6 +37,14 @@
#define ES (context->sc_es)
#define SS (context->sc_ss)
#ifdef linux
#define FS (context->sc_fs)
#define GS (context->sc_gs)
#else /* FIXME: are fs and gs supported under *BSD? */
#define FS 0
#define GS 0
#endif
#ifndef __FreeBSD__
#define EFL (context->sc_eflags)
#define FL (*(WORD*)&context->sc_eflags)

View File

@ -17,6 +17,9 @@ extern SEGPTR NE_LockResource( HMODULE hModule, HGLOBAL handle );
extern HGLOBAL NE_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size );
extern HGLOBAL NE_LoadResource( HMODULE hModule, HRSRC hRsrc );
extern HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image );
extern HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image );
struct ResourceTable
{
int id,type;

View File

@ -2,6 +2,8 @@
* Shell Library definitions
*/
extern INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon);
#define ERROR_SUCCESS 0L
#define ERROR_BADDB 1L
#define ERROR_BADKEY 2L

86
include/shm_block.h Normal file
View File

@ -0,0 +1,86 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_block.ch
* Purpose: treat a shared memory block.
***************************************************************************
*/
#ifndef __WINE_SHM_BLOCK_H
#define __WINE_SHM_BLOCK_H
#include <sys/shm.h>
#include "wintypes.h"
#define SEGSIZE 0x10000 /* 64 */
#define SHM_GRANULARITY SEGSIZE
#define SHM_MINBLOCK SHM_GRANULARITY
#define SHM_MAXBLOCK (((int)SHMMAX/(int)SHM_GRANULARITY)* \
SHM_GRANULARITY)
#define PTR2REL(block,ptr) (REL_PTR) ( (char *) (ptr) - (char *) (block) )
#define REL2PTR(block,rel) (void *) ( (char *) (block) + (rel) )
typedef int REL_PTR;
/* full info for each shm block. */
struct shm_block {
/* private */
int next_shm_id; /* IPC shm ID (for initial linking) */
/* public (read only) */
int size; /* size of the shm block */
int free; /* how much of the block is free */
int proc_idx; /* The index of the owner */
/* public - writable for shm_fragment */
REL_PTR free_list; /* first item in the free list */
};
/* used for mapping local attachments */
struct local_shm_map {
struct local_shm_map *next;
int shm_id;
int proc_idx;
/* 32 bit pointer to the beginning of the block */
struct shm_block *ptr;
};
extern struct local_shm_map *shm_map;
void shm_setup_block(struct shm_block *block, REL_PTR first, int size);
/* shm_create_block:
* allocate and setup a new block:
* first - first non header byte.
* size - block size (in bytes).
* shm_id- IPC shared memory ID.
*/
struct shm_block *shm_create_block(REL_PTR first, int size, int *shm_id);
/* shm_locate_block:
* locate existing block according to shm_id,
* Attach the block if needed. Assume the shm_id is wine's
* Set selectors also.
*/
struct shm_block *shm_locate_block(int shm_id, struct local_shm_map *map);
/* shm_locate_attached_block:
* locate existing block according to shm_id,
* Blocks are never attached.
* if proc_idx is not NULL, it will be set to owner's index.
* map - localy mapped info about block may be NULL;
*/
struct shm_block *shm_locate_attached_block(int shm_id,
struct local_shm_map *map);
/* shm_attach_block: attach existing shm block, setup selectors
* shm_id - id of the block to attach.
* proc_idx - if not -1, puts this data into local mapping
* map - localy mapped info about this block. (may be NULL)
* NOTE: same block can be attached many times
*/
struct shm_block *shm_attach_block(int shm_id, int proc_idx,
struct local_shm_map *map);
/* delete chain of shm blocks (pointing to each other */
void shm_delete_chain(int *shmid);
#endif /* __WINE_SHM_BLOCK_H */

47
include/shm_fragment.h Normal file
View File

@ -0,0 +1,47 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_fragment.h
* Purpose: Data fragments and free list items. Allocate and free blocks.
***************************************************************************
*/
#ifndef __WINE_SHM_FRAGMENT_H
#define __WINE_SHM_FRAGMENT_H
#include "shm_block.h"
#define NIL ((int) 0)
/* memory fragment: used or free (when free - it's an item of "free list",
* when allocated it contains the data, and it's size)
*/
struct shm_fragment {
int size; /* fragment's size */
/* The type of info depends on fragment's status (free/allocated) */
union info {
int next; /* next free fragment */
char data[1]; /* the data */
} info;
};
/* setup first item in the free list */
void shm_FragmentInit(struct shm_block *block,REL_PTR first,int size);
/* allocate shm fragment. return: offset to data in fragment, or NULL */
REL_PTR shm_FragmentAlloc(struct shm_block *block, int size);
/* like shm_FragmentAlloc, returns pointer instead of offset */
char *shm_FragPtrAlloc(struct shm_block *block, int size);
/* free shm fragment - according to offset */
void shm_FragmentFree(struct shm_block *block, int ofs);
/* free shm fragment - according to pointer */
void shm_FragPtrFree(struct shm_block *block, void *ptr);
/* This is used for debugging only */
void shm_print_free_list(struct shm_block *block);
#endif /* __WINE_SHM_FRAGMENT_H */

55
include/shm_main_blk.h Normal file
View File

@ -0,0 +1,55 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_main_blk.h
* Purpose: Main Wine's shared memory block
***************************************************************************
*/
#ifndef __WINE_SHM_MAIN_BLK_H
#define __WINE_SHM_MAIN_BLK_H
#include <sys/shm.h>
#include "shm_block.h"
#include "shm_semaph.h"
#include "dde_proc.h"
#include "dde_atom.h"
#include "dde_mem.h"
/*****************************************************************************
*
* main block object
*
*****************************************************************************
*/
#ifndef __inline__
#ifndef __GNUC__
#define __inline__
#endif /* __GNUC__ */
#endif /* __inline__ */
#define DDE_HANDLES_BIT_ARRAY_SIZE (DDE_HANDLES/sizeof(int)/8)
#define SHM_MAXID SHMSEG /* maximum shm blocks (Wine's limit) */
struct shm_main_block {
/* NOTE: "block" declaration must be the first */
struct shm_block block;
char magic[64]; /* magic string to identify the block */
int build_lock; /* =1 when data structure not stable yet */
shm_sem sem; /* semaphores for main_block integrity */
struct _dde_proc proc[DDE_PROCS]; /* information about processes */
REL_PTR atoms[DDE_ATOMS]; /* relative reference to global atoms */
/* Translation from global window handles to local handles */
WND_DATA windows[DDE_WINDOWS];
DDE_HWND handles[DDE_HANDLES];
/* bit array stating if a handle is free (bit=0), LSB in */
/* free_handles[0] refers handle 0x8000, the MSB refers 0x801F */
unsigned free_handles[DDE_HANDLES_BIT_ARRAY_SIZE];
};
extern struct shm_main_block *main_block;
int shm_init(void);
void shm_delete_all(int shm_id);
void DDE_mem_init();
int DDE_no_of_attached();
#define DDE_IPC_init() ( (main_block==NULL) ? (DDE_mem_init()) : 0 )
#endif /* __WINE_SHM_MAIN_BLK_H */

24
include/shm_semaph.h Normal file
View File

@ -0,0 +1,24 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_semaph.h
* Purpose: Handle semaphores for shared memory operations.
***************************************************************************
*/
#ifndef __WINE_SHM_SEMAPH_H
#define __WINE_SHM_SEMAPH_H
/* IMPORTANT: If possible, restrict usage of these functions. */
typedef int shm_sem;
void shm_read_wait(shm_sem semid);
void shm_write_wait(shm_sem semid);
void shm_write_signal(shm_sem semid);
void shm_read_signal(shm_sem semid);
void shm_sem_init(shm_sem *semptr);
void shm_sem_done(shm_sem *semptr);
#endif /* __WINE_SHM_SEMAPH_H */

View File

@ -19,6 +19,7 @@ typedef struct
{
WORD saved_ss; /* saved previous 16-bit stack */
WORD saved_sp;
WORD es;
WORD ds; /* 16-bit ds */
DWORD entry_point WINE_PACKED; /* entry point to call */
WORD ordinal_number; /* ordinal number of entry point */

View File

@ -77,6 +77,7 @@
#ifdef DEBUG_NONE
#undef DEBUG_ACCEL
#undef DEBUG_ATOM
#undef DEBUG_BITBLT
#undef DEBUG_BITMAP
#undef DEBUG_CARET
@ -89,6 +90,7 @@
#undef DEBUG_COMM
#undef DEBUG_CURSOR
#undef DEBUG_DC
#undef DEBUG_DDE
#undef DEBUG_DIALOG
#undef DEBUG_DLL
#undef DEBUG_DOSFS
@ -137,6 +139,9 @@
#undef DEBUG_SCROLL
#undef DEBUG_SELECTOR
#undef DEBUG_SELECTORS
#undef DEBUG_SEM
#undef DEBUG_SHM
#undef DEBUG_SPY
#undef DEBUG_STRESS
#undef DEBUG_SYSCOLOR
#undef DEBUG_TASK
@ -150,6 +155,7 @@
#ifdef DEBUG_ALL
#define DEBUG_ACCEL
#define DEBUG_ATOM
#define DEBUG_BITBLT
#define DEBUG_BITMAP
#define DEBUG_CARET
@ -162,6 +168,7 @@
#define DEBUG_COMM
#define DEBUG_CURSOR
#define DEBUG_DC
#define DEBUG_DDE
#define DEBUG_DIALOG
#define DEBUG_DLL
#define DEBUG_DOSFS
@ -210,6 +217,9 @@
#define DEBUG_SCROLL
#define DEBUG_SELECTOR
#define DEBUG_SELECTORS
#define DEBUG_SEM
#define DEBUG_SHM
#define DEBUG_SPY
#define DEBUG_STRESS
#define DEBUG_SYSCOLOR
#define DEBUG_TASK

View File

@ -13,6 +13,10 @@
#pragma pack(1)
#endif
extern BOOL TASK_Init(void);
extern void TASK_KillCurrentTask( int exitCode );
/* Process database (i.e. a normal DOS PSP) */
typedef struct

View File

@ -10,6 +10,7 @@
#include "ldt.h"
#include "local.h"
extern BOOL USER_HeapInit(void);
/* USER local heap */
#ifdef WINELIB

View File

@ -74,6 +74,7 @@ extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter );
extern HWND WIN_FindWinToRepaint( HWND hwnd );
extern void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam );
extern BOOL WIN_CreateDesktopWindow(void);
extern HWND WIN_GetTopParent( HWND hwnd );
extern Display * display;
extern Screen * screen;

View File

@ -2455,6 +2455,8 @@ Fa(DWORD,GetCurrentPosition,HDC,a)
Fa(DWORD,GetDCOrg,HDC,a)
Fa(DWORD,GetFreeSpace,WORD,a)
Fa(DWORD,GetHeapSpaces,HMODULE,a)
Fa(DWORD,GetSelectorBase,WORD,a)
Fa(DWORD,GetSelectorLimit,WORD,a)
Fa(DWORD,GetViewportExt,HDC,a)
Fa(DWORD,GetViewportOrg,HDC,a)
Fa(DWORD,GetWindowExt,HDC,a)
@ -2524,10 +2526,11 @@ Fa(LPSTR,GlobalLock,HGLOBAL,a)
Fa(LPSTR,LockResource,HANDLE,a)
Fa(SEGPTR,AnsiNext,SEGPTR,a)
Fa(SEGPTR,GlobalWire,HGLOBAL,a)
Fa(SEGPTR,WIN16_LockResource,HANDLE,a)
Fa(SEGPTR,WIN16_GlobalLock,HGLOBAL,a)
Fa(SEGPTR,WIN16_LockResource,HANDLE,a)
Fa(UINT,GDIRealizePalette,HDC,a)
Fa(UINT,RealizePalette,HDC,a)
Fa(WORD,AllocCStoDSAlias,WORD,a)
Fa(WORD,AllocDStoCSAlias,WORD,a)
Fa(WORD,AllocSelector,WORD,a)
Fa(WORD,AllocSelectorArray,WORD,a)
@ -2716,6 +2719,8 @@ Fb(WORD,SetMapMode,HDC,a,WORD,b)
Fb(WORD,SetPolyFillMode,HDC,a,WORD,b)
Fb(WORD,SetROP2,HDC,a,WORD,b)
Fb(WORD,SetRelAbs,HDC,a,WORD,b)
Fb(WORD,SetSelectorBase,WORD,a,DWORD,b)
Fb(WORD,SetSelectorLimit,WORD,a,DWORD,b)
Fb(WORD,SetStretchBltMode,HDC,a,WORD,b)
Fb(WORD,SetSystemPaletteUse,HDC,a,WORD,b)
Fb(WORD,SetTextAlign,HDC,a,WORD,b)
@ -2818,12 +2823,12 @@ Fc(INT,GetTextFace,HDC,a,INT,b,LPSTR,c)
Fc(INT,OpenFile,LPSTR,a,LPOFSTRUCT,b,WORD,c)
Fc(INT,_lread,INT,a,LPSTR,b,WORD,c)
Fc(INT,_lwrite,INT,a,LPCSTR,b,WORD,c)
Fc(LONG,_hread,INT,a,LPSTR,b,LONG,c)
Fc(LONG,_hwrite,INT,a,LPCSTR,b,LONG,c)
Fc(LONG,GetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
Fc(LONG,SetBitmapBits,HBITMAP,a,LONG,b,LPSTR,c)
Fc(LONG,SetClassLong,HWND,a,short,b,LONG,c)
Fc(LONG,SetWindowLong,HWND,a,short,b,LONG,c)
Fc(LONG,_hread,INT,a,LPSTR,b,LONG,c)
Fc(LONG,_hwrite,INT,a,LPCSTR,b,LONG,c)
Fc(LONG,_llseek,INT,a,LONG,b,INT,c)
Fc(SEGPTR,lstrcpyn,SEGPTR,a,SEGPTR,b,WORD,c)
Fc(WORD,GetAtomName,ATOM,a,LPSTR,b,short,c)
@ -2831,6 +2836,7 @@ Fc(WORD,GetInternalWindowPos,HWND,a,LPRECT,b,LPPOINT,c)
Fc(WORD,GetMenuState,HMENU,a,WORD,b,WORD,c)
Fc(WORD,GetProfileInt,LPSTR,a,LPSTR,b,int,c)
Fc(WORD,GlobalGetAtomName,ATOM,a,LPSTR,b,short,c)
Fc(WORD,SelectorAccessRights,WORD,a,WORD,b,WORD,c)
Fc(WORD,SetClassWord,HWND,a,short,b,WORD,c)
Fc(WORD,SetWindowWord,HWND,a,short,b,WORD,c)
Fc(int,FillRect,HDC,a,LPRECT,b,HBRUSH,c)

View File

@ -1,11 +0,0 @@
/* WINEOPTS.H
*/
#ifndef WINEOPTS_H
#define WINEOPTS_H
#include <stdio.h>
FILE *SpyFp;
#endif /* WINEOPTS_H */

View File

@ -7,13 +7,13 @@
#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
#include <windows.h>
#include <sys/types.h>
#include <sys/time.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "windows.h"
/*
* The new type to be used in all

33
ipc/Imakefile Normal file
View File

@ -0,0 +1,33 @@
#include "../Wine.tmpl"
MODULE = ipc
TEST_SRCS = \
shm_fragment_test.c \
bit_array_test.c\
dde_proc_test.c \
dde_atom_test.c \
shm_semaph_test.c \
wine_test_stub.c \
hash_test.c \
dde_mem_test.c
SRCS = bit_array.c \
dde_atom.c \
dde_mem.c \
dde_proc.c \
generic_hash.c \
shm_block.c \
shm_fragment.c \
shm_main_blk.c \
shm_semaph.c
OBJS = $(SRCS:.c=.o)
TEST_OBJS = $(TEST_SRCS:.c=.o)
WineRelocatableTarget($(MODULE),,$(OBJS))
DependTarget()
includes::
install::

57
ipc/Makefile.in Normal file
View File

@ -0,0 +1,57 @@
CC = @CC@
CFLAGS = @CFLAGS@
XINCL = @x_includes@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = ipc
SRCS = bit_array.c \
dde_atom.c \
dde_mem.c \
dde_proc.c \
generic_hash.c \
shm_block.c \
shm_fragment.c \
shm_main_blk.c \
shm_semaph.c
OBJS = $(SRCS:.c=.o)
.c.o:
$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
all: $(MODULE).o
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:

8
ipc/README Normal file
View File

@ -0,0 +1,8 @@
This is a pre-alpha code, it does not work for 100%,
but it does not break anything (I hope).
Proper documentation (LaTeX) will be ready for the next release.
You can use "ipcl" perl script to remove junk IPC stuff.
You can use "ipcs" system program to find junk IPC stuff.
Michael

42
ipc/TEST_FRAGMENT.std Normal file
View File

@ -0,0 +1,42 @@
After shm_FragmentInit
{0x0020,0xffe0} [total free=ffe0]
0: After shm_FragmentAlloc(block, 0x010000) == NULL
{0x0020,0xffe0} [total free=ffe0]
1: After shm_FragmentAlloc(block, 0x003fdc) == 0x00c024
{0x0020,0xc000} [total free=c000]
2: After shm_FragmentAlloc(block, 0x003ffc) == 0x008024
{0x0020,0x8000} [total free=8000]
3: After shm_FragmentAlloc(block, 0x003ffc) == 0x004024
{0x0020,0x4000} [total free=4000]
4: After shm_FragmentAlloc(block, 0x003ffd) == NULL
{0x0020,0x4000} [total free=4000]
5: After shm_FragmentAlloc(block, 0x003ffc) == 0x000024
no free fragments [total free=0000]
6: Doing shm_FragmentFree(block, 0x000024)
{0x0020,0x4000} [total free=4000]
7: After shm_FragmentAlloc(block, 0x001bfc) == 0x002424
{0x0020,0x2400} [total free=2400]
8: After shm_FragmentAlloc(block, 0x0013fc) == 0x001024
{0x0020,0x1000} [total free=1000]
9: After shm_FragmentAlloc(block, 0x000ffc) == 0x000024
no free fragments [total free=0000]
10: Doing shm_FragmentFree(block, 0x000024)
{0x0020,0x1000} [total free=1000]
11: Doing shm_FragmentFree(block, 0x004024)
{0x0020,0x1000} {0x4020,0x4000} [total free=5000]
12: Doing shm_FragmentFree(block, 0x00c024)
{0x0020,0x1000} {0x4020,0x4000} {0xc020,0x3fe0} [total free=8fe0]
13: After shm_FragmentAlloc(block, 0x000ffc) == 0x000024
{0x4020,0x4000} {0xc020,0x3fe0} [total free=7fe0]
14: Doing shm_FragmentFree(block, 0x000024)
{0x0020,0x1000} {0x4020,0x4000} {0xc020,0x3fe0} [total free=8fe0]
15: After shm_FragmentAlloc(block, 0x000ffd) == 0x007014
{0x0020,0x1000} {0x4020,0x2ff0} {0xc020,0x3fe0} [total free=7fd0]
16: Doing shm_FragmentFree(block, 0x008024)
{0x0020,0x1000} {0x4020,0x2ff0} {0x8020,0x7fe0} [total free=bfd0]
17: Doing shm_FragmentFree(block, 0x001024)
{0x0020,0x2400} {0x4020,0x2ff0} {0x8020,0x7fe0} [total free=d3d0]
18: Doing shm_FragmentFree(block, 0x002424)
{0x0020,0x6ff0} {0x8020,0x7fe0} [total free=efd0]
19: Doing shm_FragmentFree(block, 0x007014)
{0x0020,0xffe0} [total free=ffe0]

276
ipc/bit_array.c Normal file
View File

@ -0,0 +1,276 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: bit_array.c
* Purpose : manipulate array of bits
* Portability: This is not completely portable, non CISC arcitectures
* Might not have atomic Clear/Set/Toggle bit. On those
* architectures semaphores should be used.
* Big Endian Concerns: This code is big endian compatible,
* but the byte order will be different (i.e. bit 0 will be
* located in byte 3).
***************************************************************************
*/
/*
** uncoment the following line to disable assertions,
** this may boost performance by up to 50%
*/
/* #define NDEBUG */
#ifndef NO_ASM
#define HAS_BITOPS
#endif
#include <stdio.h>
#include <assert.h>
#include "bit_array.h"
#if defined(HAS_BITOPS)
# include <asm/bitops.h>
#else
static __inline__ int clear_bit(int bit, int *mem);
static __inline__ int set_bit(int bit, int *mem);
#endif /* HAS_BITOPS */
#define INT_NR(bit_nr) ((bit_nr) >> INT_LOG2)
#define INT_COUNT(bit_count) INT_NR( bit_count + BITS_PER_INT - 1 )
#define BIT_IN_INT(bit_nr) ((bit_nr) & (BITS_PER_INT - 1))
#if !defined(HAS_BITOPS)
/* first_zero maps bytes value to the index of first zero bit */
static char first_zero[256];
static int arrays_initialized=0;
/*
** initialize static arrays used for bit operations speedup.
** Currently initialized: first_zero[256]
** set "arrays_initialized" to inidate that arrays where initialized
*/
static void initialize_arrays()
{
int i;
int bit;
for (i=0 ; i<256 ; i++) {
/* find the first zero bit in `i' */
for (bit=0 ; bit < BITS_PER_BYTE ; bit++)
/* break if the bit is zero */
if ( ( (1 << bit) & i )
== 0)
break;
first_zero[i]= bit;
}
arrays_initialized=1;
}
/*
** Find first zero bit in the integer.
** Assume there is at least one zero.
*/
static __inline__ int find_zbit_in_integer(unsigned int integer)
{
int i;
/* find the zero bit */
for (i=0 ; i < sizeof(int) ; i++, integer>>=8) {
int byte= integer & 0xff;
if (byte != 0xff)
return ( first_zero[ byte ]
+ (i << BYTE_LOG2) );
}
assert(0); /* never reached */
return 0;
}
/* return -1 on failure */
static __inline__ int find_first_zero_bit(unsigned *array, int bits)
{
unsigned int integer;
int i;
int bytes=INT_COUNT(bits);
if (!arrays_initialized)
initialize_arrays();
for ( i=bytes ; i ; i--, array++) {
integer= *array;
/* test if integer contains a zero bit */
if (integer != ~0U)
return ( find_zbit_in_integer(integer)
+ ((bytes-i) << INT_LOG2) );
}
/* indicate failure */
return -1;
}
static __inline__ int test_bit(int pos, unsigned *array)
{
unsigned int integer;
int bit = BIT_IN_INT(pos);
integer= array[ pos >> INT_LOG2 ];
return ( (integer & (1 << bit)) != 0
? 1
: 0 ) ;
}
/*
** The following two functions are x86 specific ,
** other processors will need porting
*/
/* inputs: bit number and memory address (32 bit) */
/* output: Value of the bit before modification */
static __inline__ int clear_bit(int bit, int *mem)
{
int ret;
__asm__("xor %1,%1
btrl %2,%0
adcl %1,%1"
:"=m" (*mem), "=&r" (ret)
:"r" (bit));
return (ret);
}
static __inline__ int set_bit(int bit, int *mem)
{
int ret;
__asm__("xor %1,%1
btsl %2,%0
adcl %1,%1"
:"=m" (*mem), "=&r" (ret)
:"r" (bit));
return (ret);
}
#endif /* !deined(HAS_BITOPS) */
/* AssembleArray: assemble an array object using existing data */
bit_array *AssembleArray(bit_array *new_array, unsigned int *buff, int bits)
{
assert(new_array!=NULL);
assert(buff!=NULL);
assert(bits>0);
assert((1 << INT_LOG2) == BITS_PER_INT); /* if fails, redefine INT_LOG2 */
new_array->bits=bits;
new_array->array=buff;
return new_array;
}
/* ResetArray: reset the bit array to zeros */
int ResetArray(bit_array *bits)
{
int i;
int *p;
assert(bits!=NULL);
assert(bits->array!=NULL);
for(i= INT_COUNT(bits->bits), p=bits->array; i ; p++, i--)
*p=0;
return 1;
}
/* VacantBit: find a vacant (zero) bit in the array,
* Return: Bit index on success, -1 on failure.
*/
int VacantBit(bit_array *bits)
{
int bit;
assert(bits!=NULL);
assert(bits->array!=NULL);
bit= find_first_zero_bit(bits->array, bits->bits);
if (bit >= bits->bits) /* failed? */
return -1;
return bit;
}
int SampleBit(bit_array *bits, int i)
{
assert(bits != NULL);
assert(bits->array != NULL);
assert(i >= 0 && i < bits->bits);
return ( test_bit(i,bits->array) != 0
? 1
: 0
);
}
/*
** Use "compare and exchange" mechanism to make sure
** that bits are not modified while "integer" value
** is calculated.
**
** This may be the slowest technique, but it is the most portable
** (Since most architectures have compare and exchange command)
*/
int AssignBit(bit_array *bits, int bit_nr, int val)
{
int ret;
assert(bits != NULL);
assert(bits->array != NULL);
assert(val==0 || val==1);
assert(bit_nr >= 0 && bit_nr < bits->bits);
if (val==0)
ret= clear_bit(BIT_IN_INT(bit_nr), &bits->array[ INT_NR(bit_nr) ]);
else
ret= set_bit(BIT_IN_INT(bit_nr), &bits->array[ INT_NR(bit_nr) ]);
return ( (ret!=0) ? 1 : 0);
}
/*
** Allocate a free bit (==0) and make it used (==1).
** This operation is guaranteed to resemble an atomic instruction.
**
** Return: allocated bit index, or -1 on failure.
**
** There is a crack between locating free bit, and allocating it.
** We assign 1 to the bit, test it was not '1' before the assignment.
** If it was, restart the seek and assign cycle.
**
*/
int AllocateBit(bit_array *bits)
{
int bit_nr;
int orig_bit;
assert(bits != NULL);
assert(bits->array != NULL);
do {
bit_nr= VacantBit(bits);
if (bit_nr == -1) /* No vacant bit ? */
return -1;
orig_bit = AssignBit(bits, bit_nr, 1);
} while (orig_bit != 0); /* it got assigned before we tried */
return bit_nr;
}

93
ipc/bit_array_test.c Normal file
View File

@ -0,0 +1,93 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "bit_array.h"
#define SIZE (8*sizeof(int)*3)
static bit_array array;
static int simple_array[SIZE];
static int bits;
int are_equal()
{
int i;
for (i=0 ; i < SIZE ; i++)
if (SampleBit(&array,i) != simple_array[i]){
printf("failed bit %d (packed=%d, simple=%d)\n", i,
SampleBit(&array,i), simple_array[i]);
return 0;
}
return 1;
}
int is_same_vacant()
{
int vacant;
for (vacant =0 ; simple_array[vacant]!=0 ; vacant++)
if ( vacant >= SIZE) {
vacant=-1;
break;
}
if ( VacantBit(&array) == vacant )
return 1;
else
return 0;
}
void assign_both(int bit_nr, int bit_val)
{
int old_bit= simple_array[bit_nr];
simple_array[bit_nr]= bit_val;
bits+=bit_val - old_bit;
assert(AssignBit(&array, bit_nr, bit_val) == old_bit);
assert(are_equal());
assert(is_same_vacant());
}
int main()
{
unsigned int integers[SIZE >> 5];
int i,j;
assert( AssembleArray(&array, integers, SIZE)
== &array);
ResetArray(&array);
for (i=0 ; i<SIZE ; i++)
simple_array[i]=0;
for (j=5 ; j ; j--) {
printf("\rleft %d\r",j);
for (i=0 ; VacantBit(&array) != -1 ; i++ ) {
if (i % 256 == 0) {
printf("left %d ",j);
printf("%3d up \r", bits);
fflush(stdout);
}
assign_both(rand() % SIZE,
(rand()% SIZE > bits ) ? 0 : 1 );
}
assign_both(rand() % SIZE, 1);
for (i=0 ; bits ; i++ ) {
if (i % 256 == 0) {
printf("left %d ",j);
printf("%3d down\r", bits);
fflush(stdout);
}
assign_both(rand() % SIZE,
(rand()% SIZE <= (SIZE-bits) ) ? 0 : 1 );
}
assign_both(rand() % SIZE, 0);
}
putchar('\n');
return 0;
}

273
ipc/dde_atom.c Normal file
View File

@ -0,0 +1,273 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_atom.c
* Purpose : atom functionality for DDE
*/
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "dde_atom.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "stddebug.h"
#include "debug.h"
typedef struct
{
WORD count;
BYTE str[1];
} AtomData, *AtomData_ptr;
#define EMPTY 0 /* empty hash entry */
#define DELETED -1 /* deleted hash entry */
#define MIN_STR_ATOM 0xfc00
/* OFS2AtomData_ptr: extract AtomData_ptr from ofs */
#define OFS2AtomData_ptr(ofs) ((AtomData*)((int)&main_block->block+(ofs)))
/* OFS2AtomStr: find the string of the atom */
#define OFS2AtomStr(ofs) (OFS2AtomData_ptr(atom_ofs)->str)
/* offset of an atom according to index */
#define ATOM_OFS(idx) (main_block->atoms[idx])
/* rot_left: rotate (with wrap-around) */
static __inline__ int rot_left(unsigned var,int count)
{
return (var<<count) | (var>> (sizeof(var)-count));
}
/* find the entry in the atom table for this string */
static int FindHash(LPCSTR str) /* ignore str case */
{
int i,j;
unsigned hash1,hash2;
int deleted=-1; /* hash for deleted entry */
int atom_ofs;
/* get basic hash parameters */
for (i= hash1= hash2= 0; str[i] ; i++) {
hash1= rot_left(hash1,5) ^ toupper(str[i]);
hash2= rot_left(hash2,4) ^ toupper(str[i]);
}
hash1%= DDE_ATOMS;
atom_ofs=ATOM_OFS(hash1);
switch (atom_ofs) {
case EMPTY: /* empty atom entry */
return hash1;
case DELETED: /* deleted atom entry */
deleted=hash1;
break;
default : /* non empty atom entry */
if ( strcasecmp( OFS2AtomStr(atom_ofs) , str) == 0)
return hash1; /* found string in atom table */
}
hash2%= DDE_ATOMS-1 ; /* hash2=0..(DDE_ATOMS-2) */
hash2++; /* hash2=1..(DDE_ATOMS-1) */
/* make jumps in the hash table by hash2 steps */
for (i=hash1+hash2 ; ; i+=hash2) {
/* i wraps around into j */
j=i-DDE_ATOMS;
if (j >= 0)
i=j; /* i wraps around */
if (i==hash1)
/* here if covered all hash locations, and got back to beginning */
return deleted; /* return first empty entry - if any */
atom_ofs=ATOM_OFS(i);
switch (atom_ofs) {
case EMPTY: /* empty atom entry */
return i;
case DELETED: /* deleted atom entry */
if (deleted < 0)
/* consider only the first deleted entry */
deleted= i;
break;
default : /* nonempty atom entry */
if ( strcasecmp( OFS2AtomStr(atom_ofs) , str) == 0)
return i; /* found string in atom table */
}
}
}
void ATOM_GlobalInit(void)
{
int i;
for (i=0 ; i < DDE_ATOMS ; i++)
ATOM_OFS(i)=EMPTY;
}
/***********************************************************************
* GlobalAddAtom (USER.268)
*/
/* important! don't forget to unlock semaphores before return */
ATOM GlobalAddAtom( LPCSTR str )
{
int atom_idx;
int atom_ofs;
AtomData_ptr ptr;
ATOM atom;
dprintf_atom(stddeb,"GlobalAddAtom(%p)\n", str);
if ((unsigned) str < MIN_STR_ATOM) /* MS-windows convention */
return (ATOM) (unsigned) str;
if (str[0] == '#') { /* wine convention */
atom= (ATOM) atoi(&str[1]);
return (atom<MIN_STR_ATOM) ? atom : 0;
}
dprintf_atom(stddeb,"GlobalAddAtom(\"%s\")\n",str);
DDE_IPC_init(); /* will initialize only if needed */
shm_write_wait(main_block->sem);
atom_idx=FindHash(str);
atom=(ATOM)0;
/* use "return" only at the end so semaphore handling is done only once */
if (atom_idx>=0) {
/* unless table full and item not found */
switch (atom_ofs= ATOM_OFS(atom_idx)) {
case DELETED:
case EMPTY: /* need to allocate new atom */
atom_ofs= shm_FragmentAlloc(&main_block->block,
strlen(str)+sizeof(AtomData));
if (atom_ofs==NIL)
break; /* no more memory (atom==0) */
ATOM_OFS(atom_idx)=atom_ofs;
ptr=OFS2AtomData_ptr(atom_ofs);
strcpy(ptr->str,str);
ptr->count=1;
atom=(ATOM)(atom_idx+MIN_STR_ATOM);
break;
default : /* has to update existing atom */
OFS2AtomData_ptr(atom_ofs)->count++;
atom=(ATOM)(atom_idx+MIN_STR_ATOM);
} /* end of switch */
} /* end of if */
shm_write_signal(main_block->sem);
return atom;
}
/***********************************************************************
* GlobalDeleteAtom (USER.269)
*/
ATOM GlobalDeleteAtom( ATOM atom )
{
int atom_idx;
int atom_ofs;
AtomData_ptr atom_ptr;
ATOM retval=(ATOM) 0;
dprintf_atom(stddeb,"GlobalDeleteAtom(\"%d\")\n",(int)atom);
atom_idx=(int)atom - MIN_STR_ATOM;
if (atom_idx < 0 )
return 0;
DDE_IPC_init(); /* will initialize only if needed */
shm_write_wait(main_block->sem);
/* return used only once from here on -- for semaphore simplicity */
switch (atom_ofs=ATOM_OFS(atom_idx)) {
case DELETED:
case EMPTY:
fprintf(stderr,"trying to free unallocated atom %d\n", atom);
retval=atom;
break;
default :
atom_ptr=OFS2AtomData_ptr(atom_ofs);
if ( --atom_ptr->count == 0) {
shm_FragmentFree(&main_block->block,atom_ofs);
ATOM_OFS(atom_idx)=DELETED;
}
}
shm_write_signal(main_block->sem);
return retval;
}
/***********************************************************************
* GlobalFindAtom (USER.270)
*/
ATOM GlobalFindAtom( LPCSTR str )
{
int atom_idx;
int atom_ofs;
dprintf_atom(stddeb,"GlobalFindAtom(%p)\n", str );
if ((unsigned) str < MIN_STR_ATOM) /* MS-windows convention */
return (ATOM) (unsigned) str;
if (str[0] == '#') { /* wine convention */
ATOM atom= (ATOM) atoi(&str[1]);
return (atom<MIN_STR_ATOM) ? atom : 0;
}
dprintf_atom(stddeb,"GlobalFindAtom(\"%s\")\n",str);
DDE_IPC_init(); /* will initialize only if needed */
shm_read_wait(main_block->sem);
atom_idx=FindHash(str);
if (atom_idx>=0)
atom_ofs=ATOM_OFS(atom_idx); /* is it free ? */
else
atom_ofs=EMPTY;
shm_read_signal(main_block->sem);
if (atom_ofs==EMPTY || atom_ofs==DELETED)
return 0;
else
return (ATOM)(atom_idx+MIN_STR_ATOM);
}
/***********************************************************************
* GlobalGetAtomName (USER.271)
*/
WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
{
int atom_idx, atom_ofs;
int size;
/* temporary buffer to hold maximum "#65535\0" */
char str_num[7];
if (count<2) /* no sense to go on */
return 0;
atom_idx=(int)atom - MIN_STR_ATOM;
if (atom_idx < 0) { /* word atom */
/* use wine convention... */
sprintf(str_num,"#%d%n",(int)atom,&size);
if (size+1>count) { /* overflow ? */
/* truncate the string */
size=count-1;
str_num[size]='\0';
}
strcpy(buffer,str_num);
return size;
}
DDE_IPC_init(); /* will initialize only if needed */
/* string atom */
shm_read_wait(main_block->sem);
atom_ofs=ATOM_OFS(atom_idx);
if (atom_ofs==EMPTY || atom_ofs==DELETED) {
fprintf(stderr,"GlobalGetAtomName: illegal atom=%d\n",(int)atom);
size=0;
} else { /* non empty entry */
/* string length will be at most count-1, find actual size */
sprintf(buffer,"%.*s%n",count-1, OFS2AtomStr(atom_ofs), &size);
}
shm_read_signal(main_block->sem);
return size;
}

100
ipc/dde_atom_test.c Normal file
View File

@ -0,0 +1,100 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_atom_test.c
* Purpose : tests for dde_atom object
***************************************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <win.h>
#include "dde_atom.h"
#include "shm_main_blk.h"
#include <stddebug.h>
#include <debug.h>
#define TOGETHER (DDE_ATOMS/5)
/* run random sequences */
int main()
{
ATOM atom_list[TOGETHER];
char str[TOGETHER][80];
int i,j,atom_n;
int atom_len[TOGETHER];
debugging_shm=1;
debugging_atom=0;
debugging_sem=0;
for (i=0 ; i<=10000/TOGETHER ; i++) {
for (atom_n=0 ; atom_n<TOGETHER ; atom_n++) {
atom_len[atom_n]=rand()%64+1;
for (j=atom_len[atom_n]-1; j>=0; j--)
do {
str[atom_n][j]=(char)(rand()%255+1);
} while (j==0 && str[atom_n][j]=='#');
str[atom_n][ atom_len[atom_n] ]='\0';
atom_list[atom_n]=GlobalAddAtom(str[atom_n]);
if (atom_list[atom_n]==0) {
fprintf(stderr,"failed i=%d, atom_n=%d\n",i,atom_n);
return 1;
}
if (atom_list[atom_n]!=GlobalAddAtom(str[atom_n])) {
fprintf(stderr,
"wrong second GlobalAddAtom(\"%s\")\n", str[atom_n]);
return 1;
}
} /* for */
for (atom_n=0 ; atom_n<TOGETHER ; atom_n++) {
char buf[80];
int len;
len=GlobalGetAtomName( atom_list[atom_n], buf, 79);
if (atom_len[atom_n] != len) {
fprintf(stderr, "i=%d, atom_n=%d; ", i, atom_n);
fprintf(stderr,
"wrong length of GlobalGetAtomName(\"%s\")\n",
str[atom_n]);
return 1;
}
}
for (atom_n=0 ; atom_n<TOGETHER ; atom_n++) {
GlobalDeleteAtom(atom_list[atom_n]);
if (atom_list[atom_n]!=GlobalAddAtom(str[atom_n])) {
fprintf(stderr, "i=%d, atom_n=%d; ", i, atom_n);
fprintf(stderr,
"wrong third GlobalAddAtom(\"%s\")\n", str[atom_n]);
return 1;
}
GlobalDeleteAtom(atom_list[atom_n]);
GlobalDeleteAtom(atom_list[atom_n]);
atom_list[atom_n]=GlobalAddAtom(str[atom_n]);
if (atom_list[atom_n]!=GlobalAddAtom(str[atom_n])) {
fprintf(stderr,
"i=%d, atom_n=%d wrong fifth GlobalAddAtom(\"%s\")\n",
i, atom_n,
str[atom_n]);
return 1;
}
GlobalDeleteAtom(atom_list[atom_n]);
if (atom_list[atom_n]!=GlobalFindAtom(str[atom_n])) {
fprintf(stderr,
"i=%d, atom_n=%d wrong GlobalFindAtom(\"%s\")\n",
i, atom_n,
str[atom_n]);
return 1;
}
GlobalDeleteAtom(atom_list[atom_n]);
}
}
return 0;
}

282
ipc/dde_mem.c Normal file
View File

@ -0,0 +1,282 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_mem.c
* Purpose : shared DDE memory functionality for DDE
***************************************************************************
*/
#include <stdio.h>
#include <stddebug.h>
#include <debug.h>
#include <assert.h>
#include "ldt.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "shm_semaph.h"
#include "dde_mem.h"
#include "bit_array.h"
#define SEGPTR2HANDLE_INFO(sptr) ( (struct handle_info*)PTR_SEG_TO_LIN(sptr) )
#define HINFO2DATAPTR(h_info_ptr) ( (void*) ( (char*)h_info_ptr + \
sizeof(struct handle_info) ) )
#define DDE_MEM_IDX(handle) ((handle)& 0x7fff)
#define DDE_MEM_HANDLE(idx) ((idx) | 0x8000)
#define DDE_MEM_INFO(handle) (main_block->handles[ DDE_MEM_IDX(handle) ])
/* List of shared handles.
* This entry resides on the shared memory, the data comes right
* after the `handle_info'.
* The entry is on the same block as the actual data.
* The `next' field gives relative reference (relative to the start of
* the blcok.
*/
struct handle_info {
WORD lock_count;
WORD flags;
int size; /* size of the data (net)*/
};
static bit_array free_handles;
int debug_last_handle_size= 0; /* for debugging purpose only */
/* locate_handle:
* locate a shared memory handle.
* Application:
* The handle is first searched for in attached blocks.
* At the beginning, only blocks owned by this process are
* attached.
* If a handle is not found, new blocks are attached.
* Arguments:
* h - the handle.
* RETURN: pointer to handle info.
*/
static struct handle_info *locate_handle(HGLOBAL h, struct local_shm_map *map)
{
struct shm_block *block;
dprintf_global(stddeb,"shm:locate_handle(0x%04x)\n", h);
if (SampleBit( &free_handles, DDE_MEM_IDX(h)) == 0) {
dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
return NULL; /* free!!! */
}
block= shm_locate_block(DDE_MEM_INFO(h).shmid, map);
if (block == NULL) {
/* nothing found */
dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
return NULL;
}
return (struct handle_info *) REL2PTR(block, DDE_MEM_INFO(h).rel);
}
/* dde_alloc_handle: allocate shared DDE handle */
static HGLOBAL dde_alloc_handle()
{
int bit_nr;
bit_nr= AllocateBit( &free_handles);
if (bit_nr != -1)
return DDE_MEM_HANDLE(bit_nr);
dprintf_global(stddeb,"dde_alloc_handle: no free DDE handle found\n");
return 0;
}
/**********************************************************************
* DDE_malloc
*/
void *
DDE_malloc(unsigned int flags, unsigned long size, SHMDATA *shmdata)
{
int shmid;
struct shm_block *block;
struct handle_info *h_info;
struct local_shm_map *curr;
HGLOBAL handle;
dprintf_global(stddeb,"DDE_malloc flags %4X, size %ld\n", flags, size);
DDE_IPC_init(); /* make sure main shm block allocated */
shm_write_wait(main_block->proc[curr_proc_idx].sem);
/* Try to find fragment big enough for `size' */
/* iterate through all local shm blocks, and try to allocate
the fragment */
h_info= NULL;
for (curr= shm_map ; curr != NULL ; curr= curr->next) {
if (curr->proc_idx == curr_proc_idx) {
h_info= (struct handle_info *)
shm_FragPtrAlloc(curr->ptr, size+sizeof(struct handle_info));
if (h_info!=NULL) {
shmid= curr->shm_id;
break;
}
}
}
if (h_info == NULL) {
block= shm_create_block(0, size+sizeof(struct handle_info), &shmid);
if (block==NULL) {
shm_write_signal(main_block->proc[curr_proc_idx].sem);
return 0;
}
/* put the new block in the linked list */
block->next_shm_id= main_block->proc[curr_proc_idx].shmid;
main_block->proc[curr_proc_idx].shmid= shmid;
h_info= (struct handle_info *)
shm_FragPtrAlloc(block, size+sizeof(struct handle_info));
if (h_info==NULL) {
fprintf(stderr,"DDE_malloc: BUG! unallocated fragment\n");
shm_write_signal(main_block->proc[curr_proc_idx].sem);
return 0;
}
} else {
block= curr->ptr;
}
/* Here we have an allocated fragment */
h_info->flags= flags;
h_info->lock_count= 0;
h_info->size= size;
handle= dde_alloc_handle();
if (handle) {
dprintf_global(stddeb,
"DDE_malloc returning handle=0x%4x, ptr=0x%08lx\n",
(int)handle, (long) HINFO2DATAPTR(h_info));
DDE_MEM_INFO(handle).rel= PTR2REL(block, h_info);
DDE_MEM_INFO(handle).shmid= shmid;
}
else
dprintf_global(stddeb,"DDE_malloc failed\n");
shm_write_signal(main_block->proc[curr_proc_idx].sem);
shmdata->handle= handle;
return (char *)HINFO2DATAPTR(h_info);
}
HGLOBAL DDE_GlobalFree(HGLOBAL h)
{
struct handle_info *h_info;
int handle_index= h & 0x7fff;
struct local_shm_map map;
dprintf_global(stddeb,"DDE_GlobalFree(0x%04x)\n",h);
if (h==0)
return 0;
h_info= locate_handle(h, &map);
if (h_info == NULL)
return h;
shm_write_wait(main_block->proc[map.proc_idx].sem);
shm_FragPtrFree(map.ptr, (struct shm_fragment *) h_info);
AssignBit( &free_handles, handle_index, 0);
/* FIXME: must free the shm block some day. */
shm_write_signal(main_block->proc[map.proc_idx].sem);
return 0;
}
WORD DDE_SyncHandle(HGLOBAL handle, WORD sel)
{
struct handle_info *h_info;
void *local_ptr;
ldt_entry entry;
h_info= locate_handle(handle, NULL);
local_ptr= (void *)GET_SEL_BASE(sel);
if (h_info == NULL)
return 0;
if (local_ptr == (void *) HINFO2DATAPTR(h_info))
return sel;
/* need syncronization ! */
LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
entry.base= (unsigned long) HINFO2DATAPTR(h_info);
LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
return sel;
}
/*
* DDE_AttachHandle:
* Attach shm memory (The data must not be already attached).
* Parameters:
* handle - the memory to attach.
* segptr - in not null, return SEGPTR to the same block.
* return value:
* 32 bit pointer to the memory.
*/
void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr)
{
struct handle_info *h_info;
SHMDATA shmdata;
void *ptr;
HGLOBAL hOwner = GetCurrentPDB();
assert(is_dde_handle(handle));
if (segptr != NULL)
*segptr=0;
dprintf_global(stddeb,"DDE_AttachHandle(%04x)\n",handle);
h_info=locate_handle(handle, NULL);
if (h_info == NULL)
return NULL;
if ( !(h_info->flags & GMEM_DDESHARE) ) {
fprintf(stderr,"DDE_AttachHandle: Corrupted memory handle info\n");
return NULL;
}
dprintf_global(stddeb,"DDE_AttachHandle: h_info=%06lx\n",(long)h_info);
shmdata.handle= handle;
shmdata.shmid= DDE_MEM_INFO(handle).shmid;
ptr= HINFO2DATAPTR(h_info);
/* Allocate the selector(s) */
if (! GLOBAL_CreateBlock( h_info->flags, ptr, h_info->size, hOwner,
FALSE, FALSE, FALSE, &shmdata))
return NULL;
if (segptr != NULL)
*segptr= (SEGPTR)MAKELONG( 0, shmdata.sel);
if (debugging_dde)
debug_last_handle_size= h_info->size;
dprintf_global(stddeb,"DDE_AttachHandle returns ptr=0x%08lx\n", (long)ptr);
return (LPSTR)ptr;
}
void DDE_mem_init()
{
int nr_of_bits;
shm_init();
nr_of_bits= BITS_PER_BYTE * sizeof(main_block->free_handles);
AssembleArray( &free_handles, main_block->free_handles, nr_of_bits);
}

73
ipc/dde_mem_test.c Normal file
View File

@ -0,0 +1,73 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_mem_test.c
* Purpose : test shared DDE memory functionality for DDE
* Usage: Look for assertion failures
***************************************************************************
*/
#include <stdio.h>
#include <assert.h>
#include <win.h>
#include "dde_mem.h"
/* stub */
void ATOM_GlobalInit()
{
printf("ATOM_GlobalInit\n");
}
int main()
{
HWND h1,h2,h3;
int ret;
void *p1,*p2,*p3,*p;
SHMDATA shmdata;
/* alloc h1, h2, h3 */
setbuf(stdout,NULL);
p1=DDE_malloc(GMEM_DDESHARE, 0x6000, &shmdata);
h1= shmdata.handle;
assert(p1 != NULL);
assert(h1 != 0);
p2=DDE_malloc(GMEM_DDESHARE, 0xff00, &shmdata);
h2= shmdata.handle;
assert(p2 != NULL);
assert(h2 != 0);
p3=DDE_malloc(GMEM_DDESHARE, 0x6000, &shmdata);
h3= shmdata.handle;
assert(p3 != 0);
assert(h3 != 0);
/* lock h1, h2, h3 */
p=DDE_AttachHandle(h1,NULL);
assert(p1==p);
p=DDE_AttachHandle(h2,NULL);
assert(p2==p);
p=DDE_AttachHandle(h3,NULL);
assert(p3==p);
ret=DDE_GlobalFree(h1);
assert(ret==0);
/* do some implementation dependant tests */
p=DDE_malloc(GMEM_DDESHARE, 0x6000, &shmdata);
assert(p!=NULL);
assert(shmdata.handle==h1);
p=DDE_AttachHandle(h1,NULL);
assert(p1==p);
/* check freeing */
ret=DDE_GlobalFree(h1);
assert(ret==0);
ret=DDE_GlobalFree(h2);
assert(ret==0);
ret=DDE_GlobalFree(h3);
assert(ret==0);
return 0;
}

718
ipc/dde_proc.c Normal file
View File

@ -0,0 +1,718 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_proc.c
* Purpose : DDE signals and processes functionality for DDE
***************************************************************************
*/
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/msg.h>
#include "wintypes.h"
#include "win.h"
#include "shm_semaph.h"
#include "shm_main_blk.h"
#include "dde_proc.h"
#include "dde_mem.h"
#include "dde.h"
#include "stddebug.h"
#include "debug.h"
int curr_proc_idx= -1;
enum stop_wait_op stop_wait_op=CONT;
int had_SIGUSR2 = 0;
sigjmp_buf env_get_ack;
sigjmp_buf env_wait_x;
#define IDX_TO_HWND(idx) (0xfffe - (idx))
#define HWND_TO_IDX(wnd) (0xfffe - (wnd))
#define DDE_WIN_INFO(win) ( main_block->windows[HWND_TO_IDX(win)] )
#define DDE_WIN2PROC(win) ( DDE_WIN_INFO(win).proc_idx )
#define DDE_IsRemoteWindow(win) ( (win)<0xffff && (win)>=(0xffff-DDE_PROCS))
#define DDE_SEND 1
#define DDE_POST 2
#define DDE_ACK 3
#define DDE_MSG_SIZE sizeof(MSG)
#define FREE_WND (WORD)(-2)
#define DELETED_WND (WORD)(-3)
#if defined(DEBUG_MSG) || defined(DEBUG_RUNTIME)
static char *msg_type[4]={"********", "DDE_SEND", "DDE_POST", "DDE_ACK"};
#endif
struct msg_dat {
struct msgbuf dat;
char filler[DDE_MSG_SIZE];
} ;
typedef struct fifo_element {
int value;
struct fifo_element *next;
} fifo_element;
struct fifo {
fifo_element *first; /* first element in the fifo or NULL */
fifo_element *last; /* last element in the fifo or NULL */
};
static struct fifo fifo = {NULL,NULL};
void dde_proc_delete(int proc_idx);
void dde_proc_add_fifo(int val)
{
fifo_element *created;
created= (fifo_element*) malloc( sizeof(fifo_element) );
created->value = val;
created->next = NULL;
if (fifo.first==NULL)
fifo.first= created;
else
fifo.last->next= created;
fifo.last = created;
}
/* get an item from the fifo, and return it.
* If fifo is empty, return -1
*/
int dde_proc_shift_fifo()
{
int val;
fifo_element *deleted;
if (fifo.first == NULL)
return -1;
deleted= fifo.first;
val= deleted->value;
fifo.first= deleted->next;
if (fifo.first == NULL)
fifo.last= NULL;
free(deleted);
return val;
}
static void print_dde_message(char *desc, MSG *msg);
/* This should be run only when main_block is first allocated. */
void dde_proc_init(dde_proc proc)
{
int proc_num;
for (proc_num=0 ; proc_num<DDE_PROCS ; proc_num++, proc++) {
proc->msg=-1;
proc->sem=-1;
proc->shmid=-1;
proc->pid=-1;
}
}
/* add current process to the list of processes */
void dde_proc_add(dde_proc procs)
{
dde_proc proc;
int proc_idx;
dprintf_dde(stddeb,"dde_proc_add(..)\n");
shm_write_wait(main_block->sem);
/* find free proc_idx and allocate it */
for (proc_idx=0, proc=procs ; proc_idx<DDE_PROCS ; proc_idx++, proc++)
if (proc->pid==-1)
break; /* found! */
if (proc_idx<DDE_PROCS) { /* got here beacuse a free was found ? */
dde_msg_setup(&proc->msg);
proc->pid=getpid();
curr_proc_idx=proc_idx;
shm_sem_init(&proc->sem);
}
else {
fflush(stdout);
fprintf(stderr,"dde_proc_add: Can't allocate process\n");
}
shm_write_signal(main_block->sem);
}
/* wait for dde - acknowledge message - or timout */
static BOOL get_ack()
{
struct timeval timeout;
int size;
struct msg_dat ack_buff;
/* timeout after exactly one seconf */
timeout.tv_sec = 1;
timeout.tv_usec = 0;
sigsetjmp(env_get_ack, 1);
/* get here after normal execution, or after siglongjmp */
do { /* loop to wait for DDE_ACK */
had_SIGUSR2=0;
stop_wait_op=CONT; /* sensitive code: disallow siglongjmp */
size= msgrcv( main_block->proc[curr_proc_idx].msg , &ack_buff.dat,
1, DDE_ACK, IPC_NOWAIT);
if (size>=0) {
dprintf_msg(stddeb,"get_ack: received DDE_ACK message\n");
return TRUE;
}
if (DDE_GetRemoteMessage()) {
had_SIGUSR2=1; /* might have recieved SIGUSR2 */
}
stop_wait_op=STOP_WAIT_ACK; /* allow siglongjmp */
} while (had_SIGUSR2); /* loop if SIGUSR2 was recieved */
/* siglongjmp should be enabled at this moment */
select( 0, NULL, NULL, NULL, &timeout );
stop_wait_op=CONT; /* disallow further siglongjmp */
/* timeout !! (otherwise there would have been a siglongjmp) */
return FALSE;
}
/* Transfer one message to a given process */
static BOOL DDE_DoOneMessage (int proc_idx, int size, struct msgbuf *msgbuf)
{
dde_proc proc= &main_block->proc[ proc_idx ];
if (proc_idx == curr_proc_idx)
return FALSE;
if (kill(proc->pid,0) < 0) {
/* pid does not exist, or not our */
dde_proc_delete(proc_idx);
return FALSE;
}
if (debugging_dde) {
MSG *msg=(MSG*) &msgbuf->mtext;
char *title;
if (msgbuf->mtype==DDE_SEND)
title="sending dde:";
else if (msgbuf->mtype==DDE_POST)
title="posting dde:";
else
title=NULL;
if (title)
print_dde_message(title, msg);
else
fprintf(stddeb,"Unknown message type=0x%lx\n",msgbuf->mtype);
}
dprintf_msg(stddeb,
"DDE_DoOneMessage: to proc_idx=%d (pid=%d), queue=%u\n",
proc_idx, proc->pid, (unsigned)proc->msg);
if ( proc->msg != -1) {
dprintf_msg(stddeb, "DDE_DoOneMessage: doing...(type=%s)\n",
msg_type[msgbuf->mtype]);
size=msgsnd (proc->msg, msgbuf, size, 0);
if (size<0) {
fflush(stdout);
perror("msgsnd");
}
kill(proc->pid,SIGUSR2); /* tell the process there is a message */
dprintf_msg(stddeb,"DDE_DoOneMessage: "
"Trying to get acknowledgment from msg queue=%d\n",
proc->msg);
Yield(); /* force task switch, and */
/* acknowledgment sending */
if (get_ack()) {
return TRUE;
} else {
fflush(stdout);
fprintf(stderr,"get_ack: DDE_DoOneMessage: timeout\n");
return FALSE;
}
}
else {
dprintf_msg(stddeb,"DDE_DoOneMessage: message not sent, "
"target has no message queue\n");
return FALSE;
}
}
/* Do some sort of premitive hash table */
static HWND HWND_Local2Remote(HWND orig)
{
int dde_wnd_idx;
int deleted_idx= -1;
WND_DATA *tested;
WND_DATA *deleted= NULL;
int i;
dde_wnd_idx= orig % DDE_WINDOWS;
for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
if (dde_wnd_idx >= DDE_WINDOWS)
dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
tested= &main_block->windows[ dde_wnd_idx ];
if (tested->proc_idx == FREE_WND)
break;
if (deleted == NULL && tested->proc_idx == DELETED_WND) {
deleted= tested;
deleted_idx= dde_wnd_idx;
} else if (tested->wnd == orig && tested->proc_idx == curr_proc_idx) {
return IDX_TO_HWND(dde_wnd_idx);
}
}
if (deleted != NULL) { /* deleted is preferable */
/* free item, allocate it */
deleted->proc_idx= curr_proc_idx;
deleted->wnd = orig;
return IDX_TO_HWND(deleted_idx);
}
if (tested->proc_idx == FREE_WND) {
tested->proc_idx= curr_proc_idx;
tested->wnd = orig;
return IDX_TO_HWND(dde_wnd_idx);
}
fprintf(stderr,
"HWND_Local2Remote: Can't map any more windows to DDE windows\n");
return 0;
}
static BOOL DDE_DoMessage( MSG *msg, int type )
{
int proc_idx;
MSG *remote_message;
struct msg_dat msg_dat;
BOOL success;
if (msg->wParam == 0)
return FALSE;
if (main_block==NULL) {
if (msg->message >= WM_DDE_FIRST && msg->message <= WM_DDE_LAST)
DDE_IPC_init();
else
return FALSE;
}
if (msg->wParam == (HWND)-1)
return FALSE;
if ( ! DDE_IsRemoteWindow(msg->hwnd) && msg->hwnd!= (HWND)-1)
return FALSE;
dprintf_msg(stddeb, "%s: DDE_DoMessage(hwnd=0x%x,msg=0x%x,..)\n",
msg_type[type], (int)msg->hwnd,(int)msg->message);
dprintf_msg(stddeb,
"DDE_DoMessage(hwnd=0x%x,msg=0x%x,..) // HWND_BROADCAST !\n",
(int)msg->hwnd,(int)msg->message);
remote_message=(void*)&msg_dat.dat.mtext;
memcpy(remote_message, msg, sizeof(*msg));
remote_message->wParam= HWND_Local2Remote(msg->wParam);
if (remote_message->wParam == 0)
return FALSE;
msg_dat.dat.mtype=type;
if (msg->hwnd == (HWND)-1) {
success= FALSE;
for ( proc_idx=0; proc_idx < DDE_PROCS ; proc_idx++) {
if (proc_idx == curr_proc_idx)
continue;
if (main_block->proc[ proc_idx ].msg != -1)
success|=DDE_DoOneMessage(proc_idx, DDE_MSG_SIZE, &msg_dat.dat);
}
return success;
} else {
return DDE_DoOneMessage(DDE_WIN2PROC(msg->hwnd), DDE_MSG_SIZE,
&msg_dat.dat);
}
}
BOOL DDE_SendMessage( MSG *msg)
{
return DDE_DoMessage(msg, DDE_SEND);
}
BOOL DDE_PostMessage( MSG *msg)
{
return DDE_DoMessage(msg, DDE_POST);
}
void dde_proc_send_ack(HWND wnd, BOOL val) {
int proc,msg;
static struct msgbuf msg_ack={DDE_ACK,{'0'}};
proc=DDE_WIN2PROC(wnd);
msg=main_block->proc[proc].msg;
dprintf_msg(stddeb,"DDE_GetRemoteMessage: sending ACK "
"to wnd=%4x, proc=%d,msg=%d, pid=%d\n",wnd,proc,msg,
main_block->proc[proc].pid
);
msg_ack.mtext[0]=val;
msgsnd (msg, &msg_ack, 1, 0);
kill(main_block->proc[proc].pid, SIGUSR2);
}
/* return true (non zero) if had a remote message */
#undef DDE_GetRemoteMessage
int DDE_GetRemoteMessage()
{
static int nesting=0; /* to avoid infinite recursion */
MSG *remote_message;
int size;
struct msg_dat msg_dat;
BOOL was_sent; /* sent/received */
BOOL passed;
HWND hwnd;
WND *window;
if (curr_proc_idx==-1) /* do we have DDE initialized ? */
return 0;
if (nesting>10) {
fflush(stdout);
fprintf(stderr,"DDE_GetRemoteMessage: suspecting infinite recursion, exiting");
return 0;
}
remote_message=(void*)&msg_dat.dat.mtext;
/* test for SendMessage */
size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
DDE_MSG_SIZE, DDE_SEND, IPC_NOWAIT);
if (size==DDE_MSG_SIZE) { /* is this a correct message (if any) ?*/
was_sent=TRUE;
dprintf_msg(stddeb,
"DDE:receive sent message. msg=%04x wPar=%04x"
" lPar=%08lx\n",
remote_message->message, remote_message->wParam,
remote_message->lParam);
} else {
size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
DDE_MSG_SIZE, DDE_POST, IPC_NOWAIT);
if (size==DDE_MSG_SIZE) { /* is this a correct message (if any) ?*/
was_sent=FALSE;
dprintf_msg(stddeb,
"DDE:receive posted message. "
"msg=%04x wPar=%04x lPar=%08lx\n",
remote_message->message, remote_message->wParam,
remote_message->lParam);
}
else
return 0; /* no DDE message found */
}
/* At this point we are sure that there is a DDE message,
* was_sent is TRUE is the message was sent, and false if it was posted
*/
nesting++;
if (debugging_dde) {
char *title;
if (was_sent)
title="receive sent dde:";
else
title="receive posted dde:";
print_dde_message(title, remote_message);
}
if (remote_message->hwnd != (HWND) -1 ) {
HWND dde_window= DDE_WIN_INFO(remote_message->hwnd).wnd;
/* we should know exactly where to send the message (locally)*/
if (was_sent) {
dprintf_dde(stddeb,
"SendMessage(wnd=0x%04x, msg=0x%04x, wPar=0x%04x,"
"lPar=0x%08x\n",
dde_window, remote_message->message,
remote_message->wParam, (int)remote_message->lParam);
/* execute the recieved message */
passed= SendMessage(dde_window, remote_message->message,
remote_message->wParam, remote_message->lParam);
/* Tell the sended, that the message is here */
dde_proc_send_ack(remote_message->wParam, passed);
}
else {
passed= PostMessage(dde_window, remote_message->message,
remote_message->wParam, remote_message->lParam);
if (passed == FALSE) {
/* Tell the sender, that the message is here, and failed */
dde_proc_send_ack(remote_message->wParam, FALSE);
}
else {
/* ack will be sent later, at the first peek/get message */
dde_proc_add_fifo(remote_message->wParam);
}
}
nesting--;
return 1;
}
/* iterate through all the windows */
for (hwnd = GetTopWindow(GetDesktopWindow());
hwnd && (window = WIN_FindWndPtr(hwnd))!=NULL ;
hwnd = window->hwndNext) {
if (window->dwStyle & WS_POPUP || window->dwStyle & WS_CAPTION) {
if (was_sent)
SendMessage( hwnd, remote_message->message,
remote_message->wParam, remote_message->lParam );
else
PostMessage( hwnd, remote_message->message,
remote_message->wParam, remote_message->lParam );
} /* if */
} /* for */
/* replay with DDE_ACK after broadcasting in DDE_GetRemoteMessage */
dde_proc_send_ack(remote_message->wParam, TRUE);
nesting--;
return 1;
}
int dde_reschedule()
{
int ack_wnd;
ack_wnd= dde_proc_shift_fifo();
if (ack_wnd != -1) {
dde_proc_send_ack(ack_wnd, TRUE);
usleep(10000); /* force unix task switch */
return 1;
}
return 0;
}
void dde_msg_setup(int *msg_ptr)
{
*msg_ptr= msgget (IPC_PRIVATE, IPC_CREAT | 0700);
if (*msg_ptr==-1)
perror("dde_msg_setup fails to get message queue");
}
/* do we have dde handling in the window ?
* If we have, atom usage will make this instance of wine set up
* it's IPC stuff.
*/
void DDE_TestDDE(HWND hwnd)
{
if (main_block != NULL)
return;
dprintf_msg(stddeb,"DDE_TestDDE(0x%04x)\n", hwnd);
if (hwnd==0)
hwnd=-1;
/* just send a message to see how things are going */
SendMessage( hwnd, WM_DDE_INITIATE, 0, 0);
}
void dde_proc_delete(int proc_idx)
{
dde_proc_done(&main_block->proc[proc_idx]);
}
void stop_wait(int a)
{
had_SIGUSR2=1;
switch(stop_wait_op) {
case STOP_WAIT_ACK:
siglongjmp(env_get_ack,1);
break; /* never reached */
case STOP_WAIT_X:
siglongjmp(env_wait_x,1);
break; /* never reached */
case CONT:
/* do nothing */
}
}
static void print_dde_message(char *desc, MSG *msg)
{
extern const char *MessageTypeNames[];
extern int debug_last_handle_size;
WORD wStatus,hWord;
void *ptr;
DDEACK *ddeack;
DDEADVISE *ddeadvise;
DDEDATA *ddedata;
DDEPOKE *ddepoke;
if (is_dde_handle(msg->lParam & 0xffff) )
ptr=DDE_AttachHandle(msg->lParam&0xffff, NULL);
else
ptr =NULL;
wStatus=LOWORD(msg->lParam);
hWord=HIWORD(msg->lParam);
fprintf(stddeb,"%s", desc);
fprintf(stddeb,"%04x %04x==%s %04x %08lx ",
msg->hwnd, msg->message,MessageTypeNames[msg->message],
msg->wParam, msg->lParam);
switch(msg->message) {
case WM_DDE_INITIATE:
case WM_DDE_REQUEST:
case WM_DDE_EXECUTE:
case WM_DDE_TERMINATE:
/* nothing to do */
break;
case WM_DDE_ADVISE:
/* DDEADVISE: hOptions in WM_DDE_ADVISE message */
if (ptr) {
ddeadvise=ptr;
fprintf(stddeb,"fDeferUpd=%d,fAckReq=%d,cfFormat=0x%x",
ddeadvise->fDeferUpd, ddeadvise->fAckReq,
ddeadvise->cfFormat);
} else
fprintf(stddeb,"NO-DATA");
fprintf(stddeb," atom=0x%x",hWord);
break;
case WM_DDE_UNADVISE:
fprintf(stddeb,"format=0x%x, atom=0x%x",wStatus,hWord);
break;
case WM_DDE_ACK:
ddeack=(DDEACK*)&wStatus;
fprintf(stddeb,"bAppReturnCode=%d,fBusy=%d,fAck=%d",
ddeack->bAppReturnCode, ddeack->fBusy, ddeack->fAck);
if (ddeack->fAck)
fprintf(stddeb,"(True)");
else
fprintf(stddeb,"(False)");
break;
case WM_DDE_DATA:
if (ptr) {
ddedata=ptr;
fprintf(stddeb,"fResponse=%d,fRelease=%d,"
"fAckReq=%d,cfFormat=0x%x,value=\"%.*s\"",
ddedata->fResponse, ddedata->fRelease,
ddedata->fAckReq, ddedata->cfFormat,
debug_last_handle_size- (int)sizeof(*ddedata)+1,
ddedata->Value);
} else
fprintf(stddeb,"NO-DATA");
fprintf(stddeb," atom=0x%04x",hWord);
break;
case WM_DDE_POKE:
if (ptr) {
ddepoke=ptr;
fprintf(stddeb,"fRelease=%d,cfFormat=0x%x,value[0]='%c'",
ddepoke->fRelease, ddepoke->cfFormat, ddepoke->Value[0]);
} else
fprintf(stddeb,"NO-DATA");
fprintf(stddeb," atom=0x%04x",hWord);
break;
}
fprintf(stddeb,"\n");
}
void dde_proc_done(dde_proc proc)
{
if (proc->msg != -1)
msgctl(proc->msg, IPC_RMID, NULL);
proc->msg=-1;
proc->pid=-1;
shm_delete_chain(&proc->shmid);
shm_sem_done(&proc->sem);
}
/* delete entry, if old junk */
void dde_proc_refresh(dde_proc proc)
{
if (proc->pid == -1)
return;
if (kill(proc->pid, 0) != -1)
return;
/* get here if entry non empty, and the process does not exist */
dde_proc_done(proc);
}
void dde_wnd_setup()
{
int i;
for (i=0 ; i < DDE_WINDOWS ; i++)
main_block->windows[i].proc_idx = FREE_WND;
}
static BOOL DDE_ProcHasWindows(int proc_idx)
{
WND_DATA *tested;
int i;
for ( i=0 ; i < DDE_WINDOWS ; i++) {
tested= &main_block->windows[ i ];
if (tested->proc_idx == proc_idx)
return TRUE;
}
return FALSE;
}
/* Look for hwnd in the hash table of DDE windows,
* Delete it from there. If there are no more windows for this
* process, remove the process from the DDE data-structure.
* If there are no more processes - delete the whole DDE struff.
*
* This is inefficient, but who cares for the efficiency of this rare
* operation...
*/
void DDE_DestroyWindow(HWND hwnd)
{
int dde_wnd_idx;
WND_DATA *tested;
int i;
if (main_block == NULL)
return;
dde_wnd_idx= hwnd % DDE_WINDOWS;
for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
if (dde_wnd_idx >= DDE_WINDOWS)
dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
tested= &main_block->windows[ dde_wnd_idx ];
if (tested->proc_idx == FREE_WND)
return; /* No window will get deleted here */
if (tested->wnd == hwnd && tested->proc_idx == curr_proc_idx) {
dde_reschedule();
tested->proc_idx= DELETED_WND;
if (DDE_ProcHasWindows( curr_proc_idx ))
return;
while (dde_reschedule()) /* make sure there are no other */
/* processes waiting for acknowledgment */
;
dde_proc_delete( curr_proc_idx );
if (DDE_no_of_attached() == 1)
shm_delete_all(-1);
else {
shmdt( (void *) main_block);
main_block= NULL;
}
return;
}
}
}

117
ipc/dde_proc_test.c Normal file
View File

@ -0,0 +1,117 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: dde_proc.c
* Purpose : test DDE signals and processes functionality for DDE
* Usage: run two independant processes, one with an argument another
* without (with the argument is the server).
***************************************************************************
*/
#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <sys/syscall.h>
#include <sys/param.h>
#else
#include <syscall.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <win.h>
#include "dde.h"
#include "dde_proc.h"
#include "shm_main_blk.h"
#if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
char * cstack[4096];
#endif
#ifdef linux
extern void ___sig_restore();
extern void ___masksig_restore();
/* Similar to the sigaction function in libc, except it leaves alone the
restorer field */
static int
wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
{
__asm__("int $0x80":"=a" (sig)
:"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
if (sig>=0)
return 0;
errno = -sig;
return -1;
}
#endif
struct sigaction usr2_act;
void init_signals()
{
#ifdef linux
usr2_act.sa_handler = (__sighandler_t) stop_wait;
usr2_act.sa_flags = 0;
usr2_act.sa_restorer =
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
wine_sigaction(SIGUSR2,&usr2_act,NULL);
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__)
usr2_act.sa_hadnler = (void (*)) stop_wait;
usr2_act.sa_flags = SA_ONSTACK;
usr2_act.sa_mask = sig_mask;
usr2_act.sa_restorer =
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
if (sigaction(SIGUSR2,&usr2_act,NULL) <0) {
perror("sigaction: SIGUSR2");
exit(1);
}
#endif
}
void ATOM_GlobalInit()
{
printf("ATOM_GlobalInit\n");
}
void idle_loop()
{
int timeout;
for(timeout=500; timeout ; timeout--) {
if (DDE_GetRemoteMessage())
exit(0); ;
usleep(1000);
}
exit(-1);
}
void client()
{
MSG msg;
msg.hwnd=(HWND)-1;
msg.message= WM_DDE_INITIATE;
msg.wParam= 3;
msg.lParam= 4;
if (!DDE_SendMessage(&msg))
exit(-1);
idle_loop();
}
void server()
{
DDE_IPC_init();
idle_loop();
}
int main(int argc, char *argv[])
{
printf("Kill when done one message\n");
init_signals();
if (argc>1)
server();
else
client();
return 0;
}

678
ipc/generic_hash.c Normal file
View File

@ -0,0 +1,678 @@
/***************************************************************************
* Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
***************************************************************************
* File: generic_hash.c
* Purpose : dynamically growing hash, may use shared or local memory.
***************************************************************************
*/
#include <stdlib.h>
#include <assert.h>
#include "generic_hash.h"
#define ROUND_UP4(num) (( (num)+3) & ~3)
#define FREE_ENTRY 0
#define DELETED_ENTRY ((DWORD)-1)
#define NO_OF_PRIMES 512
#define GET_ITEM(items,size,i)\
(*(HASH_ITEM*) \
( ((char *)(items))+ \
(i)*(size)) )
static HASH_ITEM *locate_entry(HASH_CONTAINER* hash, DWORD key,
HASH_VAL *seeked_data, BOOL skip_deleted);
static void copy_hash_items(HASH_CONTAINER *hash, HASH_ITEM *old_items,
int old_n_items);
static BOOL arrays_initialized = FALSE;
static int primes[NO_OF_PRIMES];
static int best_primes[NO_OF_PRIMES];
static int no_of_primes;
static int no_of_best_primes;
static int max_num;
/* binary search for `num' in the `primes' array */
static BOOL prime_binary_search_found(int num)
{
int min_idx, max_idx, idx;
min_idx=0;
max_idx=no_of_primes-1;
while (min_idx <= max_idx) {
idx = (max_idx + min_idx) >> 1;
if (num == primes[idx])
return TRUE;
if (num < primes[idx])
max_idx = idx-1;
else
min_idx = idx+1;
}
return FALSE;
}
static BOOL is_prime(int num)
{
int i;
if ((num & 0x1) == 0) /* can be divided by 2 */
if (num == 2)
return TRUE;
else
return FALSE;
if (num <= primes[no_of_primes-1])
return prime_binary_search_found(num);
for (i=0 ; i < no_of_primes ; i++) {
if (num % primes[i] == 0)
return FALSE;
if (num < primes[i] * primes[i])
return TRUE;
}
return TRUE;
}
static void setup_primes()
{
int num;
primes[0]=2;
primes[1]=3;
no_of_primes=2;
/* count in modulo 6 to avoid numbers that divide by 2 or 3 */
for (num=5 ; ; num+=6) {
if (is_prime(num)) {
primes[no_of_primes++]=num;
if (no_of_primes >= NO_OF_PRIMES)
break;
}
if (is_prime(num+2)) {
primes[no_of_primes++]=num+2;
if (no_of_primes >= NO_OF_PRIMES)
break;
}
}
max_num= primes[no_of_primes-1] * primes[no_of_primes-1];
}
/* Find primes which are far "enough" from powers of two */
void setup_best_primes()
{
int i;
int num;
int pow2before, pow2after;
int min_range, max_range;
min_range=3;
max_range=3;
pow2before= 2;
pow2after= 4;
no_of_best_primes= 0;
for (i=0 ; i < no_of_primes ; i++){
num= primes[i];
if (num > pow2after) {
pow2before= pow2after;
pow2after <<=1;
min_range= pow2before+ (pow2before >> 3);
max_range= pow2after- (pow2before >> 2);
}
if (num > min_range && num < max_range)
best_primes[no_of_best_primes++]=num;
}
}
/* binary search for `num' in the `best_primes' array,
* Return smallest best_prime >= num.
*/
static int best_prime_binary_search(int num)
{
int min_idx, max_idx, idx;
min_idx=0;
max_idx=no_of_best_primes-1;
while (1) {
idx = (max_idx + min_idx) >> 1;
if (num == best_primes[idx])
return num;
if (num < best_primes[idx]) {
max_idx = idx-1;
if (max_idx <= min_idx)
return best_primes[idx];
}
else {
min_idx = idx+1;
if (min_idx >= max_idx)
return best_primes[max_idx];
}
}
}
/* Find the best prime, near `num' (which can be any number) */
static int best_prime(int num)
{
int log2;
int pow2less, pow2more;
int min_range, max_range;
if (num < 11)
return 11;
if (num <= best_primes[no_of_best_primes-1])
return best_prime_binary_search(num);
assert( num < max_num );
for (log2=0 ; num >> log2 ; log2++)
;
pow2less= 1 << log2;
pow2more= 1 << (log2+1);
min_range= pow2less + (pow2less >> 3);
max_range= pow2more - (pow2more >> 3);
if (num < min_range)
num= min_range;
num |= 1; /* make sure num can't be divided by 2 */
while (1) {
if (num >= max_range) {
pow2less<<= 1;
pow2more<<= 1;
min_range= pow2less + (pow2less >> 3);
max_range= pow2more - (pow2more >> 3);
num= min_range | 1; /* make sure num can't be divided by 2 */
}
/* num should be here in the range: (min_range, max_range) */
if (is_prime(num))
return num;
num+=2;
}
}
/* FIXME: This can be done before compiling. (uning a script)*/
static void setup_arrays()
{
setup_primes();
setup_best_primes();
}
/* Discard all DELETED_ENTRYs moving the data to it's correct location.
* Done without a temporary buffer.
* May require some efficiency improvements ( currently it's o(N^2)
* or is it o(N^3) in the worst case ? In the avarege it seems to be
* something like o(N log (N)))
*/
static void static_collect_garbge(HASH_CONTAINER *hash)
{
int i;
BOOL change;
HASH_ITEM *items;
HASH_ITEM *located;
HASH_ITEM *item;
int key;
items= hash->items;
do {
change= FALSE;
for (i=hash->shared->total_items-1 ; i >= 0 ; i--) {
item= &GET_ITEM(items,hash->bytes_per_item,i);
key= item->key;
if (key != DELETED_ENTRY && key != FREE_ENTRY) {
/* try to place the entry in a deleted location */
located= locate_entry(hash, key, &item->data,
0 /* no skip_deleted */);
if (located->key == DELETED_ENTRY) {
change= TRUE;
memcpy(&located, &item,
hash->bytes_per_item);
item->key= DELETED_ENTRY;
}
}
}
} while (change);
/* No change means that there is no need to go through a DELETED_ENTRY
* in order to reach an item, so DELETED_ENTRY looses it's special
* meaning, and it is the same as FREE_ENTRY.
*/
for (i=hash->shared->total_items-1 ; i >= 0 ; i--)
if (GET_ITEM(items,hash->bytes_per_item,i).key == DELETED_ENTRY)
GET_ITEM(items,hash->bytes_per_item,i).key = FREE_ENTRY;
hash->shared->deleted_items=0;
}
static void collect_garbge(HASH_CONTAINER *hash)
{
HASH_SHARED *shared= hash->shared;
HASH_ITEM *temp_items;
int size;
size= shared->total_items * hash->bytes_per_item;
temp_items= (HASH_ITEM*)malloc(size);
if (temp_items==NULL) {
static_collect_garbge(hash);
} else {
memcpy(temp_items, hash->items, size);
copy_hash_items(hash, temp_items, shared->total_items);
}
}
static void copy_hash_items(HASH_CONTAINER *hash, HASH_ITEM *old_items,
int old_n_items)
{
HASH_SHARED *shared= hash->shared;
HASH_ITEM *item;
int i;
shared->deleted_items = 0;
shared->free_items= shared->total_items;
/* make all items free */
for (i= shared->total_items-1 ; i>=0 ; i--)
GET_ITEM(hash->items, hash->bytes_per_item, i).key = FREE_ENTRY;
/* copy items */
for (i=0 ; i <= old_n_items; i++) {
item= &GET_ITEM(old_items, hash->bytes_per_item,i);
if (item->key != FREE_ENTRY && item->key != DELETED_ENTRY)
hash_add_item(hash, item->key, &item->data);
}
}
static void reorder_hash(HASH_CONTAINER *hash)
{
HASH_SHARED *shared= hash->shared;
HASH_ITEM *items, *old_items;
HASH_PTR shared_items, old_shared_items;
int n_items, old_n_items;
int size;
if (shared->deleted_items > hash->min_free_items) {
collect_garbge(hash);
return;
}
n_items= best_prime(shared->total_items * HASH_REALLOC_JUMPS);
size= n_items *
(sizeof(items[0]) - sizeof(items[0].data) + hash->bytes_per_item);
shared_items= hash->allocate_mem(size);
items= hash->access_mem(shared_items);
if (items == NULL) {
collect_garbge(hash);
return;
}
old_shared_items = shared->items;
old_n_items= shared->total_items;
old_items= hash->items;
/* setup a new clean hash based on the parameters of the original one */
hash->items= items;
shared->total_items = n_items;
shared->items= shared_items;
set_hash_parameters(hash, hash->maximum_load);
copy_hash_items(hash, old_items, old_n_items);
hash->free_mem(old_shared_items);
hash->last_ptr_update= ++shared->ptr_updates;
}
/* low level: attach hash existing hash items, no checks are performed
* No complex calculations done.
*/
static HASH_CONTAINER *attach_no_check(HASH_ITEM *items, int bytes_per_datum)
{
HASH_CONTAINER *hash;
int bytes_per_item;
HASH_ITEM dummy_item;
hash= (HASH_CONTAINER*) malloc(sizeof(HASH_CONTAINER) );
if (hash == NULL)
return NULL;
bytes_per_item= bytes_per_datum+
sizeof(dummy_item)-sizeof(dummy_item.data);
hash->bytes_per_item= ROUND_UP4(bytes_per_item);
hash->items= items;
hash->is_correct_item= NULL;
hash->allocate_mem= HASH_MEM_ALLOC;
hash->access_mem= HASH_MEM_ACCESS;
hash->free_mem= HASH_MEM_FREE;
set_hash_parameters(hash, HASH_LOAD);
return hash;
}
/* Attach existing & running remote (i.e. shared) hash.
* Attach the items using the data stored in "shared"
*/
HASH_CONTAINER *attach_remote_hash(HASH_SHARED *shared, int bytes_per_datum,
HASH_ITEM *(*access_mem)(HASH_PTR))
{
HASH_CONTAINER *hash;
HASH_ITEM *items;
assert(access_mem != NULL);
if (! arrays_initialized)
setup_arrays();
items=access_mem(shared->items);
hash= attach_no_check(items, bytes_per_datum);
if (hash == NULL)
return NULL;
hash->shared_was_malloced = FALSE;
hash->shared= shared;
return (hash);
}
HASH_CONTAINER *create_remote_hash(HASH_SHARED *shared,
int bytes_per_datum,
int total_items,
HASH_PTR (*allocate_mem)(int size),
HASH_ITEM *(*access_mem)(HASH_PTR))
{
HASH_CONTAINER *hash;
int size;
int i;
assert(total_items >= 1);
assert(bytes_per_datum >=1);
assert(access_mem != NULL);
assert(allocate_mem != NULL);
assert(shared != NULL);
if (! arrays_initialized)
setup_arrays();
if (total_items < MIN_HASH)
total_items= MIN_HASH;
else
total_items= best_prime(total_items);
hash= attach_no_check(NULL, bytes_per_datum);
if (hash==NULL) {
free(hash);
return NULL;
}
shared->total_items= total_items;
hash->shared= shared;
hash->shared_was_malloced = FALSE;
size= total_items * hash->bytes_per_item;
shared->items = allocate_mem(size);
hash->items= access_mem(shared->items);
if (hash->items == NULL ) {
free(hash);
return NULL;
}
shared->items.ptr= hash->items;
/* make all items free */
for (i=0 ; i < total_items ; i++)
GET_ITEM(hash->items,hash->bytes_per_item,i).key = FREE_ENTRY;
shared->deleted_items= 0;
shared->free_items= total_items;
shared->ptr_updates= 0;
return hash;
}
/* hash constructor: create brand new hash */
HASH_CONTAINER *create_hash(int bytes_per_datum, int total_items)
{
HASH_CONTAINER *hash;
HASH_SHARED *shared;
shared= (HASH_SHARED*)malloc(sizeof(HASH_SHARED));
if (shared == NULL)
return NULL;
hash= create_remote_hash(shared, bytes_per_datum, total_items,
HASH_MEM_ALLOC, HASH_MEM_ACCESS);
if (hash == NULL) {
free(shared);
return NULL;
}
hash->shared_was_malloced = TRUE;
return hash;
}
/* set the extra handlers to non default values */
void set_hash_handlers(HASH_CONTAINER *hash,
HASH_ITEM_TEST *is_correct_item,
HASH_PTR (*allocate_mem)(int size),
void (*free_mem)(HASH_PTR),
HASH_ITEM *(*access_mem)(HASH_PTR))
{
assert(hash);
assert(allocate_mem);
assert(free_mem);
hash->free_mem = free_mem;
hash->allocate_mem = allocate_mem;
hash->access_mem = access_mem;
hash->is_correct_item = is_correct_item;
}
/* set extra parameters */
void set_hash_parameters(HASH_CONTAINER *hash, int load)
{
assert(hash);
assert(load>30); /* no sence to realloc with less than */
/* 50% load, limiting to 30% to be on */
/* the safe size */
assert(load<=100);
hash->maximum_load= load;
hash->min_free_items= (1.0 - load/100.0) * hash->shared->total_items + 1 ;
}
/* hash destructor: destroy anything related to the hash */
void destroy_hash(HASH_CONTAINER *hash)
{
assert(hash);
hash->free_mem(hash->shared->items);
if (hash->shared_was_malloced)
free(hash->shared);
free(hash);
}
/* hash destructor: just detach hash, without destroing it (makes */
/* sence in shared memory environment) */
void detach_hash(HASH_CONTAINER *hash)
{
assert(hash);
free(hash);
}
/********** Hash usage *************/
static __inline__ BOOL
correct_entry(HASH_ITEM *item, int key, HASH_VAL *seeked_data,
HASH_ITEM_TEST *is_correct_item, BOOL skip_deleted)
{
switch(item->key) {
case FREE_ENTRY:
return TRUE;
case DELETED_ENTRY:
return skip_deleted ? FALSE : TRUE;
default:
if (item->key != key)
return FALSE;
if (is_correct_item != NULL)
return is_correct_item(&item->data, seeked_data);
else
return TRUE;
}
}
/* The algorithm of the hash (one of the 2 standard hash implementations):
* Iterate through the hash table until
* 1. The entry has been found.
* 2. A FREE entry has been found.
* 3. For insert operations only- A DELETED entry has been found.
* The difference between DELETED and FREE entires is that
* DELETED entry was one occupied, while FREE was never allocated.
* The idea behind this structure to keep other entries reachable.
*/
static HASH_ITEM *locate_entry(HASH_CONTAINER* hash, DWORD key,
HASH_VAL *seeked_data, BOOL skip_deleted)
{
DWORD hash_idx, hash_leaps;
HASH_ITEM *item;
int i;
int total_items;
assert(hash);
total_items= hash->shared->total_items;
hash_idx= key % total_items;
item= &GET_ITEM(hash->items, hash->bytes_per_item, hash_idx);
if ( correct_entry( item, key, seeked_data,
hash->is_correct_item, skip_deleted) )
return item;
/* get the WORDs in different order in this DWORD to avoid clustering */
hash_leaps=((DWORD)MAKELONG(HIWORD(key), LOWORD(key))
% (total_items-1)) +1;
/* interate through the hash table using hash_leaps */
for (i= total_items ; i ; i--) {
hash_idx+= hash_leaps;
if (hash_idx > total_items)
hash_idx -= total_items;
item= &GET_ITEM(hash->items,hash->bytes_per_item, hash_idx);
if ( correct_entry( item, key, seeked_data,
hash->is_correct_item, skip_deleted) )
return item;
}
return NULL;
}
static __inline__ void sync_shared_hash(HASH_CONTAINER *hash)
{
HASH_SHARED *shared= hash->shared;
if (shared->ptr_updates == hash->last_ptr_update)
return;
assert(shared->ptr_updates >= hash->last_ptr_update);
hash->last_ptr_update= shared->ptr_updates;
hash->min_free_items= (1.0 - hash->maximum_load/100.0) *
shared->total_items + 1 ;
hash->items= hash->access_mem(shared->items);
}
HASH_VAL *hash_locate_item(HASH_CONTAINER* hash,
int key, HASH_VAL *seeked_data)
{
HASH_ITEM *item;
assert(hash != NULL);
sync_shared_hash(hash);
item= locate_entry(hash, key, seeked_data, 1 /* skip_deleted */);
if (item == NULL)
return NULL;
if (item->key == FREE_ENTRY )
return NULL;
return &item->data;
}
BOOL hash_add_item(HASH_CONTAINER* hash, int key, HASH_VAL *data)
{
HASH_SHARED *shared;
HASH_ITEM *item;
assert(hash != NULL);
sync_shared_hash(hash);
shared= hash->shared;
item=locate_entry(hash, key, data, 0 /* no skip_deleted */);
assert(item != NULL);
if (item->key == key)
return FALSE;
if (item->key == FREE_ENTRY)
shared->free_items--;
else
shared->deleted_items--;
item->key= key;
memcpy(&item->data, data, hash->bytes_per_item-sizeof(key));
if (shared->free_items < hash->min_free_items ||
shared->deleted_items > hash->min_free_items)
reorder_hash(hash);
return TRUE;
}
BOOL hash_delete_item(HASH_CONTAINER* hash, int key, HASH_VAL *seeked_data)
{
HASH_ITEM *item;
assert(hash != NULL);
sync_shared_hash(hash);
item=locate_entry(hash, key, seeked_data, 1 /* skip_deleted */);
if (item == NULL)
return FALSE;
if (item->key == FREE_ENTRY)
return FALSE;
item->key = DELETED_ENTRY;
hash->shared->deleted_items++;
return TRUE;
}
void *ret_null()
{
return NULL;
}
HASH_ITEM *access_local_hash(HASH_PTR ptr)
{
return ptr.ptr;
}

141
ipc/generic_hash.h Normal file
View File

@ -0,0 +1,141 @@
/***************************************************************************
* Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
***************************************************************************
* File: generic_hash.h
* Purpose : dynamically growing hash, may use shared or local memory.
***************************************************************************
*/
#ifndef _GENERIC_HASH_H_
#define _GENERIC_HASH_H_
#include "wintypes.h"
#include "shm_block.h"
/* default hash values */
#define HASH_LOAD 70
#define HASH_MEM_ALLOC (HASH_PTR (*)(int size)) malloc
#define HASH_MEM_FREE (void (*)(HASH_PTR)) free
#define HASH_MEM_ACCESS access_local_hash
#define HASH_REALLOC_JUMPS 1.5 /* Relative size of the new memory */
#define MIN_HASH 13
typedef union {
char string[1];
WORD words[1];
DWORD dwords[1];
char *ptr;
SEGPTR segptr;
} HASH_VAL;
typedef struct hash_item_struct {
DWORD key;
HASH_VAL data;
} HASH_ITEM;
/* point to the hash structure */
typedef union {
HASH_ITEM* ptr; /* Local pointer */
REL_PTR rel; /* IPC relative address */
SEGPTR segptr; /* Universal (can be IPC or local) */
} HASH_PTR;
typedef struct hash_share_struct {
int total_items; /* total number of items (array size) */
int free_items; /* number of free items (excluding deleted) */
int deleted_items; /* number of deleted items */
int ptr_updates; /* Number of updates to `items' pointer */
/* (of items) - used for intecepting */
/* changes to the pointer. */
HASH_PTR items; /* pointer to the items */
} HASH_SHARED;
typedef BOOL HASH_ITEM_TEST(HASH_VAL *value, HASH_VAL *seeked_data);
/* NOTE:
* 1. Keys 0 and -1 are reserved.
* 2. none of these items should be accessed directly, use existing
* functions. If they are not enough, add a new function.
*/
typedef struct hash_container_struct {
int bytes_per_item;
int maximum_load; /* in percents (0..100) default is 70 */
int min_free_items; /* minimum free items before reallocating
(Function of maximum_load) */
int last_ptr_update; /* to be compared with shared.ptr_updates */
BOOL shared_was_malloced; /* Need that to know how to destroy hash */
/* This is an optional handler.
* If not NULL, this function is used for distinguishing between
* different data with the same key (key field holds integer and
* is too short for long keys like strings).
*/
HASH_ITEM_TEST *is_correct_item;
/* Handlers used for reallocating memory
* [by allocating new data and then freeing old data]
*/
HASH_PTR (*allocate_mem)(int size);
void (*free_mem)(HASH_PTR);
/* Translator from HASH_PTR construct to a regular pointer.
use HASH_MEM_ACCESS, if no translation is needed */
HASH_ITEM *(*access_mem)(HASH_PTR);
HASH_ITEM *items;
HASH_SHARED *shared; /* Things to be on shared memory. */
} HASH_CONTAINER;
/********** Hash maintenance functions ***********/
/* Attach existing & running remote (i.e. shared) hash.
* Attach the items using the data stored in "shared"
*/
HASH_CONTAINER *attach_remote_hash(HASH_SHARED *shared, int bytes_per_datum,
HASH_ITEM *(*access_mem)(HASH_PTR));
HASH_CONTAINER *create_remote_hash(HASH_SHARED *shared,
int bytes_per_datum,
int total_items,
HASH_PTR (*allocate_mem)(int size),
HASH_ITEM *(*access_mem)(HASH_PTR));
/* hash constructor: create brand new hash (not on shared memory) */
HASH_CONTAINER *create_hash(int bytes_per_datum, int total_items);
/* set the extra handlers to non default values */
void set_hash_handlers(HASH_CONTAINER *hash,
HASH_ITEM_TEST *is_correct_item,
HASH_PTR (*allocate_mem)(int size),
void (*free_mem)(HASH_PTR),
HASH_ITEM *(*access_mem)(HASH_PTR));
/* set extra parameters */
void set_hash_parameters(HASH_CONTAINER *hash, int load);
/* hash destructors */
void destroy_hash(HASH_CONTAINER *hash);
void detach_hash(HASH_CONTAINER *hash);
/********** Hash usage *************/
/* All following functions have the same format:
* hash- the hash structure to use
* key- used as primary means to get to the entry.
* data- 1. a secondary key (used only if `is_correct_item' is set).
* 2. data to store. (for hash_add_item).
*/
HASH_VAL *hash_locate_item(HASH_CONTAINER* hash,int key, HASH_VAL* seeked_data);
BOOL hash_add_item(HASH_CONTAINER* hash, int key, HASH_VAL* data);
BOOL hash_delete_item(HASH_CONTAINER* hash, int key, HASH_VAL* seeked_data);
void *ret_null(); /* function returning null (used for */
/* disabling memory reallocation) */
/* access function used by local (non IPC) memory */
HASH_ITEM *access_local_hash(HASH_PTR ptr);
#endif /* _GENERIC_HASH_H_ */

117
ipc/hash_test.c Normal file
View File

@ -0,0 +1,117 @@
/***************************************************************************
* Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com
***************************************************************************
* File: hash_test.c
* Purpose : test generic_hash correctness.
* NOTE:
* This code covers only about 80% of generic_hash code.
* There might be bugs in the remaining 20% - although most
* of the functionality is tested with wine linckage.
* For complete testing a little more work should be done.
***************************************************************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "generic_hash.h"
#define SIZE 200
typedef struct { int a,b;} DATA ;
DATA data[SIZE];
int keys[SIZE];
int peeks=0;
HASH_CONTAINER *hash1;
HASH_CONTAINER *hash2; /* actual data is shared with hash1 */
/* test insertion using keys[] and data[] inserting using hash1 and */
/* hash2 periodically, test hash after every 2 insertions */
void test_insert()
{
int i,j;
HASH_VAL *item;
printf("testing insertion \n");
for (i=0 ; i < SIZE-1 ; i+=2) {
assert(hash_add_item(hash1, keys[i], (HASH_VAL *)&data[i]));
assert(hash_add_item(hash2, keys[i+1], (HASH_VAL *)&data[i+1]));
for (j=0 ; j <= i+1 ; j++) {
item= hash_locate_item(hash1, keys[j], (HASH_VAL *)&data[j]);
if (item == NULL) {
printf("NULL item: i=%d,j=%d\n",i,j);
continue;
}
peeks++;
if (memcmp(item,&data[j],sizeof(DATA))!=0) {
printf("i=%d,j=%d\n",i,j);
printf("saved=(%d,%d), orig=(%d,%d)\n",
((DATA*)item)->a, ((DATA*)item)->b,
data[j].a, data[j].b);
}
}
}
}
/* test deletion using keys[] and data[] deleting using hash1 and */
/* hash2 periodicly, test hash after every 2 deletions */
void test_delete()
{
int i,j;
HASH_VAL *item;
printf("testing deletion\n");
for (i=0 ; i < SIZE-1 ; i+=2) {
assert(hash_delete_item(hash2, keys[i], NULL));
assert(hash_delete_item(hash1, keys[i+1], NULL));
for (j=0 ; j < SIZE ; j++) {
item= hash_locate_item(hash2, keys[j], (HASH_VAL *)&data[j]);
if (item == NULL) {
if ( j > i+1)
printf("NULL item: i=%d,j=%d\n",i,j);
continue;
}
if (item != NULL && j <= i+1) {
printf("Non NULL item: i=%d,j=%d\n",i,j);
continue;
}
if (memcmp(item,&data[j],sizeof(DATA))!=0) {
printf("i=%d,j=%d\n",i,j);
printf("saved=(%d,%d), orig=(%d,%d)\n",
((DATA*)item)->a, ((DATA*)item)->b,
data[j].a, data[j].b);
}
}
}
}
int main()
{
int i;
hash1= create_hash(sizeof(DATA), 1);
assert(hash1);
hash2= attach_remote_hash(hash1->shared, sizeof(DATA), HASH_MEM_ACCESS);
assert(hash2);
for (i=0 ; i< SIZE ; i++) {
data[i].a= rand();
data[i].b= rand();
keys[i]= rand();
}
test_insert();
detach_hash(hash1);
free(hash1);
hash1= attach_remote_hash(hash2->shared, sizeof(DATA), HASH_MEM_ACCESS);
test_delete();
test_insert();
detach_hash(hash1);
destroy_hash(hash2);
printf("peeks=%d\n", peeks);
return 0;
}

49
ipc/run_tests Normal file
View File

@ -0,0 +1,49 @@
#!/bin/sh
bit_array_test
bit_array=$?
dde_mem_test
mem=$?
hash_test
hash=$?
shm_semaph_test
semaph=$?
dde_atom_test
atom=$?
dde_proc_test 1 > proc_server &
sleep 1
dde_proc_test > proc_client
fgrep "DDE:receive sent message. msg=03e0 wPar=fffb lPar=00000004" proc_server &&
fgrep "DDE_GetRemoteMessage: sending ACK to wnd=fffb, proc=1" proc_server &&
fgrep "get_ack: received DDE_ACK message" proc_client
proc=$?
rm proc_client proc_server
shm_fragment_test | diff TEST_FRAGMENT.std -
fragment=$?
echo ====================================================================
echo Test results:
echo -n "bit_array "
if [ $bit_array -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
echo -n "dde_mem "
if [ $mem -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
echo -n "hash "
if [ $hash -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
echo -n "shm_semaph "
if [ $semaph -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
echo -n "dde_proc "
if [ $proc -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi
echo -n "shm_fragment "
if [ $fragment -eq 0 ] ; then echo OK ; else echo "** ERROR **" ; fi

191
ipc/shm_block.c Normal file
View File

@ -0,0 +1,191 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_block.c
* Purpose: Treat a shared memory block.
***************************************************************************
*/
#define inline __inline__
#include <sys/sem.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddebug.h>
#include <debug.h>
#include <global.h>
#include "selectors.h"
#include "shm_fragment.h"
#include "shm_block.h"
#include "shm_semaph.h"
#include "dde_proc.h"
/* How each shmid is maped to local pointer */
/* Only attached shm blocks are in this construct */
struct local_shm_map *shm_map=NULL;
/* setup a new shm block (construct a shm block object).
* block: The pointer to the memory block (local mapping)
* first: The first data byte (excluding header stuff),
* if 0 (zero) Use the default.
* size: The size of the memory block.
*/
void shm_setup_block(struct shm_block *block, int first, int size)
{
dprintf_shm(stddeb,"Setting up shm block at 0x%08x\n",(int )block);
/* setup block internal data structure */
if (first <= 0) {
first=sizeof(*block);
/* round up - so everything starts on cache line boundary
* (assume cache line=32 bytes, may be bigger/smaller for
* different processors and different L2 caches .)
*/
first=(first+0x1f) & ~0x1f;
}
block->free=size-first;
block->next_shm_id=-1; /* IPC shm ID (for initial linking) */
block->proc_idx= curr_proc_idx;
/* block->size is initialized in shm_FragmentInit */
shm_FragmentInit(block, first, size); /* first item in the free list */
dprintf_shm(stddeb,
"block was set up at 0x%08x, size=0x%04xKB, 1st usable=%02x\n",
(int )block,size/1024,first);
}
/* shm_attach_block: attach existing shm block, setup selectors
* shm_id - id of the block to attach.
* proc_idx - if not -1, puts this data into local mapping
* map - localy mapped info about this block.
*/
/* NOTE: there is no check if this block is already attached.
* Attaching the same block more than once - is possible
* In case of doubt use shm_locate_block.
*/
struct shm_block *shm_attach_block(int shm_id, int proc_idx,
struct local_shm_map *map)
{
struct shm_block *block;
struct shmid_ds ds;
struct local_shm_map *this;
shmctl(shm_id, IPC_STAT, &ds );
block=(struct shm_block*)shmat(shm_id, NULL, 0);
if (block==NULL) return NULL;
this=(struct local_shm_map *)malloc(sizeof(*this));
this->next= shm_map;
shm_map = this;
this->shm_id= shm_id;
this->ptr = block;
if (proc_idx < 0)
this->proc_idx=block->proc_idx;
else
this->proc_idx=proc_idx;
if (map != NULL) {
memcpy(map, this, sizeof(map));
map->next= NULL; /* don't pass private info */
}
return block;
}
struct shm_block *shm_create_block(int first, int size, int *shm_id)
{
struct shm_block *block;
if (size==0)
size=SHM_MINBLOCK;
else
/* round up size to a multiple of SHM_MINBLOCK */
size= (size+SHM_MINBLOCK-1) & ~(SHM_MINBLOCK-1);
*shm_id= shmget ( IPC_PRIVATE, size ,0700);
if (*shm_id==-1)
return NULL;
block=shm_attach_block(*shm_id, curr_proc_idx, NULL);
if (block!=NULL)
shm_setup_block(block, first, size);
return block;
}
/*
** Locate attached block. (return it, or NULL on failure)
** shm_id is the block we look for.
** *map - will get all the info related to this local map + proc_idx
** (may be NULL)
** *seg - will get the segment this block is attached to.
*/
struct shm_block *shm_locate_attached_block(int shm_id,
struct local_shm_map *map)
{
struct local_shm_map *curr;
for (curr= shm_map ; curr != NULL ; curr= curr->next) {
if (curr->shm_id == shm_id) {
if (map) {
memcpy(map, curr, sizeof(*curr) );
map->next = NULL; /* this is private info ! */
}
return curr->ptr;
}
}
/* block not found ! */
return 0;
}
/* shm_locate_block: see shm_attach_block.
In addition to shm_attach_block, make sure this
block is not already attached.
*/
struct shm_block *shm_locate_block(int shm_id, struct local_shm_map *map)
{
struct shm_block *ret;
ret= shm_locate_attached_block(shm_id, map);
if (ret!=NULL)
return ret;
/* block not found ! , try to attach */
return shm_attach_block(shm_id, -1, map);
}
static void forget_attached(int shmid)
{
struct local_shm_map *curr, **point_to_curr;
for (curr= shm_map, point_to_curr= &shm_map ;
curr != NULL ;
curr= curr->next, point_to_curr= &curr->next ) {
if (curr->shm_id == shmid) {
*point_to_curr= curr->next;
return;
}
}
}
/* delete chain of shm blocks (pointing to each other)
* Do it in reverse order. (This is what the recursion is for)
*/
void shm_delete_chain(int *shmid)
{
struct shm_block *block;
if (*shmid == -1)
return;
block= shm_locate_block(*shmid, NULL);
forget_attached( *shmid );
if (block == NULL)
return;
shm_delete_chain(&block->next_shm_id);
shmctl(*shmid, IPC_RMID, NULL);
*shmid=-1;
shmdt((char *)block);
}

178
ipc/shm_fragment.c Normal file
View File

@ -0,0 +1,178 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_fragment.c
* Purpose: Data fragments and free list items. Allocate and free blocks.
***************************************************************************
*/
#include <stdio.h> /* for debugging only */
#include <stddebug.h>
#include <debug.h> /* for "stddeb" */
#include "shm_fragment.h"
#include "shm_block.h"
/******************************************************************************
*
* Free list: all fragments are ordered according to memory location.
* new fragments are inserted in this way.
*
******************************************************************************
*/
#define FRAG_PTR(block,ofs) ((struct shm_fragment *) ((char *) block + ofs) )
#define NEXT_FRAG(block,ofs) ( FRAG_PTR(block,ofs)->info.next )
/* setup first item in the free list */
void shm_FragmentInit(struct shm_block *block,int first, int size)
{
struct shm_fragment *fragment;
/* round up to nearest 16 byte boundary */
first=(first+15)& ~15;
block->free_list=first;
/* make all the block (exluding the header) free */
fragment= FRAG_PTR(block, first);
block->free= fragment->size= size-first;
fragment->info.next=0;
}
void shm_FragPtrFree(struct shm_block *block, void *ptr)
{
/* ptr points to fragment->info.data, find pointer to fragment,
* find the offset of this pointer in block.
*/
if (ptr)
shm_FragmentFree(block, PTR2REL(block, ptr));
}
void shm_FragmentFree(struct shm_block *block, int fragment_ofs)
{
struct shm_fragment *fragment=NULL;
int prev;
int next;
fragment_ofs-=(int )&fragment->info.data;
fragment= FRAG_PTR(block, fragment_ofs);
block->free+=fragment->size;
/* scan free list to find candidates for merging with fragment */
for (prev=0, next=block->free_list;
(next!=0) && (fragment_ofs > next) ;
prev=next, next=NEXT_FRAG(block,next) )
;
/* insert fragment between, prev and next
* prev==0: fragment will be the first item in free list
* next==0: fragment will be the last item in free list
*/
/* update fragment (point to next, or merge with next) */
if ( fragment_ofs+fragment->size == next ) {
/* merge with the next free block */
fragment->size+= FRAG_PTR(block,next)->size;
fragment->info.next=FRAG_PTR(block,next)->info.next;
} else
/* fragment should be inserted before the next fragment or end of */
/* list. (not merged) */
fragment->info.next=next;
/* now fragment has all the information about the rest of the list */
/* upate prev fragment (point or merge with fragment) */
if (prev==0) /* first item in free list */
block->free_list=fragment_ofs;
else if ( prev+FRAG_PTR(block,prev)->size == fragment_ofs ) {
/* merge fragment with previous fragment */
FRAG_PTR(block,prev)->size+= fragment->size;
FRAG_PTR(block,prev)->info.next=fragment->info.next;
} else
/* insert fragment after previous fragment */
FRAG_PTR(block,prev)->info.next=fragment_ofs;
}
/* use "first fit" algorithm,
* return: offset to data in fragment.
*/
int shm_FragmentAlloc(struct shm_block *block, int size)
{
int prev;
int candidate;
struct shm_fragment *fragment;
struct shm_fragment *ret_fragment;
if (size <= 0)
return NIL;
/* add size of "fragment->size" */
size+= (char *)&fragment->info.data - (char *)fragment ;
/* round "size" to nearest 16 byte value */
size= (size+15) & ~15;
if (size > block->free)
return NIL;
/* scan free list to find candidates for allocation */
for (prev=0, candidate=block->free_list;
candidate!=0 ;
prev=candidate, candidate= fragment->info.next )
{
fragment=FRAG_PTR(block,candidate);
if (fragment->size >= size)
break;
}
if (candidate == 0)
return NIL;
block->free-=size;
if (fragment->size == size) {
if (prev == 0)
block->free_list= fragment->info.next;
else
FRAG_PTR(block,prev)->info.next= fragment->info.next;
return PTR2REL(block, &fragment->info.data);
}
/* fragment->size > size */
/* Split fragment in two, return one part, put the other in free list. */
/* The part that starts at the old location - will stay in the free list. */
fragment->size -= size;
ret_fragment=FRAG_PTR(block, candidate + fragment->size);
ret_fragment->size= size;
return PTR2REL(block, ret_fragment->info.data);
}
/* like shm_FragmentAlloc, returns pointer instead of offset */
char *shm_FragPtrAlloc(struct shm_block *block, int size)
{
int ofs;
ofs= shm_FragmentAlloc(block,size);
if (ofs == NIL)
return NULL;
else
return (char *) REL2PTR(block, ofs);
}
/* This is used for debugging only */
void shm_print_free_list(struct shm_block *block)
{
struct shm_fragment *fragment;
int item;
item=block->free_list;
if (item==0) {
fprintf(stddeb,"no free fragments");
} else {
for (; item ; item=fragment->info.next) {
fragment=FRAG_PTR(block,item);
fprintf(stddeb,"{0x%04x,0x%04x} ",item,fragment->size);
}
}
fprintf(stddeb," [total free=%04x]\n",block->free);
fflush(stddeb);
}

100
ipc/shm_fragment_test.c Normal file
View File

@ -0,0 +1,100 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_fragment_test.c
* Purpose: Test data fragments and free list items. Allocate and free blocks.
***************************************************************************
*/
#include <assert.h>
#include <stdio.h>
#include <stddebug.h>
#define DEBUG_DEFINE_VARIABLES /* just avoid dumb errors */
#include <debug.h> /* for "stddeb" */
#include <stdlib.h>
#include <string.h>
#include "shm_block.h"
#include "shm_fragment.h"
#define DO_FREE(id) (-id)
#define LIST_LENGTH 20
int main()
{
struct shm_block *block;
char *ret;
int size;
int i;
/* important: The test will work only for the current implementation of */
/* allocation, if the implementation will change, the list should also */
/* cahnge. */
static int sizes[LIST_LENGTH]={
SHM_MINBLOCK, /* 0: should fail */
0x3fe0-4, /* 1: */
0x4000-4, /* 2: */
0x4000-4, /* 3: */
0x4000-4+1, /* 4: should fail */
0x4000-4, /* 5: */
/* allocated(5,3,2,1) free() */
-5, /* 6: */
0x1c00-4, /* 7: */
0x1400-4, /* 8: */
0x1000-4, /* 9: */
/* allocated(9,8,7,3,2,1) free() */
-9, /* 10: */
-3, /* 11: */
-1, /* 12: */
/* allocated(8,7,2) free(9,3,1) */
0x1000-4, /* 13: */
-13, /* 14: */
0x1000+1-4, /* 15: */
/* allocated(8,7,15,2) free(9,[3-15],1) */
-2, /* 16: */
/* allocated(8,7,15) free(9,[3-15],1+2) */
-8, /* 17: */
-7, /* 18: */
-15 /* 19: */
};
static char *ptr[LIST_LENGTH];
block=malloc(SHM_MINBLOCK);
assert(block);
/* setup first item in the free list */
shm_FragmentInit(block, sizeof(*block), SHM_MINBLOCK);
fprintf(stddeb,"After shm_FragmentInit\n");
shm_print_free_list(block);
for(i=0 ; i < LIST_LENGTH; i++) {
size=sizes[i];
if (size>0) { /* allocate */
ret=shm_FragPtrAlloc(block, size);
ptr[i]=ret;
fprintf(stddeb,
"%d: After shm_FragmentAlloc(block, 0x%06x) == ",
i, size);
if (ret==NULL)
fprintf(stddeb, "NULL\n");
else {
fprintf(stddeb, "0x%06x\n", (int)ret-(int)block);
bzero (ret,size); /* test boundaries */
}
} else { /* free */
/* free shm fragment */
ret=ptr[-sizes[i]];
fprintf(stddeb, "%d: Doing shm_FragmentFree(block, ", i);
if (ret==NULL)
fprintf(stddeb, "NULL)\n");
else
fprintf(stddeb, "0x%06x)\n", (int)ret-(int)block);
fflush(stddeb);
shm_FragPtrFree(block, ret);
}
shm_print_free_list(block);
}
return 0;
}

264
ipc/shm_main_blk.c Normal file
View File

@ -0,0 +1,264 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_main_blk.c
* Purpose: Main Wine's shared memory block
***************************************************************************
*/
#define inline __inline__
#include <sys/sem.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <stddebug.h>
#include <debug.h>
#include "shm_fragment.h"
#include "shm_block.h"
#include "shm_main_blk.h"
#include "shm_semaph.h"
#define WineKey ( 'W'+((int)'i'<<8)+((int)'n'<<16)+((int)'e'<<24) )
#define SHM_KEY_RANGE 8
/* main block (set during initialization) */
struct shm_main_block *main_block=NULL;
static char *shm_header="Wine - Windows emulator DDE mechanism";
static int main_shm_id;
static void shm_main_refresh();
/* for debugging only */
static void print_perm(struct ipc_perm *perm)
{
printf("Permission:\n");
printf("\tKey=%d, mode=%03o, sequence #=%d\n",
(int)perm->key,perm->mode, perm->seq);
printf("\towner: uid=%d, gid=%d ;" ,perm->uid, perm->gid);
printf(" creator: uid=%d, gid=%d\n",perm->cuid,perm->cgid);
}
/* for debugging only */
/* print_shm_info: print shared memory descriptor info */
static void print_shm_info(int shm_id)
{
struct shmid_ds ds;
shmctl(shm_id, IPC_STAT, &ds );
printf("shm_id=%d, Size=0x%08x , Number of attaches=%d\n",
shm_id, ds.shm_segsz, (int)ds.shm_nattch);
if (ds.shm_atime)
printf("Last attach=%s",ctime(&ds.shm_atime));
if (ds.shm_dtime)
printf("Last detach=%s",ctime(&ds.shm_dtime));
printf("Last change=%s",ctime(&ds.shm_ctime));
printf("pid: creator=%d, last operator=%d\n",
(int)ds.shm_cpid,(int)ds.shm_lpid);
print_perm( &ds.shm_perm);
}
int proc_exist(__pid_t pid)
{
if ( kill(pid,0) == 0) /* dummy signal to test existence */
return 1;
else if (errno==ESRCH) /* "no such process" */
return 0;
else
return 1;
}
/* setup a new main shm block (only construct a shm block object). */
static void shm_setup_main_block()
{
dprintf_shm(stddeb,"creating data structure\n");
main_block->build_lock=1;
strcpy(main_block->magic, shm_header);
shm_setup_block(&main_block->block,sizeof(*main_block),SHM_MINBLOCK);
dde_proc_init(main_block->proc);
ATOM_GlobalInit();
shm_sem_init(&main_block->sem);
/* main block set and data structure is stable now */
main_block->build_lock=0;
}
/* Delete everything related to main_block */
void shm_delete_all(int shmid)
{
int proc_idx;
if (shmid == -1)
shmid= main_shm_id;
shmctl( shmid, IPC_RMID, NULL);
for (proc_idx= 0 ; proc_idx < DDE_PROCS ; proc_idx++)
dde_proc_done( &main_block->proc[proc_idx] );
shm_sem_done(&main_block->sem);
shmdt( (void *) main_block);
main_block= NULL;
}
int DDE_no_of_attached()
{
struct shmid_ds shm_info;
if (shmctl(main_shm_id, IPC_STAT, &shm_info) == -1)
return -1;
return shm_info.shm_nattch;
}
/*
** Test if shm_id is MainBlock and attach it (if it is),
** Return 1 if ok, 0 otherwise.
*/
static int attach_MainBlock(int shm_id)
{
struct shmid_ds shm_info;
if (shmctl(shm_id, IPC_STAT, &shm_info) == -1)
return 0;
/* Make sure we don't work on somebody else's block */
if (shm_info.shm_perm.cuid != getuid()) { /* creator is not me */
dprintf_shm(stddeb,"Creator is not me!\n");
return 0;
}
dprintf_shm(stddeb,"shared memory exist, attaching anywhere\n");
main_block=(struct shm_main_block *)shmat(shm_id, 0, 0);
if ( (int)main_block==-1) {
dprintf_shm(stddeb,"Attach failed\n");
return 0;
}
if (strcmp(main_block->magic, shm_header) != 0) {
dprintf_shm(stddeb,"Detaching, wrong magic\n");
shmdt((void *)main_block);
return 0;
}
if (debugging_shm)
print_shm_info(shm_id);
/* Is it an old unused block ? */
if (shm_info.shm_nattch == 0) {
dprintf_shm(stddeb,"No attaches, deleting old data\n");
shm_delete_all(shm_id);
return 0;
}
/* Wait for data structure to stabilize */
while (main_block->build_lock)
usleep(10000);
main_shm_id= shm_id;
shm_main_refresh();
return 1;
}
/* (Function used by the constructor)
* Try to get existing shared memory with key="Wine", size=SHM_MINBLOCK
* complete user permission.
* If such block is found - return true (1), else return false (0)
*/
static int shm_locate_MainBlock(key_t shm_key)
{
int shm_id; /* Descriptor to this shared memory */
int i;
dprintf_shm(stddeb,"shm_locate_MainBlock: trying to attach, key=0x%x\n",
shm_key);
for (i=0 ; i < SHM_KEY_RANGE ; i++) {
dprintf_shm(stddeb,"iteration=%d\n", i);
shm_id= shmget ( shm_key+i, SHM_MINBLOCK ,0700);
if (shm_id != -1) {
if ( attach_MainBlock(shm_id) ) {
return 1; /* success! */
}
} else {
switch(errno) {
case EIDRM: /* segment destroyed */
case EACCES: /* no user permision */
break;
case ENOMEM: /* no free memory */
case ENOENT: /* this key does not exist */
default :
dprintf_shm(stddeb,"shmget failed, errno=%d, %s\n",
errno, strerror(errno) );
return 0; /* Failed */
}
} /* if .. else */
} /* for */
return 0;
}
/* (Function used by the constructor)
* Try to allocate new shared memory with key="Wine", size=SHM_MINBLOCK
* with complete user permission.
* If allocation succeeds - return true (1), else return false (0)
*/
static int shm_create_MainBlock(key_t MainShmKey)
{
int shm_id;
int flags= 0700 | IPC_CREAT | IPC_EXCL;
int i;
dprintf_shm(stddeb,"creating shared memory\n");
/* try to allocate shared memory with key="Wine", size=SHM_MINBLOCK, */
/* complete user permission */
for (i=0 ; i < SHM_KEY_RANGE ; i++) {
shm_id= shmget ( (key_t) MainShmKey, SHM_MINBLOCK, flags);
if (shm_id != -1)
break;
}
if (shm_id == -1) {
dprintf_shm(stddeb,"failed to create shared memory\n");
return 0;
}
dprintf_shm(stddeb,"shared memory created, attaching\n");
main_block=(struct shm_main_block*) shmat(shm_id, 0,0);
if (debugging_shm)
print_shm_info(shm_id);
main_shm_id= shm_id;
shm_setup_main_block();
dde_wnd_setup();
return 1;
}
/* link to the dde shared memory block */
/* RETURN: 0 on success, non zero on failure */
int shm_init(void)
{
if ( !shm_locate_MainBlock(WineKey)
&& !shm_create_MainBlock(WineKey)) {
fflush(stdout);
fprintf(stderr,"shm_init: failed to init main shm block\n");
exit(1);
}
dde_proc_add(main_block->proc);
return 0;
}
static void shm_main_refresh()
{
int proc_idx;
for (proc_idx= 0 ; proc_idx < DDE_PROCS ; proc_idx++)
dde_proc_refresh( &main_block->proc[proc_idx] );
}

136
ipc/shm_semaph.c Normal file
View File

@ -0,0 +1,136 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_semaph.c
* Purpose: Handle semaphores for shared memory operations.
***************************************************************************
*/
#define inline __inline__
#include <assert.h>
#include <unistd.h>
#include <sys/sem.h>
#include <stdio.h>
#include <errno.h>
#include <stddebug.h>
#include <debug.h>
#include "shm_semaph.h"
#define SEM_READ 0
#define SEM_WRITE 1
/* IMPORTANT: Make sure that killed process will not lock everything.
* If possible, restrict usage of these functions.
*/
void shm_read_wait(shm_sem semid)
{
struct sembuf sop[2];
int ret;
dprintf_sem(stddeb,"shm_read_wait(%d)\n",semid);
sop[0].sem_num=SEM_READ;
sop[0].sem_op=1; /* add this read instance */
sop[0].sem_flg=SEM_UNDO; /* undo in case process dies */
sop[1].sem_num=SEM_WRITE;
sop[1].sem_op=0; /* wait until no writing instance exists */
sop[1].sem_flg=SEM_UNDO;
do {
ret=semop (semid,sop , 2);
} while (ret<0 && errno==EINTR); /* interrupted system call? */
if (ret<0)
fprintf(stderr,"failed semaphore lock for read. semid=%d,errno=%d\n",
semid, errno);
}
void shm_write_wait(shm_sem semid)
{
struct sembuf sop[3];
int ret;
dprintf_sem(stddeb,"shm_write_wait(%d)\n",semid);
sop[0].sem_num=SEM_READ;
sop[0].sem_op=0; /* wait until no reading instance exist */
sop[0].sem_flg=SEM_UNDO;
sop[1].sem_num=SEM_WRITE;
sop[1].sem_op=1; /* writing is in progress - disable read */
sop[1].sem_flg=SEM_UNDO; /* undo if process dies */
sop[2].sem_num=SEM_READ;
sop[2].sem_op=1; /* disable new writes */
sop[2].sem_flg=SEM_UNDO;
do {
ret=semop (semid,sop , 3);
} while (ret<0 && errno==EINTR); /* interrupted system call? */
if (ret<0) /* test for the error */
fprintf(stderr,"failed semaphore lock for write. semid=%d,errno=%d\n",
semid, errno);
}
void shm_write_signal(shm_sem semid)
{
struct sembuf sop[2];
int ret;
dprintf_sem(stddeb,"shm_write_signal(%d)\n",semid);
sop[0].sem_num=SEM_READ;
sop[0].sem_op=-1;
sop[0].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
sop[1].sem_num=SEM_WRITE;
sop[1].sem_op=-1;
sop[1].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
do {
ret=semop (semid,sop , 2);
} while (ret<0 && errno==EINTR); /* interrupted system call? */
if (ret<0) /* test for the error */
fprintf(stderr,"failed semaphore unlock for write. semid=%d,errno=%d\n",
semid, errno);
}
void shm_read_signal(shm_sem semid)
{
struct sembuf sop[2];
int ret;
dprintf_sem(stddeb,"shm_read_signal(%d)\n",semid);
sop[0].sem_num=SEM_READ;
sop[0].sem_op=-1;
sop[0].sem_flg=IPC_NOWAIT | SEM_UNDO; /* no reason to wait */
do {
ret=semop (semid,sop , 1);
} while (ret<0 && errno==EINTR); /* interrupted system call? */
if (ret<0) /* test for the error */
fprintf(stderr,"failed semaphore unlock for read. semid=%d,errno=%d\n",
semid, errno);
}
void shm_sem_init(shm_sem *sptr)
{
shm_sem semid;
union semun arg;
semid=semget (IPC_PRIVATE, 2, 0700 | IPC_CREAT);
arg.val=0;
semctl (semid, 0, SETVAL, arg);
semctl (semid, 1, SETVAL, arg);
*sptr=semid;
}
void shm_sem_done(shm_sem *semptr)
{
union semun arg;
semctl (*semptr, 0, IPC_RMID , arg);
semctl (*semptr, 1, IPC_RMID , arg);
*semptr= -1;
}

128
ipc/shm_semaph_test.c Normal file
View File

@ -0,0 +1,128 @@
/***************************************************************************
* Copyright 1995, Technion, Israel Institute of Technology
* Electrical Eng, Software Lab.
* Author: Michael Veksler.
***************************************************************************
* File: shm_semaph_test.c
* Purpose: Test semaphores handleingr shared memory operations.
***************************************************************************
*/
#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "shm_semaph.h"
#include <sys/shm.h>
#define DEBUG_DEFINE_VARIABLES
#include <stddebug.h>
#include <debug.h>
static volatile int * volatile data;
static int isparent=0;
#define DELAY (rand()%10)
shm_sem sem;
static void read_write(int num)
{
int i,j ;
volatile float dummy=0;
int val;
srand(num+time(NULL));
for (i=0x3fff;i>=0;i--) {
if((i&0x7ff)==0 && isparent)
fprintf(stderr,"0x%06x\r",i);
shm_write_wait(sem);
*data= num;
for (j=DELAY ; j>=0;j--)
dummy*=2;
if (*data!=num) {
fprintf(stderr,"\nbad shm_write_wait(), num=%d\n",num);
shm_write_signal(sem);
return;
}
shm_write_signal(sem);
for (j=DELAY ; j>=0 ;j--)
dummy*=2;
shm_read_wait(sem);
val=*data;
for (j=DELAY; j>=0 ;j--)
dummy*=0.5;
if (*data!=val) {
fprintf(stderr,"\nbad shm_read_wait(), num=%d,val=%d,*data=%d\n",
num,val,*data);
shm_read_signal(sem);
return;
}
shm_read_signal(sem);
}
if (isparent)
fputc('\n',stderr);
}
static void child1()
{
read_write(2);
}
static void child2()
{
read_write(10);
}
static void parent()
{
isparent=1;
read_write(60);
}
int main()
{
int shmid;
int ret1, ret2;
int pid1, pid2;
int stat=0;
shm_sem_init(&sem);
shmid=shmget(IPC_PRIVATE, 0x100, IPC_CREAT | 0700);
data= (int *)shmat ( shmid, NULL, 0);
*data=0;
switch (pid1=fork()) {
case -1:
perror("fork 1");
return 1;
case 0:
fprintf(stderr,"child1\n");
child1();
fprintf(stderr,"child1 done\n");
return 0;
default :
}
switch (pid2=fork()) {
case -1:
perror("fork 2");
stat|=1;
break;
case 0:
fprintf(stderr,"child2\n");
child2();
fprintf(stderr,"child2 done\n");
return 0;
default :
}
fprintf(stderr,"parent\n");
if (pid2>0) { /* if second fork did not fail */
parent();
fprintf(stderr,"parent done, waiting for child2\n");
waitpid(pid2,&ret2,WUNTRACED);
stat|=ret2;
}
fprintf(stderr,"parent done, waiting for child1\n");
waitpid(pid1,&ret1,WUNTRACED);
stat|=ret1;
fprintf(stderr,"all done\n");
shmctl(shmid, IPC_RMID,NULL);
shm_sem_done(&sem);
return stat;
}

117
ipc/wine_test_stub.c Normal file
View File

@ -0,0 +1,117 @@
#include <stdlib.h>
#include "dde.h"
#include <wintypes.h>
#include "global.h"
#include <win.h>
#define DEBUG_DEFINE_VARIABLES
#define DEBUG_ALL
#include <stddebug.h>
#include <debug.h>
#define DDE_PROC2WIN(proc_idx) ( (HWND) ~( (proc_idx)+1) )
#define DDE_WIN2PROC(win) ( (int) ~(short) ((win)+1) )
#define DDE_IsRemoteWindow(win) ( (win)<0xffff && (win)>=(0xffff-DDE_PROCS))
char *MessageTypeNames[0x400]={NULL};
char *dummy_store_for_debug_msg_name;
ldt_copy_entry ldt_copy[LDT_SIZE];
int LDT_GetEntry( int entry, ldt_entry *content )
{
return 0;
}
int LDT_SetEntry( int entry, ldt_entry *content )
{
return 0;
}
void dummy_usage_of_debug_msg_name()
{
dummy_store_for_debug_msg_name=debug_msg_name[0];
}
/* stub */
HWND GetDesktopWindow()
{
printf("GetDesktopWindow\n");
return 0;
}
/* stub */
/* smart stub */
LONG SendMessage(HWND a,WORD b,WORD c,LONG d)
{
MSG msg;
printf("SendMessage(%04x,%04x,%04x,%04lx)\n",a,b,c,d);
if (DDE_IsRemoteWindow(a) || a==(HWND)-1)
return 0;
if (b!=WM_DDE_INITIATE)
return 0;
msg.hwnd=c;
msg.message= WM_DDE_ACK;
msg.lParam= 0;
msg.wParam= 0;
return DDE_SendMessage(&msg);
}
/* stub */
BOOL PostMessage(HWND a,WORD b,WORD c,LONG d)
{
printf("PostMessage(%04x,%04x,%04x,%04lx)\n",a,b,c,d);
return 0;
}
/* stub */
HWND GetTopWindow(HWND a)
{
printf("GetTopWindow(%04x)\n",a);
return 1;
}
/* stub */
WORD FreeSelector(WORD a)
{
printf("FreeSelector(%04x)\n",a);
return 0;
}
/* stub that partially emulates the true GLOBAL_CreateBlock function */
HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
HGLOBAL hOwner, BOOL isCode,
BOOL is32Bit, BOOL isReadOnly,
SHMDATA *shmdata )
{
printf("GLOBAL_CreateBlock(flags=0x%x,ptr=0x%08lx, size=0x%x,hOwner=0x%x\n",
(int)flags, (long)ptr, (int)size, (int)hOwner);
printf("isCode=%d, is32Bit=%d, isReadOnly=%d, \n", isCode, is32Bit,
isReadOnly);
printf("*shmdata={handle=0x%x,sel=0x%x, shmid=%d})\n",
shmdata->handle, shmdata->sel, shmdata->shmid);
return 1;
}
/* stub */
WND *WIN_FindWndPtr(HWND hwnd)
{
static WND win;
printf("WIN_FindWndPtr(%d)\n",hwnd);
if (hwnd==0)
return NULL;
win.hwndNext=0;
win.dwStyle=WS_POPUP;
return &win;
}
/* stub */
WORD GetCurrentPDB(void)
{
printf("GetCurrentPDB()\n");
return 0;
}
/* stub */
void Yield(void)
{
}

View File

@ -3,7 +3,6 @@
MODULE = loader
SRCS = \
dump.c \
main.c \
module.c \
ne_image.c \

50
loader/Makefile.in Normal file
View File

@ -0,0 +1,50 @@
CC = @CC@
CFLAGS = @CFLAGS@
XINCL = @x_includes@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = loader
SRCS = main.c module.c ne_image.c ne_resource.c pe_image.c \
pe_resource.c selector.c signal.c resource.c task.c
OBJS = $(SRCS:.c=.o)
.c.o:
$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
all: $(MODULE).o
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:

View File

@ -1,75 +0,0 @@
#ifndef WINELIB
/*
static char RCSId[] = "$Id: dump.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef linux
#include <linux/unistd.h>
#include <linux/head.h>
#include <linux/ldt.h>
#endif
#include <errno.h>
#include "neexe.h"
#include "prototypes.h"
/**********************************************************************
* PrintFileHeader
*/
void
PrintFileHeader(struct ne_header_s *ne_header)
{
printf("ne_header: %c%c\n",
ne_header->ne_magic & 0xff,
ne_header->ne_magic >> 8 );
printf("linker version: %d.%d\n", ne_header->linker_version,
ne_header->linker_revision);
printf("format flags: %04x\n", ne_header->format_flags);
printf("automatic data segment: %04x\n", ne_header->auto_data_seg);
printf("CS:IP %04x:%04x\n", ne_header->cs, ne_header->ip);
printf("SS:SP %04x:%04x\n", ne_header->ss, ne_header->sp);
printf("additional flags: %02x\n", ne_header->additional_flags);
printf("operating system: %02x\n", ne_header->operating_system);
printf("fast load offset: %04x\n", ne_header->fastload_offset);
printf("fast load length: %04x\n", ne_header->fastload_length);
}
/**********************************************************************
* PrintRelocationTable
*/
void
PrintRelocationTable(char *exe_ptr,
struct ne_segment_table_entry_s *seg_entry_p,
int segment)
{
struct relocation_entry_s *rep;
int i;
int offset;
u_short n_entries, *sp;
printf("RELOCATION TABLE %d:\n", segment + 1);
if (seg_entry_p->seg_data_offset == 0)
return;
offset = seg_entry_p->seg_data_length;
if (offset == 0)
offset = 0x10000;
sp = (u_short *) (exe_ptr + seg_entry_p->seg_data_offset * 512 + offset);
n_entries = *sp;
rep = (struct relocation_entry_s *) (sp + 1);
for (i = 0; i < n_entries; i++, rep++)
{
printf(" ADDR TYPE %d, TYPE %d, OFFSET %04x,",
rep->address_type, rep->relocation_type, rep->offset);
printf("TARGET %04x %04x\n", rep->target1, rep->target2);
}
}
#endif /* ifndef WINELIB */

View File

@ -11,6 +11,18 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include <string.h>
#include <errno.h>
#include "windows.h"
#include "module.h"
#include "task.h"
#include "selectors.h"
#include "comm.h"
#include "user.h"
#include "menu.h"
#include "atom.h"
#include "dialog.h"
#include "message.h"
#include "syscolor.h"
#include "sysmetrics.h"
#include "gdi.h"
#include "debugger.h"
#include "dos_fs.h"
#include "dlls.h"
@ -18,6 +30,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
#include "neexe.h"
#include "options.h"
#include "task.h"
#include "dce.h"
#include "pe_image.h"
#include "stddebug.h"
#include "debug.h"
@ -29,6 +42,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
int MAIN_Init(void)
{
extern BOOL RELAY_Init(void);
extern BOOL RELAY32_Init(void);
int queueSize;
@ -103,14 +117,22 @@ int MAIN_Init(void)
int _WinMain(int argc, char **argv)
{
int i;
HANDLE handle;
if (!MAIN_Init()) return 0;
for (i = 1; i < argc; i++)
{
if (WinExec( argv[i], SW_SHOWNORMAL ) < 32)
if ((handle = WinExec( argv[i], SW_SHOWNORMAL )) < 32)
{
fprintf(stderr, "wine: can't exec '%s'.\n", argv[i]);
fprintf(stderr, "wine: can't exec '%s': ", argv[i]);
switch (handle)
{
case 2: fprintf( stderr, "file not found\n" ); break;
case 11: fprintf( stderr, "invalid exe file\n" ); break;
case 21: fprintf( stderr, "win32 executable\n" ); break;
default: fprintf( stderr, "error=%d\n", handle ); break;
}
exit(1);
}
}

View File

@ -21,7 +21,6 @@
#include "task.h"
#include "toolhelp.h"
#include "stddebug.h"
/* #define DEBUG_MODULE */
#include "debug.h"
@ -53,7 +52,7 @@ BOOL MODULE_Init(void)
hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->module_start,
table->module_end - table->module_start,
0, FALSE, FALSE, FALSE );
0, FALSE, FALSE, FALSE, NULL );
if (!hModule) return FALSE;
FarSetOwner( hModule, hModule );
@ -69,7 +68,7 @@ BOOL MODULE_Init(void)
pSegTable->selector = GLOBAL_CreateBlock(GMEM_FIXED, table->code_start,
pSegTable->minsize, hModule,
TRUE, TRUE, FALSE );
TRUE, TRUE, FALSE, NULL );
if (!pSegTable->selector) return FALSE;
pSegTable++;
@ -99,35 +98,34 @@ BOOL MODULE_Init(void)
MODULE_SetEntryPoint( hModule, 183, /* KERNEL.183: __0000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 193, /* KERNEL.193: __0040H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x400,
0x100, hModule, FALSE, FALSE, FALSE ) );
0x100, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 174, /* KERNEL.174: __A000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x10000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 181, /* KERNEL.181: __B000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x20000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 182, /* KERNEL.182: __B800H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x28000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 195, /* KERNEL.195: __C000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x30000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 179, /* KERNEL.179: __D000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x40000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 190, /* KERNEL.190: __E000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x50000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 173, /* KERNEL.173: __ROMBIOS */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
MODULE_SetEntryPoint( hModule, 194, /* KERNEL.194: __F000H */
GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
0x10000, hModule, FALSE, FALSE, FALSE ) );
0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
return TRUE;
}
@ -304,15 +302,8 @@ static BOOL MODULE_CreateSegments( HMODULE hModule )
{
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
if (i == pModule->ss) minsize += pModule->stack_size;
if (i == pModule->dgroup)
{
#if 0
/* FIXME: this is needed because heap growing is not implemented */
pModule->heap_size = 0x10000 - minsize;
#endif
/* The DGROUP is allocated by MODULE_CreateInstance */
continue;
}
/* The DGROUP is allocated by MODULE_CreateInstance */
if (i == pModule->dgroup) continue;
pSegment->selector = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
minsize, hModule,
!(pSegment->flags & NE_SEGFLAGS_DATA),
@ -1013,6 +1004,12 @@ BOOL FreeModule( HANDLE hModule )
/**********************************************************************
* GetModuleHandle (KERNEL.47)
*/
HMODULE WIN16_GetModuleHandle( SEGPTR name )
{
if (HIWORD(name) == 0) return GetExePtr( LOWORD(name) );
return MODULE_FindModule( PTR_SEG_TO_LIN(name) );
}
HMODULE GetModuleHandle( LPCSTR name )
{
return MODULE_FindModule( name );

View File

@ -197,7 +197,7 @@ HINSTANCE PE_LoadImage(struct w_files *wpnt)
wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
}
if(result==-1){
fprintf(stderr,"Could not load section %x to desired address %x\n",
fprintf(stderr,"Could not load section %x to desired address %lx\n",
i, load_addr+wpnt->pe->pe_seg[i].Virtual_Address);
fprintf(stderr,"Need to implement relocations now\n");
exit(0);

View File

@ -32,6 +32,16 @@
else \
dprintf_resource( stddeb, "#%04x", LOWORD(name));
/**********************************************************************
* LoadIconHandler (USER.456)
*/
HICON LoadIconHandler( HANDLE hResource, BOOL bNew )
{
return 0;
}
/**********************************************************************
* FindResource (KERNEL.60)
*/

View File

@ -8,33 +8,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef WINELIB
#ifdef __linux__
#include <sys/mman.h>
#include <linux/unistd.h>
#include <linux/head.h>
#include <linux/mman.h>
#include <linux/a.out.h>
#include <linux/ldt.h>
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <sys/mman.h>
#include <machine/segments.h>
#endif
#include "windows.h"
#include "ldt.h"
#include "wine.h"
#include "global.h"
#include "dlls.h"
#include "neexe.h"
#include "prototypes.h"
#include "module.h"
#include "stddebug.h"
/* #define DEBUG_SELECTORS */

View File

@ -15,7 +15,6 @@
#endif
#include "debugger.h"
#include "prototypes.h"
#include "miscemu.h"
#include "registers.h"
#include "win.h"
@ -24,6 +23,7 @@
char * cstack[4096];
#endif
struct sigaction segv_act;
struct sigaction usr2_act;
#ifdef linux
extern void ___sig_restore();
@ -71,15 +71,21 @@ static void win_fault(int signal, int code, struct sigcontext *context)
void init_wine_signals(void)
{
extern void stop_wait(int a);
#ifdef linux
segv_act.sa_handler = (__sighandler_t) win_fault;
/* Point to the top of the stack, minus 4 just in case, and make
it aligned */
segv_act.sa_restorer =
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
usr2_act.sa_restorer= segv_act.sa_restorer;
usr2_act.sa_handler = (__sighandler_t) stop_wait;
/* Point to the top of the stack, minus 4 just in case, and make
it aligned */
wine_sigaction(SIGSEGV, &segv_act, NULL);
wine_sigaction(SIGILL, &segv_act, NULL);
wine_sigaction(SIGFPE, &segv_act, NULL);
wine_sigaction(SIGUSR2, &usr2_act, NULL);
#ifdef SIGBUS
wine_sigaction(SIGBUS, &segv_act, NULL);
#endif
@ -126,6 +132,13 @@ void init_wine_signals(void)
perror("sigaction: SIGTRAP");
exit(1);
}
usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
usr2_act.sa_flags = SA_ONSTACK;
usr2_act.sa_mask = sig_mask;
if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
perror("sigaction: SIGUSR2");
exit(1);
}
#endif
}

View File

@ -21,6 +21,7 @@
#include "toolhelp.h"
#include "stddebug.h"
#include "debug.h"
#include "dde_proc.h"
/* Min. number of thunks allocated when creating a new segment */
#define MIN_THUNKS 32
@ -247,7 +248,8 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
STACK16FRAME *frame16;
STACK32FRAME *frame32;
extern DWORD CALL16_RetAddr_word;
char filename[256];
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
pSegTable = NE_SEG_TABLE( pModule );
@ -258,6 +260,12 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
if (!hTask) return 0;
pTask = (TDB *)GlobalLock( hTask );
/* get current directory */
GetModuleFileName( hModule, filename, sizeof(filename) );
name = strrchr(filename, '\\');
if (name) *(name+1) = 0;
/* Fill the task structure */
pTask->nEvents = 1; /* So the task can be started */
@ -268,10 +276,10 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
pTask->hPrevInstance = hPrevInstance;
pTask->hModule = hModule;
pTask->hParent = hCurrentTask;
pTask->curdrive = 'C' - 'A' + 0x80;
pTask->curdrive = filename[0] - 'A' + 0x80;
pTask->magic = TDB_MAGIC;
pTask->nCmdShow = cmdShow;
strcpy( pTask->curdir, "WINDOWS" );
strcpy( pTask->curdir, filename+2 );
/* Create the thunks block */
@ -302,13 +310,13 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
/* Allocate a selector for the PDB */
pTask->hPDB = GLOBAL_CreateBlock( GMEM_FIXED, &pTask->pdb, sizeof(PDB),
hModule, FALSE, FALSE, FALSE );
hModule, FALSE, FALSE, FALSE, NULL );
/* Allocate a code segment alias for the TDB */
pTask->hCSAlias = GLOBAL_CreateBlock( GMEM_FIXED, (void *)pTask,
sizeof(TDB), pTask->hPDB, TRUE,
FALSE, FALSE );
FALSE, FALSE, NULL );
/* Set the owner of the environment block */
@ -326,6 +334,7 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
/* Create the 32-bit stack frame */
*(DWORD *)GlobalLock(pTask->hStack32) = 0xDEADBEEF;
stack32Top = (char*)GlobalLock(pTask->hStack32) + STACK32_SIZE;
frame32 = (STACK32FRAME *)stack32Top - 1;
frame32->saved_esp = (DWORD)stack32Top;
@ -342,13 +351,13 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
/* Create the 16-bit stack frame */
pTask->ss = hInstance;
pTask->sp = (pModule->sp != 0) ? pModule->sp :
pSegTable[pModule->ss-1].minsize + pModule->stack_size;
pTask->sp = ((pModule->sp != 0) ? pModule->sp :
pSegTable[pModule->ss-1].minsize + pModule->stack_size) & ~1;
stack16Top = (char *)PTR_SEG_OFF_TO_LIN( pTask->ss, pTask->sp );
frame16 = (STACK16FRAME *)stack16Top - 1;
frame16->saved_ss = pTask->ss;
frame16->saved_sp = pTask->sp;
frame16->ds = pTask->hInstance;
frame16->ds = frame16->es = pTask->hInstance;
frame16->entry_point = 0;
frame16->ordinal_number = 24; /* WINPROCS.24 is TASK_Reschedule */
frame16->dll_id = 24; /* WINPROCS */
@ -461,6 +470,7 @@ void TASK_Reschedule(void)
TDB *pOldTask = NULL, *pNewTask;
HTASK hTask = 0;
dde_reschedule();
/* First check if there's a task to kill */
if (hTaskToKill && (hTaskToKill != hCurrentTask))

49
memory/Makefile.in Normal file
View File

@ -0,0 +1,49 @@
CC = @CC@
CFLAGS = @CFLAGS@
XINCL = @x_includes@
TOPSRC = @top_srcdir@
DIVINCL = -I$(TOPSRC)/include
LD = @LD@
LDCOMBINEFLAGS = @LDCOMBINEFLAGS@
MODULE = memory
SRCS = selector.c global.c ldt.c local.c
OBJS = $(SRCS:.c=.o)
.c.o:
$(CC) -c $(CFLAGS) $(XINCL) $(DIVINCL) -o $*.o $<
all: $(MODULE).o
$(MODULE).o: $(OBJS)
$(LD) $(LDCOMBINEFLAGS) $(OBJS) -o $(MODULE).o
depend:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
$(CC) $(DIVINCL) $(XINCL) -MM *.c >> tmp_make
cp tmp_make Makefile
rm tmp_make
clean:
rm -f *.o \#*\# *~ tmp_make
distclean: clean
rm Makefile
countryclean:
NAMES = $(SRCS:.c=)
winelibclean:
for i in $(NAMES); do \
if test `grep -c WINELIB $$i.c` -ne 0; then \
rm $$i.o; \
fi; \
done
dummy:
### Dependencies:

View File

@ -6,10 +6,12 @@
#include <stdlib.h>
#include <string.h>
#include "windows.h"
#include "global.h"
#include "toolhelp.h"
#include "selectors.h"
#include "dde_mem.h"
#include "stackframe.h"
#include "stddebug.h"
#include "debug.h"
@ -25,12 +27,14 @@ typedef struct
BYTE pageLockCount; /* Count of GlobalPageLock() calls */
BYTE flags; /* Allocation flags */
BYTE selCount; /* Number of selectors allocated for this block */
int shmid;
} GLOBALARENA;
/* Flags definitions */
#define GA_MOVEABLE 0x02 /* same as GMEM_MOVEABLE */
#define GA_DGROUP 0x04
#define GA_DISCARDABLE 0x08
#define GA_IPCSHARE 0x10 /* same as GMEM_DDESHARE */
/* Arena array */
static GLOBALARENA *pGlobalArena = NULL;
@ -62,6 +66,36 @@ static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
}
void debug_handles()
{
int printed=0;
int i;
for (i = globalArenaSize-1 ; i>=0 ; i--) {
if (pGlobalArena[i].size!=0 && (pGlobalArena[i].handle & 0x8000)){
printed=1;
printf("0x%08x, ",pGlobalArena[i].handle);
}
}
if (printed)
printf("\n");
}
/***********************************************************************
* GLOBAL_FindArena
*
* Find the arena for a given handle
* (when handle is not serial - e.g. DDE)
*/
static GLOBALARENA *GLOBAL_FindArena( HGLOBAL handle)
{
int i;
for (i = globalArenaSize-1 ; i>=0 ; i--) {
if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == handle)
return ( &pGlobalArena[i] );
}
return NULL;
}
/***********************************************************************
* GLOBAL_CreateBlock
*
@ -69,15 +103,18 @@ static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount )
*/
HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
HGLOBAL hOwner, BOOL isCode,
BOOL is32Bit, BOOL isReadOnly )
BOOL is32Bit, BOOL isReadOnly,
SHMDATA *shmdata )
{
WORD sel, selcount;
GLOBALARENA *pArena;
/* Allocate the selector(s) */
sel = SELECTOR_AllocBlock( ptr, size, isCode ? SEGMENT_CODE : SEGMENT_DATA,
is32Bit, isReadOnly );
sel = SELECTOR_AllocBlock( ptr, size,
isCode ? SEGMENT_CODE : SEGMENT_DATA,
is32Bit, isReadOnly );
if (!sel) return 0;
selcount = (size + 0xffff) / 0x10000;
@ -91,12 +128,23 @@ HGLOBAL GLOBAL_CreateBlock( WORD flags, void *ptr, DWORD size,
pArena->base = (DWORD)ptr;
pArena->size = GET_SEL_LIMIT(sel) + 1;
pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
if (flags & GMEM_DDESHARE)
{
pArena->handle = shmdata->handle;
pArena->shmid = shmdata->shmid;
shmdata->sel = sel;
}
else
{
pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel;
pArena->shmid = 0;
}
pArena->hOwner = hOwner;
pArena->lockCount = 0;
pArena->pageLockCount = 0;
pArena->flags = flags & GA_MOVEABLE;
if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE;
if (flags & GMEM_DDESHARE) pArena->flags |= GA_IPCSHARE;
if (!isCode) pArena->flags |= GA_DGROUP;
pArena->selCount = selcount;
if (selcount > 1) /* clear the next arena blocks */
@ -119,7 +167,7 @@ BOOL GLOBAL_FreeBlock( HGLOBAL handle )
if (!handle) return TRUE;
sel = GlobalHandleToSel( handle );
if (FreeSelector( sel )) return FALSE; /* failed */
memset( GET_ARENA_PTR(handle), 0, sizeof(GLOBALARENA) );
memset( GET_ARENA_PTR(sel), 0, sizeof(GLOBALARENA) );
return TRUE;
}
@ -134,6 +182,7 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
{
void *ptr;
HGLOBAL handle;
SHMDATA shmdata;
dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags );
@ -145,13 +194,16 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
/* Allocate the linear memory */
ptr = malloc( size );
if (flags & GMEM_DDESHARE)
ptr= DDE_malloc(flags, size, &shmdata);
else
ptr = malloc( size );
if (!ptr) return 0;
/* Allocate the selector(s) */
handle = GLOBAL_CreateBlock( flags, ptr, size, hOwner,
isCode, is32Bit, isReadOnly);
isCode, is32Bit, isReadOnly, &shmdata);
if (!handle)
{
free( ptr );
@ -162,6 +214,29 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner,
return handle;
}
/***********************************************************************
* DDE_GlobalHandleToSel
*/
WORD DDE_GlobalHandleToSel( HGLOBAL handle )
{
GLOBALARENA *pArena;
SEGPTR segptr;
pArena= GLOBAL_FindArena(handle);
if (pArena) {
int ArenaIdx = pArena - pGlobalArena;
/* See if synchronized to the shared memory */
return DDE_SyncHandle(handle, ( ArenaIdx << __AHSHIFT) | 7);
}
/* attach the block */
DDE_AttachHandle(handle, &segptr);
return SELECTOROF( segptr );
}
/***********************************************************************
* GlobalAlloc (KERNEL.15)
@ -172,7 +247,6 @@ HGLOBAL GlobalAlloc( WORD flags, DWORD size )
if (flags & GMEM_DDESHARE)
owner = GetExePtr(owner); /* Make it a module handle */
return GLOBAL_Alloc( flags, size, owner, FALSE, FALSE, FALSE );
}
@ -182,14 +256,22 @@ HGLOBAL GlobalAlloc( WORD flags, DWORD size )
*/
HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
{
WORD sel, selcount;
WORD selcount;
DWORD oldsize;
void *ptr;
GLOBALARENA *pArena, *pNewArena;
WORD sel = GlobalHandleToSel( handle );
dprintf_global( stddeb, "GlobalReAlloc: %04x %ld flags=%04x\n",
handle, size, flags );
if (!handle) return 0;
if (flags & GMEM_DDESHARE || is_dde_handle(handle)) {
fprintf(stdnimp,
"GlobalReAlloc: shared memory reallocating unimplemented\n");
return 0;
}
pArena = GET_ARENA_PTR( handle );
/* Discard the block if requested */
@ -201,6 +283,10 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
(pArena->lockCount > 0) || (pArena->pageLockCount > 0)) return 0;
free( (void *)pArena->base );
pArena->base = 0;
/* Note: we rely on the fact that SELECTOR_ReallocBlock won't */
/* change the selector if we are shrinking the block */
SELECTOR_ReallocBlock( sel, 0, 1, SEGMENT_DATA, 0, 0 );
return handle;
}
/* Fixup the size */
@ -221,7 +307,6 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
/* Reallocate the linear memory */
sel = GlobalHandleToSel( handle );
ptr = (void *)pArena->base;
oldsize = pArena->size;
dprintf_global(stddeb,"oldsize %08lx\n",oldsize);
@ -275,12 +360,12 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
*/
HGLOBAL GlobalFree( HGLOBAL handle )
{
void *ptr;
void *ptr = GlobalLock( handle );
dprintf_global( stddeb, "GlobalFree: %04x\n", handle );
if (!(ptr = GlobalLock( handle ))) return handle; /* failed */
if (!GLOBAL_FreeBlock( handle )) return handle; /* failed */
free( ptr );
if (is_dde_handle(handle)) return DDE_GlobalFree(handle);
if (ptr) free( ptr );
return 0;
}
@ -295,7 +380,9 @@ SEGPTR WIN16_GlobalLock( HGLOBAL handle )
dprintf_global( stddeb, "WIN16_GlobalLock(%04x) -> %08lx\n",
handle, MAKELONG( 0, GlobalHandleToSel(handle)) );
if (!handle) return 0;
if (!GET_ARENA_PTR(handle)->base) return (SEGPTR)0;
if ( !is_dde_handle(handle) && !GET_ARENA_PTR(handle)->base)
return (SEGPTR)0;
return (SEGPTR)MAKELONG( 0, GlobalHandleToSel(handle) );
}
@ -308,6 +395,9 @@ SEGPTR WIN16_GlobalLock( HGLOBAL handle )
LPSTR GlobalLock( HGLOBAL handle )
{
if (!handle) return 0;
if (is_dde_handle(handle)) {
return DDE_AttachHandle(handle, NULL);
}
return (LPSTR)GET_ARENA_PTR(handle)->base;
}
@ -552,6 +642,9 @@ WORD GlobalHandleToSel( HGLOBAL handle )
{
dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle );
if (!handle) return 0;
if (is_dde_handle(handle))
return DDE_GlobalHandleToSel(handle);
if (!(handle & 7))
{
fprintf( stderr, "Program attempted invalid selector conversion\n" );

View File

@ -157,7 +157,8 @@ int LDT_SetEntry( int entry, const ldt_entry *content )
ldt_flags_copy[entry] = (content->type & LDT_FLAGS_TYPE) |
(content->read_only ? LDT_FLAGS_READONLY : 0) |
(content->seg_32bit ? LDT_FLAGS_32BIT : 0) |
(content->limit_in_pages ? LDT_FLAGS_BIG : 0);
(content->limit_in_pages ? LDT_FLAGS_BIG : 0) |
(ldt_flags_copy[entry] & LDT_FLAGS_ALLOCATED);
return ret;
}

Some files were not shown because too many files have changed in this diff Show More