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:
parent
ded3038c1c
commit
e2991ea7bd
21
ANNOUNCE
21
ANNOUNCE
|
@ -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
190
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
11
Imakefile
11
Imakefile
|
@ -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`
|
||||
|
|
|
@ -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
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/* @configure_input@ */
|
||||
#define WINE_INI_GLOBAL @WINE_INI_GLOBAL@
|
||||
#define AutoDefines @LANG@
|
File diff suppressed because it is too large
Load Diff
|
@ -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:
|
|
@ -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:
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
|
@ -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'); }
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
|
@ -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;
|
||||
}
|
|
@ -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 },
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
** Unix system-dependant routines for editline library.
|
||||
*/
|
||||
#include "editline.h"
|
||||
#include "config.h"
|
||||
|
||||
#if defined(HAVE_TCGETATTR)
|
||||
#include <termios.h>
|
||||
|
|
|
@ -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 */
|
||||
}
|
|
@ -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) */
|
|
@ -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:
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
381
include/debug.h
381
include/debug.h
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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)])
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
struct options
|
||||
{
|
||||
char * spyFilename;
|
||||
char * desktopGeometry; /* NULL when no desktop */
|
||||
char * programName; /* To use when loading resources */
|
||||
int usePrivateMap;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "ldt.h"
|
||||
#include "local.h"
|
||||
|
||||
extern BOOL USER_HeapInit(void);
|
||||
/* USER local heap */
|
||||
|
||||
#ifdef WINELIB
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
/* WINEOPTS.H
|
||||
*/
|
||||
|
||||
#ifndef WINEOPTS_H
|
||||
#define WINEOPTS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
FILE *SpyFp;
|
||||
|
||||
#endif /* WINEOPTS_H */
|
|
@ -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
|
||||
|
|
|
@ -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::
|
|
@ -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:
|
|
@ -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
|
|
@ -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]
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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] );
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -3,7 +3,6 @@
|
|||
MODULE = loader
|
||||
|
||||
SRCS = \
|
||||
dump.c \
|
||||
main.c \
|
||||
module.c \
|
||||
ne_image.c \
|
||||
|
|
|
@ -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:
|
|
@ -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 */
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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:
|
121
memory/global.c
121
memory/global.c
|
@ -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" );
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue