Release 971221
Fri Dec 19 10:50:46 1997 Douglas Ridgway <ridgway@winehq.com>
* [Make.rules.in] [Makefile.in] [documentation/Makefile.in]
[documentation/README.documentation]
First cut at Wine API documentation. No longer install reference
manual by default.
Wed Dec 17 21:32:23 1997 Andreas Mohr <100.30936@germany.net>
* [files/file.c]
Fixed GetTempFileName16() to use current path of requested drive
as needed.
* [if1632/Makefile.in] [if1632/builtin.c] [if1632/dciman32.spec]
[if1632/msvfw32.spec] [if1632/tapi32.spec] [if1632/wow32.spec]
Added misc DLLs needed by various apps.
Wed Dec 17 12:01:50 1997 Morten Eriksen <mortene@sim.no>
* [if1632/gdi32.spec] [include/windows.h] [objects/palette.c]
Inserted empty stub for CreateHalftonePalette.
Tue Dec 16 22:08:06 1997 Huw D M Davies <h.davies1@physics.oxford.ac.uk>
* [windows/mdi.c]
Use VK_TAB instead of VK_SEPARATOR in TranslateMDISysAccel().
* [graphics/metafiledrv/init.c]
DeleteDC() on a MetaDC doesn't do anything - it shouldn't. Therefore
fix cleanup of MetaDCs in CloseMetaFile(); they now actually get
removed from the GDI heap!
* [graphics/x11drv/xfont.c]
Preserve FO_MATCH_XYINDEP flag in XFONT_MatchFIList(). Should reduce
the number of bold-italic matches.
Tue Dec 16 20:11:43 1997 Bertho Stultiens <bertho@panter.soci.aau.dk>
* [graphics/painting.c]
Included an implementation of DrawState
* [if1632/thunk.c]
Changed many fprintfs into dprintf_thunk
* [include/cache.h] [graphics/cache.c]
New files to hold cached handles to regulary used GDI object.
* [include/windows.h]
Added DRAWSTATExx typedefs
Added DSS_DEFAULT define for DrawState
* [objects/text.c]
New implementation of GrayString()
* [controls/uitools.c]
Implemented DrawFrameControl() functions
Changed DrawEdge() behaviour to win95 implementation
Mon Dec 15 23:43:01 1997 Martin Boehme <boehme@informatik.mu-luebeck.de>
* [graphics/path.c] [include/path.h] [graphics/painting.c]
[if1632/gdi32.spec] [include/gdi.h] [include/windows.h]
[objects/dc.c]
Added preliminary support for GDI paths.
* [objects/dc.c]
Added DC_Init_DC_INFO function for initializing WIN_DC_INFO
structure.
* [include/windows.h] [include/gdi.h] [objects/gdiobj.c]
Added DEFAULT_GUI_FONT.
* [include/winerror.h]
Added a few error codes.
* [memory/heap.c]
Changed HeapAlloc to make the correct calls to SetLastError
(now conforms to NT's behaviour).
* [windows/win.c]
Changed WIN_CreateWindowEx to allow child windows with zero
width / height.
Sun Dec 14 12:01:07 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [if1632/*] [relay32/*]
Moved all 32-bit relay stuff to relay32/
* [fi1632/thunk.c] [win32/kernel32.c]
Moved all KERNEL32 ordinal functions to kernel32.c
* [memory/selector.c]
Initialize selectors in AllocSelectorArray.
* [tools/build.c]
Generate C instead of assembly for Win32 relays.
Fixed stack corruption in CallTo16 functions, found by Bertho
Stultiens.
Sun Dec 14 10:55:00 1997 Andreas Mohr <100.30936@germany.net>
* [if1632/Makefile.in] [if1632/builtin.c] [if1632/ole2thk.spec]
Added built-in OLE2THK.DLL.
* [if1632/toolhelp.spec] [include/toolhelp.h] [memory/selector.c]
[misc/toolhelp.c]
Added stubs for StackTraceFirst(), StackTraceCSIPFirst(),
StackTraceNext(), UTSelectorOffsetToLinear()
and UTLinearToSelectorOffset().
Sat Dec 13 17:26:41 1997 Alex Korobka <alex@trantor.pharm.sunysb.edu>
* [misc/winsock.c]
32-bit API fixes for reported problems (thanks to Marcus
and David).
* [graphics/x11drv/xfont.c]
Little tweak in point size calculation.
* [windows/defwnd.c] [windows/dce.c] [windows/winhelp.c]
[windows/winproc.c] [windows/win.c]
Bug fixes.
Sat Dec 13 16:35:14 1997 Kai Morich <kai.morich@rhein-neckar.netsurf.de>
* [files/dos_fs.c]
OpenFile with empty filename and OF_PARSE returns current dir.
* [misc/commdlg.c]
Ignore initial dir if bogus.
* [files/file.c]
Locking an identic region in a file must not be an error.
* [misc/lstr.c]
Use wide char ctype functions.
Fri Dec 12 23:46:22 1997 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
* [file/drive.c]
First attempt for GetDiskFreeSpaceEx.
Fri Dec 12 23:18:41 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [loader/pe_resource.c]
Fixed wrongly appearing menus problem (only use default lookups in
last resource subtree).
* [multimedia/*.c]
Added win32 support for time* and joy* lowlevel drivers,
(not excessively tested), some misc fixes and cleanups.
* [misc/shellord.c][misc/shell.c][ole/folders.c][ole/ifs.c]
[include/interfaces.h][include/shlobj.h]
Added some more undocumented SHELL32 functions, some shell folder
interface stubs added, SHGetMalloc, SHGetDesktopFolder,
SHGetSpecialFolderLocation, SHGetPathFromIDList stubs added,
IMalloc, IUnknown implemented.
* [windows/msgbox.c]
Implemented MessageBoxIndirect*, some internal changes.
* [if1632/thunk.c]
KERNEL_431 implemented.
* [objects/gdiobj.c]
GetCurrentObject implemented.
Wed Dec 3 01:09:17 1997 Gordon Chaffee <chaffee@apu.cs.berkeley.edu>
* [objects/dib.c]
Fix a couple small DIB problems.
* [controls/edit.c]
Fix a typo.
* [files/dos_fs.c]
Try normal readdir in case fs is specified as vfat but isn't.
* [files/profile.c]
Implementation of WritePrivateProfileSection32A from Uwe Bonnes.
* [misc/printdrv.c]
OpenPrinter32A stub, helps Word97 start.
* [objects/text.c]
Fixup implementation of GetTextCharsetInfo.
* [scheduler/process.c]
Fix environment variable expansion.
* [win32/code_page.c]
Make MultiByteToWideChar and WideCharToMultiByte conform in return
values and error conditions to those in Windows NT 4.0.
* [windows/message.c]
Fix broadcasting problems in Win32. The Win32 docs say to use
HWND_TOPMOST to broadcast to all Win32 Windows.
* [memory/virtual.c] [loader/pe_image.c]
Do not map in VirtualAlloc if address is specified and space is
not available. This is required by Win32.
* [include/pen.h] [include/x11drv.h] [objects/dc.c]
[objects/pen.c] [graphics/x11drv/pen.c]
Support for ExtCreatePen.
Tue Dec 2 20:22:06 1997 Morten Welinder <terra@diku.dk>
* [*/*.c] [*/*.h]
Add lots of prototypes.
* [if1632/kernel32.spec][include/windows.h][include/winnt.h]
[misc/cpu.c]
Define IsProcessorFeaturePresent.
* [misc/crtdll.c]
(CRTDLL__getcwd): Allocate enough memory for the terminating zero.
* [misc/ver.c]
Improve check for null component in _find_data[AW]. Plug leaks
in VerQueryValue*.
* [win32/console.c][if1632/kernel32.spec]
Add stubs for GetConsoleCursorInfo32, SetConsoleCursorInfo32.
* [windows/message.c][if1632/user32.spec][include/windows.h]
Define SendMessageTimeout*.
* [graphics/x11drv/xfont.c]
Change algorithm of __genericCheckSum to be alignment safe.
* [misc/main.c] [misc/winsock.c] [misc/winsock_dns.c]
Include winsock.h early to avoid Solaris problem.
* [include/windows.h]
Undef FSHIFT before we define it.
* [rc/winerc.c]
Include <fcntl.h> instead of <sys/fcntl.h>.
* [files/file.c]
Use strerror in FILE_SetDosError if available.
* [include/config.h.in] [configure.in]
Check for strerror.
* [objects/gdiobj.c]
Make static font structures aligned.
Mon Dec 1 10:10:21 1997 Karl Garrison <karlos@eznet.net>
* [win32/console.c] [if1632/kernel32.spec] [include/windows.h]
Added stub for GetNumberOfConsoleMouseButtons.
Added stub for PeekConsoleInput(A,W).
Fixed parameter list for WriteConsole(A,W).
GetNumberOfConsoleInputEvents now returns 0 events instead of 1
(since low-level console functions are not yet supported).
GetConsoleMode no longer returns ENABLE_WINDOW_INPUT and
ENABLE_MOUSE_INPUT since these are not currently implemented.
diff --git a/ANNOUNCE b/ANNOUNCE
index 93c7b24..3f2c359 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,16 @@
-This is release 971130 of Wine, the MS Windows emulator. This is still a
+This is release 971221 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 correctly.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
-WHAT'S NEW with Wine-971130: (see ChangeLog for details)
- - Better Win32s support.
- - Lots of new Win32 functions.
- - DIB handling improvements.
+WHAT'S NEW with Wine-971221: (see ChangeLog for details)
+ - Preliminary GDI paths support.
+ - DrawFrameControl implementation.
+ - Multimedia support for time and joystick functions.
+ - Win32 spec files now generate C code for Winelib.
+ - Tons of new Win32 functions and stubs.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@@ -17,10 +19,10 @@
the release is available at the ftp sites. The sources will be available
from the following locations:
- ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-971130.tar.gz
- ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-971130.tar.gz
- ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-971130.tar.gz
- ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-971130.tar.gz
+ ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-971221.tar.gz
+ ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-971221.tar.gz
+ ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-971221.tar.gz
+ ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-971221.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
diff --git a/AUTHORS b/AUTHORS
index cd18940..616a2e6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -102,6 +102,7 @@
William Smith,
Dominik Strasser,
Vadim Strizhevsky,
+Bertho Stultiens,
Erik Svendsen,
Tristan Tarrant,
Andrew Taylor,
diff --git a/BUGS b/BUGS
index cc9b8c0..8e339b2 100644
--- a/BUGS
+++ b/BUGS
@@ -5,7 +5,7 @@
add new entries and, more importantly, remove those for the
bugs you fixed ;-)
------------------------------------------------------------
-As of Nov 1997 -
+As of Dec 1997 -
General:
@@ -32,13 +32,15 @@
Miscellaneous:
- * Invisible controls in BCW dialogs.
+ * 16-bit Eudora 1.5.2 goes into recursion trying to display
+ a horizontal scrollbar (SetScrollPos() artifact).
* mIRC 'commands' menu stays on top and will not refresh.
* mIRC is unable to show 'Options' dialog.
- * Tab switching in mIRC 'Setup' dialog leaks memory.
+ * Tab switching in mIRC 'Setup' dialog stops erasing background
+ after a random number of repetitions.
* nBytesWidth in CURSORICONINFO is bogus for some bpp
(doesn't reflect the fact that bits are packed and 16-bit aligned).
@@ -47,7 +49,7 @@
(probably because of bytes width stuff).
* Netscape displays partially downloaded inline graphics with
- wrong offsets. Bitmap is missing in the splash-window.
+ wrong offsets.
* Text alignment problems in Word and Write (variable pitch fonts).
@@ -62,6 +64,8 @@
* AllocCSToDSAlias() shouldn't alloc alias for the same segment multiple
times.
+ * X11DRV_PaintRgn doesn't respect mapping modes
+
Where to look in source files:
* grep for FIXME in the source files.
diff --git a/ChangeLog b/ChangeLog
index 76ac4ba..aad647d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,266 @@
----------------------------------------------------------------------
+Fri Dec 19 10:50:46 1997 Douglas Ridgway <ridgway@winehq.com>
+
+ * [Make.rules.in] [Makefile.in] [documentation/Makefile.in]
+ [documentation/README.documentation]
+ First cut at Wine API documentation. No longer install reference
+ manual by default.
+
+Wed Dec 17 21:32:23 1997 Andreas Mohr <100.30936@germany.net>
+
+ * [files/file.c]
+ Fixed GetTempFileName16() to use current path of requested drive
+ as needed.
+
+ * [if1632/Makefile.in] [if1632/builtin.c] [if1632/dciman32.spec]
+ [if1632/msvfw32.spec] [if1632/tapi32.spec] [if1632/wow32.spec]
+ Added misc DLLs needed by various apps.
+
+Wed Dec 17 12:01:50 1997 Morten Eriksen <mortene@sim.no>
+
+ * [if1632/gdi32.spec] [include/windows.h] [objects/palette.c]
+ Inserted empty stub for CreateHalftonePalette.
+
+Tue Dec 16 22:08:06 1997 Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+ * [windows/mdi.c]
+ Use VK_TAB instead of VK_SEPARATOR in TranslateMDISysAccel().
+
+ * [graphics/metafiledrv/init.c]
+ DeleteDC() on a MetaDC doesn't do anything - it shouldn't. Therefore
+ fix cleanup of MetaDCs in CloseMetaFile(); they now actually get
+ removed from the GDI heap!
+
+ * [graphics/x11drv/xfont.c]
+ Preserve FO_MATCH_XYINDEP flag in XFONT_MatchFIList(). Should reduce
+ the number of bold-italic matches.
+
+Tue Dec 16 20:11:43 1997 Bertho Stultiens <bertho@panter.soci.aau.dk>
+
+ * [graphics/painting.c]
+ Included an implementation of DrawState
+
+ * [if1632/thunk.c]
+ Changed many fprintfs into dprintf_thunk
+
+ * [include/cache.h] [graphics/cache.c]
+ New files to hold cached handles to regulary used GDI object.
+
+ * [include/windows.h]
+ Added DRAWSTATExx typedefs
+ Added DSS_DEFAULT define for DrawState
+
+ * [objects/text.c]
+ New implementation of GrayString()
+
+ * [controls/uitools.c]
+ Implemented DrawFrameControl() functions
+ Changed DrawEdge() behaviour to win95 implementation
+
+Mon Dec 15 23:43:01 1997 Martin Boehme <boehme@informatik.mu-luebeck.de>
+
+ * [graphics/path.c] [include/path.h] [graphics/painting.c]
+ [if1632/gdi32.spec] [include/gdi.h] [include/windows.h]
+ [objects/dc.c]
+ Added preliminary support for GDI paths.
+
+ * [objects/dc.c]
+ Added DC_Init_DC_INFO function for initializing WIN_DC_INFO
+ structure.
+
+ * [include/windows.h] [include/gdi.h] [objects/gdiobj.c]
+ Added DEFAULT_GUI_FONT.
+
+ * [include/winerror.h]
+ Added a few error codes.
+
+ * [memory/heap.c]
+ Changed HeapAlloc to make the correct calls to SetLastError
+ (now conforms to NT's behaviour).
+
+ * [windows/win.c]
+ Changed WIN_CreateWindowEx to allow child windows with zero
+ width / height.
+
+Sun Dec 14 12:01:07 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
+
+ * [if1632/*] [relay32/*]
+ Moved all 32-bit relay stuff to relay32/
+
+ * [fi1632/thunk.c] [win32/kernel32.c]
+ Moved all KERNEL32 ordinal functions to kernel32.c
+
+ * [memory/selector.c]
+ Initialize selectors in AllocSelectorArray.
+
+ * [tools/build.c]
+ Generate C instead of assembly for Win32 relays.
+ Fixed stack corruption in CallTo16 functions, found by Bertho
+ Stultiens.
+
+Sun Dec 14 10:55:00 1997 Andreas Mohr <100.30936@germany.net>
+
+ * [if1632/Makefile.in] [if1632/builtin.c] [if1632/ole2thk.spec]
+ Added built-in OLE2THK.DLL.
+
+ * [if1632/toolhelp.spec] [include/toolhelp.h] [memory/selector.c]
+ [misc/toolhelp.c]
+ Added stubs for StackTraceFirst(), StackTraceCSIPFirst(),
+ StackTraceNext(), UTSelectorOffsetToLinear()
+ and UTLinearToSelectorOffset().
+
+Sat Dec 13 17:26:41 1997 Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+ * [misc/winsock.c]
+ 32-bit API fixes for reported problems (thanks to Marcus
+ and David).
+
+ * [graphics/x11drv/xfont.c]
+ Little tweak in point size calculation.
+
+ * [windows/defwnd.c] [windows/dce.c] [windows/winhelp.c]
+ [windows/winproc.c] [windows/win.c]
+ Bug fixes.
+
+Sat Dec 13 16:35:14 1997 Kai Morich <kai.morich@rhein-neckar.netsurf.de>
+
+ * [files/dos_fs.c]
+ OpenFile with empty filename and OF_PARSE returns current dir.
+
+ * [misc/commdlg.c]
+ Ignore initial dir if bogus.
+
+ * [files/file.c]
+ Locking an identic region in a file must not be an error.
+
+ * [misc/lstr.c]
+ Use wide char ctype functions.
+
+Fri Dec 12 23:46:22 1997 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
+
+ * [file/drive.c]
+ First attempt for GetDiskFreeSpaceEx.
+
+Fri Dec 12 23:18:41 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+ * [loader/pe_resource.c]
+ Fixed wrongly appearing menus problem (only use default lookups in
+ last resource subtree).
+
+ * [multimedia/*.c]
+ Added win32 support for time* and joy* lowlevel drivers,
+ (not excessively tested), some misc fixes and cleanups.
+
+ * [misc/shellord.c][misc/shell.c][ole/folders.c][ole/ifs.c]
+ [include/interfaces.h][include/shlobj.h]
+ Added some more undocumented SHELL32 functions, some shell folder
+ interface stubs added, SHGetMalloc, SHGetDesktopFolder,
+ SHGetSpecialFolderLocation, SHGetPathFromIDList stubs added,
+ IMalloc, IUnknown implemented.
+
+ * [windows/msgbox.c]
+ Implemented MessageBoxIndirect*, some internal changes.
+
+ * [if1632/thunk.c]
+ KERNEL_431 implemented.
+
+ * [objects/gdiobj.c]
+ GetCurrentObject implemented.
+
+Wed Dec 3 01:09:17 1997 Gordon Chaffee <chaffee@apu.cs.berkeley.edu>
+
+ * [objects/dib.c]
+ Fix a couple small DIB problems.
+
+ * [controls/edit.c]
+ Fix a typo.
+
+ * [files/dos_fs.c]
+ Try normal readdir in case fs is specified as vfat but isn't.
+
+ * [files/profile.c]
+ Implementation of WritePrivateProfileSection32A from Uwe Bonnes.
+
+ * [misc/printdrv.c]
+ OpenPrinter32A stub, helps Word97 start.
+
+ * [objects/text.c]
+ Fixup implementation of GetTextCharsetInfo.
+
+ * [scheduler/process.c]
+ Fix environment variable expansion.
+
+ * [win32/code_page.c]
+ Make MultiByteToWideChar and WideCharToMultiByte conform in return
+ values and error conditions to those in Windows NT 4.0.
+
+ * [windows/message.c]
+ Fix broadcasting problems in Win32. The Win32 docs say to use
+ HWND_TOPMOST to broadcast to all Win32 Windows.
+
+ * [memory/virtual.c] [loader/pe_image.c]
+ Do not map in VirtualAlloc if address is specified and space is
+ not available. This is required by Win32.
+
+ * [include/pen.h] [include/x11drv.h] [objects/dc.c]
+ [objects/pen.c] [graphics/x11drv/pen.c]
+ Support for ExtCreatePen.
+
+Tue Dec 2 20:22:06 1997 Morten Welinder <terra@diku.dk>
+
+ * [*/*.c] [*/*.h]
+ Add lots of prototypes.
+
+ * [if1632/kernel32.spec][include/windows.h][include/winnt.h]
+ [misc/cpu.c]
+ Define IsProcessorFeaturePresent.
+
+ * [misc/crtdll.c]
+ (CRTDLL__getcwd): Allocate enough memory for the terminating zero.
+
+ * [misc/ver.c]
+ Improve check for null component in _find_data[AW]. Plug leaks
+ in VerQueryValue*.
+
+ * [win32/console.c][if1632/kernel32.spec]
+ Add stubs for GetConsoleCursorInfo32, SetConsoleCursorInfo32.
+
+ * [windows/message.c][if1632/user32.spec][include/windows.h]
+ Define SendMessageTimeout*.
+
+ * [graphics/x11drv/xfont.c]
+ Change algorithm of __genericCheckSum to be alignment safe.
+
+ * [misc/main.c] [misc/winsock.c] [misc/winsock_dns.c]
+ Include winsock.h early to avoid Solaris problem.
+
+ * [include/windows.h]
+ Undef FSHIFT before we define it.
+
+ * [rc/winerc.c]
+ Include <fcntl.h> instead of <sys/fcntl.h>.
+
+ * [files/file.c]
+ Use strerror in FILE_SetDosError if available.
+
+ * [include/config.h.in] [configure.in]
+ Check for strerror.
+
+ * [objects/gdiobj.c]
+ Make static font structures aligned.
+
+Mon Dec 1 10:10:21 1997 Karl Garrison <karlos@eznet.net>
+
+ * [win32/console.c] [if1632/kernel32.spec] [include/windows.h]
+ Added stub for GetNumberOfConsoleMouseButtons.
+ Added stub for PeekConsoleInput(A,W).
+ Fixed parameter list for WriteConsole(A,W).
+ GetNumberOfConsoleInputEvents now returns 0 events instead of 1
+ (since low-level console functions are not yet supported).
+ GetConsoleMode no longer returns ENABLE_WINDOW_INPUT and
+ ENABLE_MOUSE_INPUT since these are not currently implemented.
+
+----------------------------------------------------------------------
Sat Nov 29 12:35:26 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [if1632/builtin.c]
diff --git a/Make.rules.in b/Make.rules.in
index e27e88b..7b1e7d7 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -36,6 +36,7 @@
AR = ar rc
RM = rm -f
MKDIR = mkdir
+C2MAN = c2man
BUILD = $(TOPOBJDIR)/tools/build@PROGEXT@
MAKEDEP = $(TOPOBJDIR)/tools/makedep@PROGEXT@
WINERC = $(TOPOBJDIR)/rc/winerc@PROGEXT@
@@ -108,6 +109,10 @@
$(MODULE).o: $(OBJS)
$(LDCOMBINE) $(OBJS) -o $(MODULE).o
+# Rule for man pages
+
+man: $(C_SRCS)
+ for i in $(C_SRCS); do $(C2MAN) -L -o$(TOPOBJDIR)/documentation/man3w -S3w $(DIVINCL) $$i; done
# Misc. rules
diff --git a/Makefile.in b/Makefile.in
index c326756..c34c3b6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -7,6 +7,7 @@
# install: install everything
# depend: create the dependencies
# etags: create a TAGS file for Emacs.
+# manpages: compile manpages for Wine API
#
# Main target to build
@@ -24,6 +25,7 @@
LIBSUBDIRS = \
rc \
+ tools \
controls \
files \
graphics \
@@ -44,11 +46,11 @@
windows
EMUSUBDIRS = \
- tools \
debugger \
graphics/win16drv \
if1632 \
- miscemu
+ miscemu \
+ relay32
PROGSUBDIRS = libtest programs
@@ -90,7 +92,8 @@
debugger/debugger.o \
graphics/win16drv/win16drv.o \
if1632/if1632.o \
- miscemu/miscemu.o
+ miscemu/miscemu.o \
+ relay32/relay32.o
all: $(MAIN_TARGET)
@@ -139,6 +142,10 @@
TAGS etags:
etags `find $(TOPSRCDIR) -name '*.[chS]' -print | grep -v dbgmain`
+manpages:
+ -$(MKDIR) $(TOPOBJDIR)/documentation/man3w
+ for i in $(LIBSUBDIRS); do (cd $$i && $(MAKE) man); done
+
clean::
for i in $(ALLSUBDIRS); do (cd $$i; $(MAKE) clean) || exit 1; done
for i in include; do (cd $$i; $(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc); done
diff --git a/configure b/configure
index 5699464..1032ff2 100755
--- a/configure
+++ b/configure
@@ -2070,7 +2070,7 @@
-for ac_func in memmove tcgetattr usleep wait4 waitpid
+for ac_func in memmove strerror tcgetattr usleep wait4 waitpid
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2077: checking for $ac_func" >&5
@@ -2523,10 +2523,12 @@
objects/Makefile
ole/Makefile
programs/Makefile
+programs/notepad/Makefile
programs/progman/Makefile
programs/winhelp/Makefile
programs/winver/Makefile
rc/Makefile
+relay32/Makefile
resources/Makefile
scheduler/Makefile
tools/Makefile
@@ -2647,10 +2649,12 @@
objects/Makefile
ole/Makefile
programs/Makefile
+programs/notepad/Makefile
programs/progman/Makefile
programs/winhelp/Makefile
programs/winver/Makefile
rc/Makefile
+relay32/Makefile
resources/Makefile
scheduler/Makefile
tools/Makefile
diff --git a/configure.in b/configure.in
index 8c1186c..11b26ab 100644
--- a/configure.in
+++ b/configure.in
@@ -114,7 +114,7 @@
dnl **** Check for functions and header files ****
-AC_CHECK_FUNCS(memmove tcgetattr usleep wait4 waitpid)
+AC_CHECK_FUNCS(memmove strerror tcgetattr usleep wait4 waitpid)
AC_HEADER_STAT()
AC_C_CONST()
AC_TYPE_SIZE_T()
@@ -148,10 +148,12 @@
objects/Makefile
ole/Makefile
programs/Makefile
+programs/notepad/Makefile
programs/progman/Makefile
programs/winhelp/Makefile
programs/winver/Makefile
rc/Makefile
+relay32/Makefile
resources/Makefile
scheduler/Makefile
tools/Makefile
diff --git a/controls/edit.c b/controls/edit.c
index b4cd3ac..303d2f1 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -3494,7 +3494,7 @@
e = EDIT_CharFromPos(wnd, es, x, y, &after_wrap);
EDIT_EM_SetSel(wnd, es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap);
EDIT_EM_ScrollCaret(wnd, es);
- es->region_posx = es->region_posx = 0;
+ es->region_posx = es->region_posy = 0;
SetTimer32(wnd->hwndSelf, 0, 100, NULL);
return 0;
}
diff --git a/controls/menu.c b/controls/menu.c
index 35a89f1..8c2e984 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -3878,7 +3878,7 @@
BOOL32 WINAPI InsertMenuItem32A(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos,
const MENUITEMINFO32A *lpmii)
{
- MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos);
+ MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0 );
return SetMenuItemInfo32_common(item, lpmii, FALSE);
}
@@ -3889,7 +3889,7 @@
BOOL32 WINAPI InsertMenuItem32W(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos,
const MENUITEMINFO32W *lpmii)
{
- MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos);
+ MENUITEM *item = MENU_InsertItem(hMenu, uItem, bypos ? MF_BYPOSITION : 0 );
return SetMenuItemInfo32_common(item, (const MENUITEMINFO32A*)lpmii, TRUE);
}
diff --git a/controls/uitools.c b/controls/uitools.c
index b245ebc..e3c64de 100644
--- a/controls/uitools.c
+++ b/controls/uitools.c
@@ -2,12 +2,93 @@
* User Interface Functions
*
* Copyright 1997 Dimitrie O. Paun
+ * Copyright 1997 Bertho A. Stultiens
*/
#include <stdio.h>
#include "windows.h"
#include "debug.h"
+static const WORD wPattern_AA55[8] = { 0xaaaa, 0x5555, 0xaaaa, 0x5555,
+ 0xaaaa, 0x5555, 0xaaaa, 0x5555 };
+
+/* These tables are used in:
+ * UITOOLS_DrawDiagEdge()
+ * UITOOLS_DrawRectEdge()
+ */
+static const char LTInnerNormal[] = {
+ -1, -1, -1, -1,
+ -1, COLOR_BTNHIGHLIGHT, COLOR_BTNHIGHLIGHT, -1,
+ -1, COLOR_3DDKSHADOW, COLOR_3DDKSHADOW, -1,
+ -1, -1, -1, -1
+};
+
+static const char LTOuterNormal[] = {
+ -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1,
+ COLOR_BTNHIGHLIGHT, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1,
+ COLOR_3DDKSHADOW, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1,
+ -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1
+};
+
+static const char RBInnerNormal[] = {
+ -1, -1, -1, -1,
+ -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1,
+ -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1,
+ -1, -1, -1, -1
+};
+
+static const char RBOuterNormal[] = {
+ -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1,
+ COLOR_BTNSHADOW, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1,
+ COLOR_3DLIGHT, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1,
+ -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1
+};
+
+static const char LTInnerSoft[] = {
+ -1, -1, -1, -1,
+ -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1,
+ -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1,
+ -1, -1, -1, -1
+};
+
+static const char LTOuterSoft[] = {
+ -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1,
+ COLOR_3DLIGHT, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1,
+ COLOR_BTNSHADOW, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1,
+ -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1
+};
+
+#define RBInnerSoft RBInnerNormal /* These are the same */
+#define RBOuterSoft RBOuterNormal
+
+static const char LTRBOuterMono[] = {
+ -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
+ COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
+ COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
+ COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
+};
+
+static const char LTRBInnerMono[] = {
+ -1, -1, -1, -1,
+ -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
+ -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
+ -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW,
+};
+
+static const char LTRBOuterFlat[] = {
+ -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
+ COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
+ COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
+ COLOR_WINDOWFRAME, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW,
+};
+
+static const char LTRBInnerFlat[] = {
+ -1, -1, -1, -1,
+ -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
+ -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
+ -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME,
+};
+
/***********************************************************************
* UITOOLS_DrawDiagEdge
*
@@ -19,143 +100,252 @@
* using the brushes returned by GetSysColorBrush func, but I did not have
* the patience to implement that yet.
*/
-static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, RECT32 *rect, UINT32 edge,
- UINT32 flags)
+/*********************************************************************
+ * 03-Dec-1997: Changed by Bertho Stultiens
+ *
+ * See also comments with UITOOLS_DrawRectEdge()
+ */
+static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 uFlags)
{
- HPEN32 facePen, shadowPen, lightPen, blackPen, grayPen, nullPen;
- HPEN32 iPen, oPen, oldPen;
- HBRUSH32 oldBrush, faceBrush;
- int cl, cr, ct, cb;
- BOOL32 mainDiag;
- POINT32 tp;
- RECT32 r;
+ POINT32 Points[4];
+ char InnerI, OuterI;
+ HPEN32 InnerPen, OuterPen;
+ POINT32 SavePoint;
+ HPEN32 SavePen;
+ int spx, spy;
+ int epx, epy;
+ int Width = rc->right - rc->left;
+ int Height= rc->bottom - rc->top;
+ int SmallDiam = Width > Height ? Height : Width;
+ BOOL32 retval = !( ((uType & BDR_INNER) == BDR_INNER
+ || (uType & BDR_OUTER) == BDR_OUTER)
+ && !(uFlags & (BF_FLAT|BF_MONO)) );
+ int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
+ + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);
- /* If both rasied and sunken is specified, they anihilate one another */
- if( !((flags & BF_MONO) || (flags & BF_FLAT)) ){
- if( (edge & BDR_RAISEDOUTER) && (edge & BDR_SUNKENOUTER) )
- return FALSE;
- if( (edge & BDR_RAISEDINNER) && (edge & BDR_SUNKENINNER) )
- return FALSE;
- }
-
- /* Create/get the tools of the trade... */
- facePen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNFACE));
- shadowPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW));
- lightPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHILIGHT));
- grayPen = CreatePen32(PS_SOLID, 0, RGB(168, 152, 144));
- blackPen = GetStockObject32(BLACK_PEN);
- nullPen = GetStockObject32(NULL_PEN);
- faceBrush = GetSysColorBrush32(COLOR_BTNFACE);
- oldPen = SelectObject32(hdc, nullPen);
- oldBrush = SelectObject32(hdc, faceBrush);
-
- /* this is my working rectangle */
- r = *rect;
-
- if(flags & BF_MONO){
- oPen = blackPen;
- iPen = nullPen;
- }else if(flags & BF_FLAT){
- oPen = shadowPen;
- iPen = facePen;
- }else {
- if(flags & BF_SOFT){
- if(flags & BF_BOTTOM){
- oPen = (edge & BDR_RAISEDOUTER) ? blackPen : lightPen;
- iPen = (edge & BDR_RAISEDINNER) ? shadowPen : grayPen;
- }
- else{
- oPen = (edge & BDR_RAISEDOUTER) ? lightPen : blackPen;
- iPen = (edge & BDR_RAISEDINNER) ? grayPen : shadowPen;
- }
+ /* Init some vars */
+ OuterPen = InnerPen = (HPEN32)GetStockObject32(NULL_PEN);
+ SavePen = (HPEN32)SelectObject32(hdc, InnerPen);
+ spx = spy = epx = epy = 0; /* Satisfy the compiler... */
+
+ /* Determine the colors of the edges */
+ if(uFlags & BF_MONO)
+ {
+ InnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)];
}
- else{
- if(flags & BF_BOTTOM){
- oPen = (edge & BDR_RAISEDOUTER) ? blackPen : lightPen;
- iPen = (edge & BDR_RAISEDINNER) ? shadowPen : grayPen;
- }
- else{
- oPen = (edge & BDR_RAISEDOUTER) ? grayPen : shadowPen;
- iPen = (edge & BDR_RAISEDINNER) ? lightPen : blackPen;
- }
+ else if(uFlags & BF_FLAT)
+ {
+ InnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)];
}
- }
-
- if(flags & BF_BOTTOM){
- if(flags & BF_LEFT){
- cr = -1; cl = 0;
- ct = 0; cb = -1;
- mainDiag = TRUE;
- tp.x = r.left; tp.y = r.top;
+ else if(uFlags & BF_SOFT)
+ {
+ if(uFlags & BF_BOTTOM)
+ {
+ InnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else
+ {
+ InnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
+ }
}
- else{ /* RIGHT */
- cr = -1; cl = 0;
- ct = 1; cb = 0;
- tp.x = r.left; tp.y = r.bottom-1;
- mainDiag = FALSE;
+ else
+ {
+ if(uFlags & BF_BOTTOM)
+ {
+ InnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else
+ {
+ InnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
+ }
}
- }
- else{ /* TOP */
- if(flags & BF_LEFT){
- cr = 0; cl = 1;
- ct = 0; cb = -1;
- mainDiag = FALSE;
- tp.x = r.right; tp.y = r.top;
+
+ if(InnerI != -1) InnerPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)InnerI));
+ if(OuterI != -1) OuterPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)OuterI));
+
+ MoveToEx32(hdc, 0, 0, &SavePoint);
+
+ /* Don't ask me why, but this is what is visible... */
+ /* This must be possible to do much simpler, but I fail to */
+ /* see the logic in the MS implementation (sigh...). */
+ /* So, this might look a bit brute force here (and it is), but */
+ /* it gets the job done;) */
+
+ switch(uFlags & BF_RECT)
+ {
+ case 0:
+ case BF_LEFT:
+ case BF_BOTTOM:
+ case BF_BOTTOMLEFT:
+ /* Left bottom endpoint */
+ epx = rc->left-1;
+ spx = epx + SmallDiam;
+ epy = rc->bottom;
+ spy = epy - SmallDiam;
+ break;
+
+ case BF_TOPLEFT:
+ case BF_BOTTOMRIGHT:
+ /* Left top endpoint */
+ epx = rc->left-1;
+ spx = epx + SmallDiam;
+ epy = rc->top-1;
+ spy = epy + SmallDiam;
+ break;
+
+ case BF_TOP:
+ case BF_RIGHT:
+ case BF_TOPRIGHT:
+ case BF_RIGHT|BF_LEFT:
+ case BF_RIGHT|BF_LEFT|BF_TOP:
+ case BF_BOTTOM|BF_TOP:
+ case BF_BOTTOM|BF_TOP|BF_LEFT:
+ case BF_BOTTOMRIGHT|BF_LEFT:
+ case BF_BOTTOMRIGHT|BF_TOP:
+ case BF_RECT:
+ /* Right top endpoint */
+ spx = rc->left;
+ epx = spx + SmallDiam;
+ spy = rc->bottom-1;
+ epy = spy - SmallDiam;
+ break;
}
- else{ /* RIGHT */
- cr = 0; cl = 1;
- ct = 1; cb = 0;
- tp.x = r.right; tp.y = r.bottom-1;
- mainDiag = TRUE;
+
+ MoveToEx32(hdc, spx, spy, NULL);
+ SelectObject32(hdc, OuterPen);
+ LineTo32(hdc, epx, epy);
+
+ SelectObject32(hdc, InnerPen);
+
+ switch(uFlags & (BF_RECT|BF_DIAGONAL))
+ {
+ case BF_DIAGONAL_ENDBOTTOMLEFT:
+ case (BF_DIAGONAL|BF_BOTTOM):
+ case BF_DIAGONAL:
+ case (BF_DIAGONAL|BF_LEFT):
+ MoveToEx32(hdc, spx-1, spy, NULL);
+ LineTo32(hdc, epx, epy-1);
+ Points[0].x = spx-add;
+ Points[0].y = spy;
+ Points[1].x = rc->left;
+ Points[1].y = rc->top;
+ Points[2].x = epx+1;
+ Points[2].y = epy-1-add;
+ Points[3] = Points[2];
+ break;
+
+ case BF_DIAGONAL_ENDBOTTOMRIGHT:
+ MoveToEx32(hdc, spx-1, spy, NULL);
+ LineTo32(hdc, epx, epy+1);
+ Points[0].x = spx-add;
+ Points[0].y = spy;
+ Points[1].x = rc->left;
+ Points[1].y = rc->bottom-1;
+ Points[2].x = epx+1;
+ Points[2].y = epy+1+add;
+ Points[3] = Points[2];
+ break;
+
+ case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP):
+ case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP|BF_LEFT):
+ case BF_DIAGONAL_ENDTOPRIGHT:
+ case (BF_DIAGONAL|BF_RIGHT|BF_TOP|BF_LEFT):
+ MoveToEx32(hdc, spx+1, spy, NULL);
+ LineTo32(hdc, epx, epy+1);
+ Points[0].x = epx-1;
+ Points[0].y = epy+1+add;
+ Points[1].x = rc->right-1;
+ Points[1].y = rc->top+add;
+ Points[2].x = rc->right-1;
+ Points[2].y = rc->bottom-1;
+ Points[3].x = spx+add;
+ Points[3].y = spy;
+ break;
+
+ case BF_DIAGONAL_ENDTOPLEFT:
+ MoveToEx32(hdc, spx, spy-1, NULL);
+ LineTo32(hdc, epx+1, epy);
+ Points[0].x = epx+1+add;
+ Points[0].y = epy+1;
+ Points[1].x = rc->right-1;
+ Points[1].y = rc->top;
+ Points[2].x = rc->right-1;
+ Points[2].y = rc->bottom-1-add;
+ Points[3].x = spx;
+ Points[3].y = spy-add;
+ break;
+
+ case (BF_DIAGONAL|BF_TOP):
+ case (BF_DIAGONAL|BF_BOTTOM|BF_TOP):
+ case (BF_DIAGONAL|BF_BOTTOM|BF_TOP|BF_LEFT):
+ MoveToEx32(hdc, spx+1, spy-1, NULL);
+ LineTo32(hdc, epx, epy);
+ Points[0].x = epx-1;
+ Points[0].y = epy+1;
+ Points[1].x = rc->right-1;
+ Points[1].y = rc->top;
+ Points[2].x = rc->right-1;
+ Points[2].y = rc->bottom-1-add;
+ Points[3].x = spx+add;
+ Points[3].y = spy-add;
+ break;
+
+ case (BF_DIAGONAL|BF_RIGHT):
+ case (BF_DIAGONAL|BF_RIGHT|BF_LEFT):
+ case (BF_DIAGONAL|BF_RIGHT|BF_LEFT|BF_BOTTOM):
+ MoveToEx32(hdc, spx, spy, NULL);
+ LineTo32(hdc, epx-1, epy+1);
+ Points[0].x = spx;
+ Points[0].y = spy;
+ Points[1].x = rc->left;
+ Points[1].y = rc->top+add;
+ Points[2].x = epx-1-add;
+ Points[2].y = epy+1+add;
+ Points[3] = Points[2];
+ break;
}
- }
- /* if it has external edge, draw it */
- if(edge & BDR_OUTER){
- SelectObject32(hdc, oPen);
- MoveToEx32(hdc, r.left, mainDiag ? r.bottom-1 : r.top, 0);
- LineTo32(hdc, r.right, mainDiag ? r.top-1 : r.bottom);
- r.left += cl; r.right += cr; r.top += ct; r.bottom += cb;
- }
+ /* Fill the interior if asked */
+ if((uFlags & BF_MIDDLE) && retval)
+ {
+ HBRUSH32 hbsave;
+ HBRUSH32 hb = uFlags & BF_MONO ? GetSysColorBrush32(COLOR_WINDOW)
+ : GetSysColorBrush32(COLOR_BTNFACE);
+ HPEN32 hpsave;
+ HPEN32 hp = CreatePen32(PS_SOLID, 0, uFlags & BF_MONO ? GetSysColor32(COLOR_WINDOW)
+ : GetSysColor32(COLOR_BTNFACE));
+ hbsave = (HBRUSH32)SelectObject32(hdc, hb);
+ hpsave = (HPEN32)SelectObject32(hdc, hp);
+ Polygon32(hdc, Points, 4);
+ SelectObject32(hdc, hbsave);
+ SelectObject32(hdc, hpsave);
+ DeleteObject32(hp);
+ }
- /* if it has internal edge, draw it */
- if(edge & BDR_INNER){
- SelectObject32(hdc, iPen);
- MoveToEx32(hdc, r.left, mainDiag ? r.bottom-1 : r.top, 0);
- LineTo32(hdc, r.right, mainDiag ? r.top-1 : r.bottom);
- r.left += cl; r.right += cr; r.top += ct; r.bottom += cb;
- }
+ /* Adjust rectangle if asked */
+ if(uFlags & BF_ADJUST)
+ {
+ if(uFlags & BF_LEFT) rc->left += add;
+ if(uFlags & BF_RIGHT) rc->right -= add;
+ if(uFlags & BF_TOP) rc->top += add;
+ if(uFlags & BF_BOTTOM) rc->bottom -= add;
+ }
- if((flags & BF_MIDDLE) && !(flags & BF_MONO)){
- POINT32 p[3];
- p[0].x = mainDiag ? r.right: r.left;
- p[0].y = r.top;
- p[1].x = mainDiag ? r.left : r.right;
- p[1].y = r.bottom;
- p[2].x = tp.x;
- p[2].y = tp.y;
- SelectObject32(hdc, nullPen);
- SelectObject32(hdc, faceBrush);
- Polygon32(hdc, p, 3);
- }
+ /* Cleanup */
+ SelectObject32(hdc, SavePen);
+ if(InnerI != -1) DeleteObject32(InnerPen);
+ if(OuterI != -1) DeleteObject32(OuterPen);
+ MoveToEx32(hdc, SavePoint.x, SavePoint.y, NULL);
- if(flags & BF_ADJUST)
- *rect = r;
-
- /* Restore the DC */
- SelectObject32(hdc, oldPen);
- SelectObject32(hdc, oldBrush);
-
- /* Clean-up */
- DeleteObject32(facePen);
- DeleteObject32(shadowPen);
- DeleteObject32(lightPen);
- DeleteObject32(grayPen);
-
- return TRUE;
+ return retval;
}
-
/***********************************************************************
* UITOOLS_DrawRectEdge
*
@@ -167,115 +357,208 @@
* one generated by the native DrawEdge and it is identical on all cases that
* I tried, and I tried quite a few.
*/
-static BOOL32 UITOOLS_DrawRectEdge(HDC32 hdc, RECT32 *rect,
- UINT32 edge, UINT32 flags)
+/*********************************************************************
+ * 23-Nov-1997: Changed by Bertho Stultiens
+ *
+ * Well, I started testing this and found out that there are a few things
+ * that weren't quite as win95. The following rewrite should reproduce
+ * win95 results completely.
+ * The colorselection is table-driven to avoid awfull if-statements.
+ * The table below show the color settings.
+ *
+ * Pen selection table for uFlags = 0
+ *
+ * uType | LTI | LTO | RBI | RBO
+ * ------+-------+-------+-------+-------
+ * 0000 | x | x | x | x
+ * 0001 | x | 22 | x | 21
+ * 0010 | x | 16 | x | 20
+ * 0011 | x | x | x | x
+ * ------+-------+-------+-------+-------
+ * 0100 | x | 20 | x | 16
+ * 0101 | 20 | 22 | 16 | 21
+ * 0110 | 20 | 16 | 16 | 20
+ * 0111 | x | x | x | x
+ * ------+-------+-------+-------+-------
+ * 1000 | x | 21 | x | 22
+ * 1001 | 21 | 22 | 22 | 21
+ * 1010 | 21 | 16 | 22 | 20
+ * 1011 | x | x | x | x
+ * ------+-------+-------+-------+-------
+ * 1100 | x | x | x | x
+ * 1101 | x | x (22)| x | x (21)
+ * 1110 | x | x (16)| x | x (20)
+ * 1111 | x | x | x | x
+ *
+ * Pen selection table for uFlags = BF_SOFT
+ *
+ * uType | LTI | LTO | RBI | RBO
+ * ------+-------+-------+-------+-------
+ * 0000 | x | x | x | x
+ * 0001 | x | 20 | x | 21
+ * 0010 | x | 21 | x | 20
+ * 0011 | x | x | x | x
+ * ------+-------+-------+-------+-------
+ * 0100 | x | 22 | x | 16
+ * 0101 | 22 | 20 | 16 | 21
+ * 0110 | 22 | 21 | 16 | 20
+ * 0111 | x | x | x | x
+ * ------+-------+-------+-------+-------
+ * 1000 | x | 16 | x | 22
+ * 1001 | 16 | 20 | 22 | 21
+ * 1010 | 16 | 21 | 22 | 20
+ * 1011 | x | x | x | x
+ * ------+-------+-------+-------+-------
+ * 1100 | x | x | x | x
+ * 1101 | x | x (20)| x | x (21)
+ * 1110 | x | x (21)| x | x (20)
+ * 1111 | x | x | x | x
+ *
+ * x = don't care; (n) = is what win95 actually uses
+ * LTI = left Top Inner line
+ * LTO = left Top Outer line
+ * RBI = Right Bottom Inner line
+ * RBO = Right Bottom Outer line
+ * 15 = COLOR_BTNFACE
+ * 16 = COLOR_BTNSHADOW
+ * 20 = COLOR_BTNHIGHLIGHT
+ * 21 = COLOR_3DDKSHADOW
+ * 22 = COLOR_3DLIGHT
+ */
+
+
+static BOOL32 UITOOLS_DrawRectEdge(HDC32 hdc, LPRECT32 rc, UINT32 uType, UINT32 uFlags)
{
- HBRUSH32 faceBrush, shadowBrush, lightBrush, blackBrush, grayBrush, nullBrush;
- HBRUSH32 iNBrush, iSBrush, iEBrush, iWBrush;
- HBRUSH32 oNBrush, oSBrush, oEBrush, oWBrush;
- HBRUSH32 oldBrush;
- RECT32 r;
+ char LTInnerI, LTOuterI;
+ char RBInnerI, RBOuterI;
+ HPEN32 LTInnerPen, LTOuterPen;
+ HPEN32 RBInnerPen, RBOuterPen;
+ RECT32 InnerRect = *rc;
+ POINT32 SavePoint;
+ HPEN32 SavePen;
+ int LBpenplus = 0;
+ int LTpenplus = 0;
+ int RTpenplus = 0;
+ int RBpenplus = 0;
+ BOOL32 retval = !( ((uType & BDR_INNER) == BDR_INNER
+ || (uType & BDR_OUTER) == BDR_OUTER)
+ && !(uFlags & (BF_FLAT|BF_MONO)) );
+
+ /* Init some vars */
+ LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN32)GetStockObject32(NULL_PEN);
+ SavePen = (HPEN32)SelectObject32(hdc, LTInnerPen);
- /* If both rasied and sunken is specified, they anihilate one another */
- if( !((flags & BF_MONO) || (flags & BF_FLAT)) ){
- if( (edge & BDR_RAISEDOUTER) && (edge & BDR_SUNKENOUTER) )
- return FALSE;
- if( (edge & BDR_RAISEDINNER) && (edge & BDR_SUNKENINNER) )
- return FALSE;
- }
+ /* Determine the colors of the edges */
+ if(uFlags & BF_MONO)
+ {
+ LTInnerI = RBInnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)];
+ LTOuterI = RBOuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else if(uFlags & BF_FLAT)
+ {
+ LTInnerI = RBInnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)];
+ LTOuterI = RBOuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else if(uFlags & BF_SOFT)
+ {
+ LTInnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
+ LTOuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
+ RBInnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
+ RBOuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else
+ {
+ LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
+ LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
+ RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
+ RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
+ }
- faceBrush = GetSysColorBrush32(COLOR_BTNFACE);
- shadowBrush = GetSysColorBrush32(COLOR_BTNSHADOW);
- lightBrush = GetSysColorBrush32(COLOR_BTNHILIGHT);
- blackBrush = GetStockObject32(BLACK_BRUSH);
- grayBrush = GetStockObject32(LTGRAY_BRUSH);
- nullBrush = GetStockObject32(NULL_BRUSH);
- oldBrush = SelectObject32(hdc, nullBrush);
+ if((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT) LBpenplus = 1;
+ if((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT) RTpenplus = 1;
+ if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT) RBpenplus = 1;
+ if((uFlags & BF_TOPLEFT) == BF_TOPLEFT) LTpenplus = 1;
- /* this is my working rectangle */
- r = *rect;
+ if(LTInnerI != -1) LTInnerPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)LTInnerI));
+ if(LTOuterI != -1) LTOuterPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)LTOuterI));
+ if(RBInnerI != -1) RBInnerPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)RBInnerI));
+ if(RBOuterI != -1) RBOuterPen = CreatePen32(PS_SOLID, 0, GetSysColor32((int)RBOuterI));
- if(flags & BF_MONO){
- oNBrush = oSBrush = oEBrush = oWBrush = blackBrush;
- iNBrush = iSBrush = iEBrush = iWBrush = nullBrush;
- }else if(flags & BF_FLAT){
- oNBrush = oSBrush = oEBrush = oWBrush = shadowBrush;
- iNBrush = iSBrush = iEBrush = iWBrush = faceBrush;
- }else {
- if(flags & BF_SOFT){
- oNBrush = oWBrush = (edge & BDR_RAISEDOUTER) ? lightBrush : blackBrush;
- oSBrush = oEBrush = (edge & BDR_RAISEDOUTER) ? blackBrush : lightBrush;
- iNBrush = iWBrush = (edge & BDR_RAISEDINNER) ? grayBrush : shadowBrush;
- iSBrush = iEBrush = (edge & BDR_RAISEDINNER) ? shadowBrush : grayBrush;
+ if((uFlags & BF_MIDDLE) && retval)
+ {
+ FillRect32(hdc, &InnerRect, (uFlags & BF_MONO) ? GetSysColorBrush32(COLOR_WINDOW)
+ : GetSysColorBrush32(COLOR_BTNFACE));
}
- else{
- oNBrush = oWBrush = (edge & BDR_RAISEDOUTER) ? grayBrush : shadowBrush;
- oSBrush = oEBrush = (edge & BDR_RAISEDOUTER) ? blackBrush : lightBrush;
- iNBrush = iWBrush = (edge & BDR_RAISEDINNER) ? lightBrush : blackBrush;
- iSBrush = iEBrush = (edge & BDR_RAISEDINNER) ? shadowBrush : grayBrush;
- }
- }
- /* if it has external edge, draw it */
- if(edge & BDR_OUTER){
- if(flags & BF_RIGHT){
- SelectObject32(hdc, oEBrush);
- PatBlt32(hdc, r.right-1, r.top, 1, r.bottom - r.top, PATCOPY);
- r.right--;
- }
- if(flags & BF_BOTTOM){
- SelectObject32(hdc, oSBrush);
- PatBlt32(hdc, r.left, r.bottom-1, r.right-r.left, 1, PATCOPY);
- r.bottom--;
- }
- if(flags & BF_LEFT){
- SelectObject32(hdc, oWBrush);
- PatBlt32(hdc, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
- r.left++;
- }
- if(flags & BF_TOP){
- SelectObject32(hdc, oNBrush);
- PatBlt32(hdc, r.left, r.top, r.right-r.left, 1, PATCOPY);
- r.top++;
- }
- }
+ MoveToEx32(hdc, 0, 0, &SavePoint);
- /* if it has internal edge, draw it */
- if(edge & BDR_INNER){
- if(flags & BF_RIGHT){
- SelectObject32(hdc, iEBrush);
- PatBlt32(hdc, r.right-1, r.top, 1, r.bottom - r.top, PATCOPY);
- r.right--;
+ /* Draw the outer edge */
+ SelectObject32(hdc, LTOuterPen);
+ if(uFlags & BF_TOP)
+ {
+ MoveToEx32(hdc, InnerRect.left, InnerRect.top, NULL);
+ LineTo32(hdc, InnerRect.right, InnerRect.top);
}
- if(flags & BF_BOTTOM){
- SelectObject32(hdc, iSBrush);
- PatBlt32(hdc, r.left, r.bottom-1, r.right-r.left, 1, PATCOPY);
- r.bottom--;
+ if(uFlags & BF_LEFT)
+ {
+ MoveToEx32(hdc, InnerRect.left, InnerRect.top, NULL);
+ LineTo32(hdc, InnerRect.left, InnerRect.bottom);
}
- if(flags & BF_LEFT){
- SelectObject32(hdc, iWBrush);
- PatBlt32(hdc, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
- r.left++;
+ SelectObject32(hdc, RBOuterPen);
+ if(uFlags & BF_BOTTOM)
+ {
+ MoveToEx32(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL);
+ LineTo32(hdc, InnerRect.left-1, InnerRect.bottom-1);
}
- if(flags & BF_TOP){
- SelectObject32(hdc, iNBrush);
- PatBlt32(hdc, r.left, r.top, r.right-r.left, 1, PATCOPY);
- r.top++;
+ if(uFlags & BF_RIGHT)
+ {
+ MoveToEx32(hdc, InnerRect.right-1, InnerRect.bottom-1, NULL);
+ LineTo32(hdc, InnerRect.right-1, InnerRect.top-1);
}
- }
- /* if we got to fill the middle, to it now */
- if((flags & BF_MIDDLE) && !(flags & BF_MONO))
- FillRect32(hdc, &r, faceBrush);
+ /* Draw the inner edge */
+ SelectObject32(hdc, LTInnerPen);
+ if(uFlags & BF_TOP)
+ {
+ MoveToEx32(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL);
+ LineTo32(hdc, InnerRect.right-RTpenplus, InnerRect.top+1);
+ }
+ if(uFlags & BF_LEFT)
+ {
+ MoveToEx32(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL);
+ LineTo32(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus);
+ }
+ SelectObject32(hdc, RBInnerPen);
+ if(uFlags & BF_BOTTOM)
+ {
+ MoveToEx32(hdc, InnerRect.right-1-RBpenplus, InnerRect.bottom-2, NULL);
+ LineTo32(hdc, InnerRect.left-1+LBpenplus, InnerRect.bottom-2);
+ }
+ if(uFlags & BF_RIGHT)
+ {
+ MoveToEx32(hdc, InnerRect.right-2, InnerRect.bottom-1-RBpenplus, NULL);
+ LineTo32(hdc, InnerRect.right-2, InnerRect.top-1+RTpenplus);
+ }
- /* adjust the rectangle if required */
- if(flags & BF_ADJUST)
- *rect = r;
+ /* Adjust rectangle if asked */
+ if(uFlags & BF_ADJUST)
+ {
+ int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
+ + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);
+ if(uFlags & BF_LEFT) rc->left += add;
+ if(uFlags & BF_RIGHT) rc->right -= add;
+ if(uFlags & BF_TOP) rc->top += add;
+ if(uFlags & BF_BOTTOM) rc->bottom -= add;
+ }
- /* Restore the DC */
- SelectObject32(hdc, oldBrush);
-
- return TRUE;
+ /* Cleanup */
+ SelectObject32(hdc, SavePen);
+ if(LTInnerI != -1) DeleteObject32(LTInnerPen);
+ if(LTOuterI != -1) DeleteObject32(LTOuterPen);
+ if(RBInnerI != -1) DeleteObject32(RBInnerPen);
+ if(RBOuterI != -1) DeleteObject32(RBOuterPen);
+ MoveToEx32(hdc, SavePoint.x, SavePoint.y, NULL);
+ return retval;
}
@@ -309,44 +592,823 @@
}
+/************************************************************************
+ * UITOOLS_MakeSquareRect
+ *
+ * Utility to create a square rectangle and returning the width
+ */
+static int UITOOLS_MakeSquareRect(LPRECT32 src, LPRECT32 dst)
+{
+ int Width = src->right - src->left;
+ int Height = src->bottom - src->top;
+ int SmallDiam = Width > Height ? Height : Width;
+
+ *dst = *src;
+
+ /* Make it a square box */
+ if(Width < Height) /* SmallDiam == Width */
+ {
+ dst->top += (Height-Width)/2;
+ dst->bottom = dst->top + SmallDiam;
+ }
+ else if(Width > Height) /* SmallDiam == Height */
+ {
+ dst->left += (Width-Height)/2;
+ dst->right = dst->left + SmallDiam;
+ }
+
+ return SmallDiam;
+}
+
+
+/************************************************************************
+ * UITOOLS_DFC_ButtonPush
+ *
+ * Draw a push button coming from DrawFrameControl()
+ *
+ * Does a pretty good job in emulating MS behavior. Some quirks are
+ * however there because MS uses a TrueType font (Marlett) to draw
+ * the buttons.
+ */
+static BOOL32 UITOOLS_DFC_ButtonPush(HDC32 dc, LPRECT32 r, UINT32 uFlags)
+{
+ UINT32 edge;
+ RECT32 myr = *r;
+
+ if(uFlags & (DFCS_PUSHED | DFCS_CHECKED | DFCS_FLAT))
+ edge = EDGE_SUNKEN;
+ else
+ edge = EDGE_RAISED;
+
+ if(uFlags & DFCS_CHECKED)
+ {
+ if(uFlags & DFCS_MONO)
+ UITOOLS_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST);
+ else
+ UITOOLS_DrawRectEdge(dc, &myr, edge, (uFlags&DFCS_FLAT)|BF_RECT|BF_SOFT|BF_ADJUST);
+
+ if(GetSysColor32(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255))
+ {
+ HBITMAP32 hbm = CreateBitmap32(8, 8, 1, 1, wPattern_AA55);
+ HBRUSH32 hbsave;
+ HBRUSH32 hb = CreatePatternBrush32(hbm);
+
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNFACE));
+ hbsave = (HBRUSH32)SelectObject32(dc, hb);
+ PatBlt32(dc, myr.left, myr.top, myr.right-myr.left, myr.bottom-myr.top, 0x00FA0089);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hb);
+ DeleteObject32(hbm);
+ }
+ else
+ {
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNHIGHLIGHT));
+ }
+ }
+ else
+ {
+ if(uFlags & DFCS_MONO)
+ {
+ UITOOLS_DrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST);
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNFACE));
+ }
+ else
+ {
+ UITOOLS_DrawRectEdge(dc, r, edge, (uFlags&DFCS_FLAT) | BF_MIDDLE |BF_SOFT| BF_RECT);
+ }
+ }
+
+ /* Adjust rectangle if asked */
+ if(uFlags & DFCS_ADJUSTRECT)
+ {
+ r->left += 2;
+ r->right -= 2;
+ r->top += 2;
+ r->bottom -= 2;
+ }
+
+ return TRUE;
+}
+
+
+/************************************************************************
+ * UITOOLS_DFC_ButtonChcek
+ *
+ * Draw a check/3state button coming from DrawFrameControl()
+ *
+ * Does a pretty good job in emulating MS behavior. Some quirks are
+ * however there because MS uses a TrueType font (Marlett) to draw
+ * the buttons.
+ */
+#define DFC_CHECKPOINTSMAX 6
+
+static BOOL32 UITOOLS_DFC_ButtonCheck(HDC32 dc, LPRECT32 r, UINT32 uFlags)
+{
+ RECT32 myr;
+ int SmallDiam = UITOOLS_MakeSquareRect(r, &myr);
+ int BorderShrink = SmallDiam / 16;
+
+ if(BorderShrink < 1) BorderShrink = 1;
+
+ /* FIXME: The FillRect() sequence doesn't work for sizes less than */
+ /* 4 pixels in diameter. Not really a problem but it isn't M$'s */
+ /* 100% equivalent. */
+ if(uFlags & (DFCS_FLAT|DFCS_MONO))
+ {
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_WINDOWFRAME));
+ myr.left += 2 * BorderShrink;
+ myr.right -= 2 * BorderShrink;
+ myr.top += 2 * BorderShrink;
+ myr.bottom -= 2 * BorderShrink;
+ }
+ else
+ {
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNHIGHLIGHT));
+ myr.right -= BorderShrink;
+ myr.bottom -= BorderShrink;
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNSHADOW));
+ myr.left += BorderShrink;
+ myr.top += BorderShrink;
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_3DLIGHT));
+ myr.right -= BorderShrink;
+ myr.bottom -= BorderShrink;
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_3DDKSHADOW));
+ myr.left += BorderShrink;
+ myr.top += BorderShrink;
+ }
+
+ if(uFlags & (DFCS_INACTIVE|DFCS_PUSHED))
+ {
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNFACE));
+ }
+ else if(uFlags & DFCS_CHECKED)
+ {
+ if(GetSysColor32(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255))
+ {
+ HBITMAP32 hbm = CreateBitmap32(8, 8, 1, 1, wPattern_AA55);
+ HBRUSH32 hbsave;
+ HBRUSH32 hb = CreatePatternBrush32(hbm);
+
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNFACE));
+ hbsave = (HBRUSH32)SelectObject32(dc, hb);
+ PatBlt32(dc, myr.left, myr.top, myr.right-myr.left, myr.bottom-myr.top, 0x00FA0089);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hb);
+ DeleteObject32(hbm);
+ }
+ else
+ {
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_BTNHIGHLIGHT));
+ }
+ }
+ else
+ {
+ FillRect32(dc, &myr, GetSysColorBrush32(COLOR_WINDOW));
+ }
+
+ if(uFlags & DFCS_CHECKED)
+ {
+ POINT32 CheckPoints[DFC_CHECKPOINTSMAX];
+ int i;
+ HBRUSH32 hbsave;
+ HPEN32 hp, hpsave;
+
+ /* FIXME: This comes very close to M$'s checkmark, but not */
+ /* exactly... When small or large there is a few pixels */
+ /* shift. Not bad, but could be better :) */
+ UITOOLS_MakeSquareRect(r, &myr);
+ CheckPoints[0].x = myr.left + 253*SmallDiam/1000;
+ CheckPoints[0].y = myr.top + 345*SmallDiam/1000;
+ CheckPoints[1].x = myr.left + 409*SmallDiam/1000;
+ CheckPoints[1].y = CheckPoints[0].y + (CheckPoints[1].x-CheckPoints[0].x);
+ CheckPoints[2].x = myr.left + 690*SmallDiam/1000;
+ CheckPoints[2].y = CheckPoints[1].y - (CheckPoints[2].x-CheckPoints[1].x);
+ CheckPoints[3].x = CheckPoints[2].x;
+ CheckPoints[3].y = CheckPoints[2].y + 3*SmallDiam/16;
+ CheckPoints[4].x = CheckPoints[1].x;
+ CheckPoints[4].y = CheckPoints[1].y + 3*SmallDiam/16;
+ CheckPoints[5].x = CheckPoints[0].x;
+ CheckPoints[5].y = CheckPoints[0].y + 3*SmallDiam/16;
+
+ i = (uFlags & DFCS_INACTIVE) || (uFlags & 0xff) == DFCS_BUTTON3STATE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT;
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(i));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ Polygon32(dc, CheckPoints, DFC_CHECKPOINTSMAX);
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hp);
+ }
+ return TRUE;
+}
+
+
+/************************************************************************
+ * UITOOLS_DFC_ButtonRadio
+ *
+ * Draw a radio/radioimage/radiomask button coming from DrawFrameControl()
+ *
+ * Does a pretty good job in emulating MS behavior. Some quirks are
+ * however there because MS uses a TrueType font (Marlett) to draw
+ * the buttons.
+ */
+static BOOL32 UITOOLS_DFC_ButtonRadio(HDC32 dc, LPRECT32 r, UINT32 uFlags)
+{
+ RECT32 myr;
+ int i;
+ int SmallDiam = UITOOLS_MakeSquareRect(r, &myr);
+ int BorderShrink = SmallDiam / 16;
+ HPEN32 hpsave, hp;
+ HBRUSH32 hbsave;
+ int xe, ye;
+ int xc, yc;
+
+ if(BorderShrink < 1) BorderShrink = 1;
+
+ if((uFlags & 0xff) == DFCS_BUTTONRADIOIMAGE)
+ {
+ FillRect32(dc, r, (HBRUSH32)GetStockObject32(BLACK_BRUSH));
+ }
+
+ xe = myr.left;
+ ye = myr.top + SmallDiam - SmallDiam/2;
+
+ xc = myr.left + SmallDiam - SmallDiam/2;
+ yc = myr.top + SmallDiam - SmallDiam/2;
+
+ /* Define bounding box */
+ i = 14*SmallDiam/16;
+ myr.left = xc - i+i/2;
+ myr.right = xc + i/2;
+ myr.top = yc - i+i/2;
+ myr.bottom = yc + i/2;
+
+ if((uFlags & 0xff) == DFCS_BUTTONRADIOMASK)
+ {
+ hbsave = (HBRUSH32)SelectObject32(dc, GetStockObject32(BLACK_BRUSH));
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
+ SelectObject32(dc, hbsave);
+ }
+ else
+ {
+ if(uFlags & (DFCS_FLAT|DFCS_MONO))
+ {
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_WINDOWFRAME));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_WINDOWFRAME));
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
+ SelectObject32(dc, hbsave);
+ SelectObject32(dc, hpsave);
+ DeleteObject32(hp);
+ }
+ else
+ {
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNHIGHLIGHT));
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top);
+ SelectObject32(dc, hbsave);
+ SelectObject32(dc, hpsave);
+ DeleteObject32(hp);
+
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNSHADOW));
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom);
+ SelectObject32(dc, hbsave);
+ SelectObject32(dc, hpsave);
+ DeleteObject32(hp);
+
+ myr.left += BorderShrink;
+ myr.right -= BorderShrink;
+ myr.top += BorderShrink;
+ myr.bottom -= BorderShrink;
+
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_3DLIGHT));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_3DLIGHT));
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.left-1, myr.bottom, myr.right-1, myr.top);
+ SelectObject32(dc, hbsave);
+ SelectObject32(dc, hpsave);
+ DeleteObject32(hp);
+
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_3DDKSHADOW));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_3DDKSHADOW));
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, myr.right+1, myr.top, myr.left+1, myr.bottom);
+ SelectObject32(dc, hbsave);
+ SelectObject32(dc, hpsave);
+ DeleteObject32(hp);
+ }
+
+ i = 10*SmallDiam/16;
+ myr.left = xc - i+i/2;
+ myr.right = xc + i/2;
+ myr.top = yc - i+i/2;
+ myr.bottom = yc + i/2;
+ i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE;
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(i));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i));
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
+ SelectObject32(dc, hbsave);
+ SelectObject32(dc, hpsave);
+ DeleteObject32(hp);
+ }
+
+ if(uFlags & DFCS_CHECKED)
+ {
+ i = 6*SmallDiam/16;
+ i = i < 1 ? 1 : i;
+ myr.left = xc - i+i/2;
+ myr.right = xc + i/2;
+ myr.top = yc - i+i/2;
+ myr.bottom = yc + i/2;
+
+ i = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_WINDOWTEXT;
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(i));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(i));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hp);
+ }
+
+ /* FIXME: M$ has a polygon in the center at relative points: */
+ /* 0.476, 0.476 (times SmallDiam, SmallDiam) */
+ /* 0.476, 0.525 */
+ /* 0.500, 0.500 */
+ /* 0.500, 0.499 */
+ /* when the button is unchecked. The reason for it is unknown. The */
+ /* color is COLOR_BTNHIGHLIGHT, although the polygon gets painted at */
+ /* least 3 times (it looks like a clip-region when you see it happen). */
+ /* I do not really see a reason why this should be implemented. If you */
+ /* have a good reason, let me know. Maybe this is a quirk in the Marlett */
+ /* font. */
+
+ return TRUE;
+}
+
/***********************************************************************
* UITOOLS_DrawFrameButton
*/
static BOOL32 UITOOLS_DrawFrameButton(HDC32 hdc, LPRECT32 rc, UINT32 uState)
{
- fprintf( stdnimp,"DrawFrameButton(%x,%p,%x), empty stub!\n",
- hdc,rc,uState );
+ switch(uState & 0xff)
+ {
+ case DFCS_BUTTONPUSH:
+ return UITOOLS_DFC_ButtonPush(hdc, rc, uState);
+
+ case DFCS_BUTTONCHECK:
+ case DFCS_BUTTON3STATE:
+ return UITOOLS_DFC_ButtonCheck(hdc, rc, uState);
+
+ case DFCS_BUTTONRADIOIMAGE:
+ case DFCS_BUTTONRADIOMASK:
+ case DFCS_BUTTONRADIO:
+ return UITOOLS_DFC_ButtonRadio(hdc, rc, uState);
+
+ default:
+ fprintf(stdnimp, "UITOOLS_DrawFrameButton: Report this: Invalid button state: 0x%04x\n", uState);
+ }
+
return FALSE;
}
/***********************************************************************
* UITOOLS_DrawFrameCaption
+ *
+ * Draw caption buttons (win95), coming from DrawFrameControl()
*/
-static BOOL32 UITOOLS_DrawFrameCaption(HDC32 hdc, LPRECT32 rc, UINT32 uState)
+
+static BOOL32 UITOOLS_DrawFrameCaption(HDC32 dc, LPRECT32 r, UINT32 uFlags)
{
- fprintf( stdnimp,"DrawFrameCaption(%x,%p,%x), empty stub!\n",
- hdc,rc,uState );
- return FALSE;
+ POINT32 Line1[10];
+ POINT32 Line2[10];
+ int Line1N;
+ int Line2N;
+ RECT32 myr;
+ int SmallDiam = UITOOLS_MakeSquareRect(r, &myr)-2;
+ int i;
+ HBRUSH32 hbsave;
+ HPEN32 hpsave, hp;
+ HFONT32 hfsave, hf;
+ int xc = (myr.left+myr.right)/2;
+ int yc = (myr.top+myr.bottom)/2;
+ int edge, move;
+ char str[2] = "?";
+ UINT32 alignsave;
+ int bksave;
+ COLORREF clrsave;
+ SIZE32 size;
+
+ UITOOLS_DFC_ButtonPush(dc, r, uFlags & 0xff00);
+
+ switch(uFlags & 0xff)
+ {
+ case DFCS_CAPTIONCLOSE:
+ edge = 328*SmallDiam/1000;
+ move = 95*SmallDiam/1000;
+ Line1[0].x = Line2[0].x = Line1[1].x = Line2[1].x = xc - edge;
+ Line1[2].y = Line2[5].y = Line1[1].y = Line2[4].y = yc - edge;
+ Line1[3].x = Line2[3].x = Line1[4].x = Line2[4].x = xc + edge;
+ Line1[5].y = Line2[2].y = Line1[4].y = Line2[1].y = yc + edge;
+ Line1[2].x = Line2[2].x = Line1[1].x + move;
+ Line1[0].y = Line2[3].y = Line1[1].y + move;
+ Line1[5].x = Line2[5].x = Line1[4].x - move;
+ Line1[3].y = Line2[0].y = Line1[4].y - move;
+ Line1N = 6;
+ Line2N = 6;
+ break;
+
+ case DFCS_CAPTIONHELP:
+ /* This one breaks the flow */
+ /* FIXME: We need the Marlett font in order to get this right. */
+
+ hf = CreateFont32A(-SmallDiam, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
+ ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
+ DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "System");
+ alignsave = SetTextAlign32(dc, TA_TOP|TA_LEFT);
+ bksave = SetBkMode32(dc, TRANSPARENT);
+ clrsave = GetTextColor32(dc);
+ hfsave = (HFONT32)SelectObject32(dc, hf);
+ GetTextExtentPoint32A(dc, str, 1, &size);
+
+ if(uFlags & DFCS_INACTIVE)
+ {
+ SetTextColor32(dc, GetSysColor32(COLOR_BTNHIGHLIGHT));
+ TextOut32A(dc, xc-size.cx/2+1, yc-size.cy/2+1, str, 1);
+ }
+ SetTextColor32(dc, GetSysColor32(uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT));
+ TextOut32A(dc, xc-size.cx/2, yc-size.cy/2, str, 1);
+
+ SelectObject32(dc, hfsave);
+ SetTextColor32(dc, clrsave);
+ SetBkMode32(dc, bksave);
+ SetTextAlign32(dc, alignsave);
+ DeleteObject32(hf);
+ return TRUE;
+
+ case DFCS_CAPTIONMIN:
+ Line1[0].x = Line1[3].x = myr.left + 96*SmallDiam/750+2;
+ Line1[1].x = Line1[2].x = Line1[0].x + 372*SmallDiam/750;
+ Line1[0].y = Line1[1].y = myr.top + 563*SmallDiam/750+1;
+ Line1[2].y = Line1[3].y = Line1[0].y + 92*SmallDiam/750;
+ Line1N = 4;
+ Line2N = 0;
+ break;
+
+ case DFCS_CAPTIONMAX:
+ edge = 47*SmallDiam/750;
+ Line1[0].x = Line1[5].x = myr.left + 57*SmallDiam/750+3;
+ Line1[0].y = Line1[1].y = myr.top + 143*SmallDiam/750+1;
+ Line1[1].x = Line1[2].x = Line1[0].x + 562*SmallDiam/750;
+ Line1[5].y = Line1[4].y = Line1[0].y + 93*SmallDiam/750;
+ Line1[2].y = Line1[3].y = Line1[0].y + 513*SmallDiam/750;
+ Line1[3].x = Line1[4].x = Line1[1].x - edge;
+
+ Line2[0].x = Line2[5].x = Line1[0].x;
+ Line2[3].x = Line2[4].x = Line1[1].x;
+ Line2[1].x = Line2[2].x = Line1[0].x + edge;
+ Line2[0].y = Line2[1].y = Line1[0].y;
+ Line2[4].y = Line2[5].y = Line1[2].y;
+ Line2[2].y = Line2[3].y = Line1[2].y - edge;
+ Line1N = 6;
+ Line2N = 6;
+ break;
+
+ case DFCS_CAPTIONRESTORE:
+ /* FIXME: this one looks bad at small sizes < 15x15 :( */
+ edge = 47*SmallDiam/750;
+ move = 420*SmallDiam/750;
+ Line1[0].x = Line1[9].x = myr.left + 198*SmallDiam/750+2;
+ Line1[0].y = Line1[1].y = myr.top + 169*SmallDiam/750+1;
+ Line1[6].y = Line1[7].y = Line1[0].y + 93*SmallDiam/750;
+ Line1[7].x = Line1[8].x = Line1[0].x + edge;
+ Line1[1].x = Line1[2].x = Line1[0].x + move;
+ Line1[5].x = Line1[6].x = Line1[1].x - edge;
+ Line1[9].y = Line1[8].y = Line1[0].y + 187*SmallDiam/750;
+ Line1[2].y = Line1[3].y = Line1[0].y + 327*SmallDiam/750;
+ Line1[4].y = Line1[5].y = Line1[2].y - edge;
+ Line1[3].x = Line1[4].x = Line1[2].x - 140*SmallDiam/750;
+
+ Line2[1].x = Line2[2].x = Line1[3].x;
+ Line2[7].x = Line2[8].x = Line2[1].x - edge;
+ Line2[0].x = Line2[9].x = Line2[3].x = Line2[4].x = Line2[1].x - move;
+ Line2[5].x = Line2[6].x = Line2[0].x + edge;
+ Line2[0].y = Line2[1].y = Line1[9].y;
+ Line2[4].y = Line2[5].y = Line2[8].y = Line2[9].y = Line2[0].y + 93*SmallDiam/750;
+ Line2[2].y = Line2[3].y = Line2[0].y + 327*SmallDiam/750;
+ Line2[6].y = Line2[7].y = Line2[2].y - edge;
+ Line1N = 10;
+ Line2N = 10;
+ break;
+
+ default:
+ fprintf(stdnimp, "UITOOLS_DrawFrameCaption: Report this: Invalid caption; flags: 0x%04x\n", uFlags);
+ return FALSE;
+ }
+
+ /* Here the drawing takes place */
+ if(uFlags & DFCS_INACTIVE)
+ {
+ /* If we have an inactive button, then you see a shadow */
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNHIGHLIGHT));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ Polygon32(dc, Line1, Line1N);
+ if(Line2N > 0)
+ Polygon32(dc, Line2, Line2N);
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hp);
+ }
+
+ /* Correct for the shadow shift */
+ for(i = 0; i < Line1N; i++)
+ {
+ Line1[i].x--;
+ Line1[i].y--;
+ }
+ for(i = 0; i < Line2N; i++)
+ {
+ Line2[i].x--;
+ Line2[i].y--;
+ }
+
+ /* Make the final picture */
+ if(uFlags & DFCS_INACTIVE)
+ {
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNSHADOW));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW));
+ }
+ else
+ {
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNTEXT));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNTEXT));
+ }
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ Polygon32(dc, Line1, Line1N);
+ if(Line2N > 0)
+ Polygon32(dc, Line2, Line2N);
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hp);
+
+ return TRUE;
}
-/***********************************************************************
- * UITOOLS_DrawFrameMenu
+
+/************************************************************************
+ * UITOOLS_DrawFrameScroll
+ *
+ * Draw a scroll-bar control coming from DrawFrameControl()
*/
-static BOOL32 UITOOLS_DrawFrameMenu(HDC32 hdc, LPRECT32 rc, UINT32 uState)
+static BOOL32 UITOOLS_DrawFrameScroll(HDC32 dc, LPRECT32 r, UINT32 uFlags)
{
- fprintf( stdnimp,"DrawFrameMenu32(%x,%p,%x), empty stub!\n",
- hdc,rc,uState );
- return FALSE;
+ POINT32 Line[4];
+ RECT32 myr;
+ int SmallDiam = UITOOLS_MakeSquareRect(r, &myr) - 2;
+ int i;
+ HBRUSH32 hbsave, hb, hb2;
+ HPEN32 hpsave, hp, hp2;
+ int tri = 310*SmallDiam/1000;
+ int d46, d93;
+
+ switch(uFlags & 0xff)
+ {
+ case DFCS_SCROLLCOMBOBOX:
+ case DFCS_SCROLLDOWN:
+ Line[2].x = myr.left + 470*SmallDiam/1000 + 2;
+ Line[2].y = myr.top + 687*SmallDiam/1000 + 1;
+ Line[0].x = Line[2].x - tri;
+ Line[1].x = Line[2].x + tri;
+ Line[0].y = Line[1].y = Line[2].y - tri;
+ break;
+
+ case DFCS_SCROLLUP:
+ Line[2].x = myr.left + 470*SmallDiam/1000 + 2;
+ Line[2].y = myr.top + 313*SmallDiam/1000 + 1;
+ Line[0].x = Line[2].x - tri;
+ Line[1].x = Line[2].x + tri;
+ Line[0].y = Line[1].y = Line[2].y + tri;
+ break;
+
+ case DFCS_SCROLLLEFT:
+ Line[2].x = myr.left + 313*SmallDiam/1000 + 1;
+ Line[2].y = myr.top + 470*SmallDiam/1000 + 2;
+ Line[0].y = Line[2].y - tri;
+ Line[1].y = Line[2].y + tri;
+ Line[0].x = Line[1].x = Line[2].x + tri;
+ break;
+
+ case DFCS_SCROLLRIGHT:
+ Line[2].x = myr.left + 687*SmallDiam/1000 + 1;
+ Line[2].y = myr.top + 470*SmallDiam/1000 + 2;
+ Line[0].y = Line[2].y - tri;
+ Line[1].y = Line[2].y + tri;
+ Line[0].x = Line[1].x = Line[2].x - tri;
+ break;
+
+ case DFCS_SCROLLSIZEGRIP:
+ /* This one breaks the flow... */
+ UITOOLS_DrawRectEdge(dc, r, EDGE_BUMP, BF_MIDDLE | ((uFlags&(DFCS_MONO|DFCS_FLAT)) ? BF_MONO : 0));
+ hpsave = (HPEN32)SelectObject32(dc, GetStockObject32(NULL_PEN));
+ hbsave = (HBRUSH32)SelectObject32(dc, GetStockObject32(NULL_BRUSH));
+ if(uFlags & (DFCS_MONO|DFCS_FLAT))
+ {
+ hp = hp2 = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_WINDOWFRAME));
+ hb = hb2 = GetSysColorBrush32(COLOR_WINDOWFRAME);
+ }
+ else
+ {
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT));
+ hp2 = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW));
+ hb = GetSysColorBrush32(COLOR_BTNHIGHLIGHT);
+ hb2 = GetSysColorBrush32(COLOR_BTNSHADOW);
+ }
+ Line[0].x = Line[1].x = r->right-1;
+ Line[2].y = Line[3].y = r->bottom-1;
+ d46 = 46*SmallDiam/750;
+ d93 = 93*SmallDiam/750;
+
+ i = 586*SmallDiam/750;
+ Line[0].y = r->bottom - i - 1;
+ Line[3].x = r->right - i - 1;
+ Line[1].y = Line[0].y + d46;
+ Line[2].x = Line[3].x + d46;
+ SelectObject32(dc, hb);
+ SelectObject32(dc, hp);
+ Polygon32(dc, Line, 4);
+
+ Line[1].y++; Line[2].x++;
+ Line[0].y = Line[1].y + d93;
+ Line[3].x = Line[2].x + d93;
+ SelectObject32(dc, hb2);
+ SelectObject32(dc, hp2);
+ Polygon32(dc, Line, 4);
+
+ i = 398*SmallDiam/750;
+ Line[0].y = r->bottom - i - 1;
+ Line[3].x = r->right - i - 1;
+ Line[1].y = Line[0].y + d46;
+ Line[2].x = Line[3].x + d46;
+ SelectObject32(dc, hb);
+ SelectObject32(dc, hp);
+ Polygon32(dc, Line, 4);
+
+ Line[1].y++; Line[2].x++;
+ Line[0].y = Line[1].y + d93;
+ Line[3].x = Line[2].x + d93;
+ SelectObject32(dc, hb2);
+ SelectObject32(dc, hp2);
+ Polygon32(dc, Line, 4);
+
+ i = 210*SmallDiam/750;
+ Line[0].y = r->bottom - i - 1;
+ Line[3].x = r->right - i - 1;
+ Line[1].y = Line[0].y + d46;
+ Line[2].x = Line[3].x + d46;
+ SelectObject32(dc, hb);
+ SelectObject32(dc, hp);
+ Polygon32(dc, Line, 4);
+
+ Line[1].y++; Line[2].x++;
+ Line[0].y = Line[1].y + d93;
+ Line[3].x = Line[2].x + d93;
+ SelectObject32(dc, hb2);
+ SelectObject32(dc, hp2);
+ Polygon32(dc, Line, 4);
+
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hp);
+ DeleteObject32(hp2);
+ return TRUE;
+
+ default:
+ fprintf(stdnimp, "UITOOLS_DrawFrameScroll: Report this: Invalid scroll; flags: 0x%04x\n", uFlags);
+ return FALSE;
+ }
+
+ /* Here do the real scroll-bar controls end up */
+ UITOOLS_DFC_ButtonPush(dc, r, uFlags & 0xff00);
+
+ if(uFlags & DFCS_INACTIVE)
+ {
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNHIGHLIGHT));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHIGHLIGHT));
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ Polygon32(dc, Line, 3);
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hp);
+ }
+
+ for(i = 0; i < 3; i++)
+ {
+ Line[i].x--;
+ Line[i].y--;
+ }
+
+ if(uFlags & DFCS_INACTIVE)
+ {
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNSHADOW));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW));
+ }
+ else
+ {
+ hbsave = (HBRUSH32)SelectObject32(dc, GetSysColorBrush32(COLOR_BTNTEXT));
+ hp = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNTEXT));
+ }
+ hpsave = (HPEN32)SelectObject32(dc, hp);
+ Polygon32(dc, Line, 3);
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ DeleteObject32(hp);
+
+ return TRUE;
}
-/***********************************************************************
- * UITOOLS_DrawFrameScroll
+/************************************************************************
+ * UITOOLS_DrawFrameMenu
+ *
+ * Draw a menu control coming from DrawFrameControl()
*/
-static BOOL32 UITOOLS_DrawFrameScroll(HDC32 hdc, LPRECT32 rc, UINT32 uState)
+static BOOL32 UITOOLS_DrawFrameMenu(HDC32 dc, LPRECT32 r, UINT32 uFlags)
{
- fprintf( stdnimp,"DrawFrameScroll32(%x,%p,%x), empty stub!\n",
- hdc,rc,uState );
- return FALSE;
+ POINT32 Points[6];
+ RECT32 myr;
+ int SmallDiam = UITOOLS_MakeSquareRect(r, &myr);
+ int i;
+ HBRUSH32 hbsave;
+ HPEN32 hpsave;
+ int xe, ye;
+ int xc, yc;
+ BOOL32 retval = TRUE;
+
+ /* Using black and white seems to be utterly wrong, but win95 doesn't */
+ /* use anything else. I think I tried all sys-colors to change things */
+ /* without luck. It seems as if this behavior is inherited from the */
+ /* win31 DFC() implementation... (you remember, B/W menus). */
+
+ FillRect32(dc, r, (HBRUSH32)GetStockObject32(WHITE_BRUSH));
+
+ hbsave = (HBRUSH32)SelectObject32(dc, GetStockObject32(BLACK_BRUSH));
+ hpsave = (HPEN32)SelectObject32(dc, GetStockObject32(BLACK_PEN));
+
+ switch(uFlags & 0xff)
+ {
+ case DFCS_MENUARROW:
+ i = 187*SmallDiam/750;
+ Points[2].x = myr.left + 468*SmallDiam/750;
+ Points[2].y = myr.top + 352*SmallDiam/750+1;
+ Points[0].y = Points[2].y - i;
+ Points[1].y = Points[2].y + i;
+ Points[0].x = Points[1].x = Points[2].x - i;
+ Polygon32(dc, Points, 3);
+ break;
+
+ case DFCS_MENUBULLET:
+ xe = myr.left;
+ ye = myr.top + SmallDiam - SmallDiam/2;
+ xc = myr.left + SmallDiam - SmallDiam/2;
+ yc = myr.top + SmallDiam - SmallDiam/2;
+ i = 234*SmallDiam/750;
+ i = i < 1 ? 1 : i;
+ myr.left = xc - i+i/2;
+ myr.right = xc + i/2;
+ myr.top = yc - i+i/2;
+ myr.bottom = yc + i/2;
+ Pie32(dc, myr.left, myr.top, myr.right, myr.bottom, xe, ye, xe, ye);
+ break;
+
+ case DFCS_MENUCHECK:
+ Points[0].x = myr.left + 253*SmallDiam/1000;
+ Points[0].y = myr.top + 445*SmallDiam/1000;
+ Points[1].x = myr.left + 409*SmallDiam/1000;
+ Points[1].y = Points[0].y + (Points[1].x-Points[0].x);
+ Points[2].x = myr.left + 690*SmallDiam/1000;
+ Points[2].y = Points[1].y - (Points[2].x-Points[1].x);
+ Points[3].x = Points[2].x;
+ Points[3].y = Points[2].y + 3*SmallDiam/16;
+ Points[4].x = Points[1].x;
+ Points[4].y = Points[1].y + 3*SmallDiam/16;
+ Points[5].x = Points[0].x;
+ Points[5].y = Points[0].y + 3*SmallDiam/16;
+ Polygon32(dc, Points, 6);
+ break;
+
+ default:
+ fprintf(stdnimp, "UITOOLS_DrawFrameMenu: Report this: Invalid menu; flags: 0x%04x\n", uFlags);
+ retval = FALSE;
+ break;
+ }
+
+ SelectObject32(dc, hpsave);
+ SelectObject32(dc, hbsave);
+ return retval;
}
@@ -372,6 +1434,10 @@
BOOL32 WINAPI DrawFrameControl32( HDC32 hdc, LPRECT32 rc, UINT32 uType,
UINT32 uState )
{
+ /* Win95 doesn't support drawing in other mapping modes */
+ if(GetMapMode32(hdc) != MM_TEXT)
+ return FALSE;
+
switch(uType)
{
case DFC_BUTTON:
diff --git a/debugger/info.c b/debugger/info.c
index f5c4d4c..a1cb378 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -141,7 +141,7 @@
" delete display <disnum>\n",
"Wine-specific commands:",
-" mode [16,32] walk [wnd,class,queue] <handle>",
+" mode [16,32] walk [wnd,class,queue,module]",
" info (see 'help info' for options)\n",
"The 'x' command accepts repeat counts and formats (including 'i') in the",
@@ -176,13 +176,13 @@
" info display Shows auto-display expressions in use",
" info locals Displays values of all local vars for current frame",
" info maps Dumps all virtual memory mappings",
-" info module Displays information about all modules",
-" info queue <handle> Dumps queue information",
+" info module <handle> Displays internal module state",
+" info queue <handle> Displays internal queue state",
" info reg Displays values in all registers at top of stack",
" info segments Dumps information about all known segments",
" info share Dumps information about shared libraries",
" info stack Dumps information about top of stack",
-" info wnd <handle> Dumps information about all windows",
+" info wnd <handle> Displays internal window state",
"",
NULL
};
diff --git a/documentation/Makefile.in b/documentation/Makefile.in
index fe1be2b..6026158 100644
--- a/documentation/Makefile.in
+++ b/documentation/Makefile.in
@@ -22,6 +22,10 @@
all: $(INFOFILES) $(DVIFILES)
+info: $(INFOFILES)
+
+dvi: $(DVIFILES)
+
@MAKE_RULES@
$(INFOFILES): $(SOURCES)
@@ -34,13 +38,17 @@
$(RM) $(INCLUDES)
for i in $(INCLUDES); do $(LN_S) $(TOPSRCDIR)/$$i $$i || exit 1; done
-install:: $(INFOFILES)
- for i in $(INFOFILES); do $(INSTALL_DATA) $$i $(infodir)/$$i; done
+install::
$(INSTALL_DATA) $(SRCDIR)/wine.man $(mandir)/wine$(manext)
+# Not done by default because of makeinfo bugs
+install_info: $(INFOFILES)
+ for i in $(INFOFILES); do $(INSTALL_DATA) $$i $(infodir)/$$i; done
+
clean::
$(RM) $(INFOFILES) $(DVIFILES) $(INCLUDES)
$(RM) wine.aux wine.cp wine.cps wine.fn wine.fns wine.ky wine.log \
wine.pg wine.toc wine.tp wine.tps wine.vr wine.vrs
+ $(RM) -r man3w
### Dependencies:
diff --git a/documentation/README.documentation b/documentation/README.documentation
new file mode 100644
index 0000000..6a91dc6
--- /dev/null
+++ b/documentation/README.documentation
@@ -0,0 +1,122 @@
+
+ Wine Documentation README
+
+
+Wine Man Page
+
+ The man page for the wine emulator is in this directory. It is installed
+by 'make install'.
+
+Wine Reference Manual
+
+ Texinfo source for preliminary comprehensive documentation is in
+this directory. Use 'make info' in this directory to generate the GNU
+info version, 'make dvi' to generate the DVI version (hit 'r' to
+ignore errors), or 'make all' for both. It is no longer installed by
+default.
+
+Wine API documentation
+
+ Do a 'make manpages' in the Wine toplevel directory to generate the
+API manpages from the Wine source, or 'make man' in any source
+subdirectory to generate manpages from only that directory. The
+manpages will be deposited in [documentation/man3w]. You will need
+c2man, available as source from http://www.debian.org/ and other
+places. Apply the patch included at the end of this file for improved
+terse description formatting. The man pages are not installed
+automatically.
+
+Other READMEs
+
+ Other informational files are in this directory as well as scattered
+through the source tree.
+
+Other resources:
+
+ Usenet: news:comp.emulators.ms-windows.wine
+ WWW: http://www.winehq.com/
+
+
+Writing Wine API Documentation
+
+To improve the documentation of the Wine API, just add comments to the
+existing source. For example,
+
+/******************************************************************
+ * PlayMetaFile32 (GDI32.265) Render metafile to device
+ *
+ * The metafile is rendered in the device context specified by hdc.
+ *
+ * RETURNS
+ *
+ * Always returns TRUE.
+ *
+ * FIXME
+ * Wine metafiles are not 100% binary compatible with Microsoft Windows
+ * metafiles.
+ */
+BOOL32 WINAPI PlayMetaFile32(
+ HDC32 hdc, /* handle of device context in which to render metafile */
+ HMETAFILE32 hmf /* metafile handle */
+) {
+
+becomes, after processing with c2man and nroff -man,
+
+
+PlayMetaFile32(3w) PlayMetaFile32(3w)
+
+
+NAME
+ PlayMetaFile32 - PlayMetaFile32 (GDI32.265) Render
+ metafile to device
+
+SYNOPSIS
+ BOOL32 PlayMetaFile32
+ (
+ HDC32 hdc,
+ HMETAFILE32 hmf
+ );
+
+PARAMETERS
+ HDC32 hdc
+ Handle of device context in which to render
+ metafile.
+
+ HMETAFILE32 hmf
+ Metafile handle.
+
+DESCRIPTION
+ The metafile is rendered in the device context specified
+ by hdc.
+
+RETURNS
+ Always returns TRUE.
+
+FIXME
+ Wine metafiles are not 100% binary compatible with
+ Microsoft Windows metafiles.
+
+----------------------------------------------------------------
+Patch for c2man:
+
+diff -u c2man-2.41.orig/manpage.c c2man-2.41/manpage.c
+--- c2man-2.41.orig/manpage.c Tue Apr 23 21:13:44 1996
++++ c2man-2.41/manpage.c Thu Dec 18 13:20:08 1997
+@@ -585,10 +585,15 @@
+ const char *endterse, *afterdash = skipdash(start_line);
+
+ /* find the end of the terse comment */
+- while (*c && *c != '.' && *c != '\n')
++ while (*c && *c != '\n')
++ {
+ c++;
++ /* '.' ends terse description only if it ends sentence */
++ if (*(c-1)=='.' && *c && isspace(*c))
++ break;
++ }
+
+- endterse = *c == '.' ? c+1 : c;
++ endterse = c;
+ *terse = alloc_string(
+ afterdash < endterse ? afterdash : start_line,
+ endterse);
diff --git a/documentation/how-to-port b/documentation/how-to-port
new file mode 100644
index 0000000..5800f92
--- /dev/null
+++ b/documentation/how-to-port
@@ -0,0 +1,135 @@
+What is this?
+------------
+
+This note is a short description of
+
+* How to port Wine to your favourite operating system
+* Why you probably shouldn't use "#ifdef MyOS"
+* What to do instead.
+
+This document does not say a thing about how to port Wine to non-386
+operating systems, though. You would need a CPU emulator. Let's get
+Wine into a better shape on 386 first, OK?
+
+
+
+
+Why "#ifdef MyOS" is probably a mistake.
+---------------------------------------
+
+Operating systems change. Maybe yours doesn't have the "foo.h"
+header, but maybe a future version will have it. If you want
+to "#include <foo.h>", it doesn't matter what operating system
+you are using; it only matters whether "foo.h" is there.
+
+Furthermore, operating systems change names or "fork" into
+several ones. An "#ifdef MyOs" will break over time.
+
+If you use the feature of Autoconf, the Gnu auto-configuration
+utility wisely, you will help future porters automatically
+because your changes will test for _features_, not names of
+operating systems. A feature can be many things:
+
+* existance of a header file
+* existance of a library function
+* existance of libraries
+* bugs in header files, library functions, the compiler, ...
+* (you name it)
+
+You will need Gnu Autoconf, which you can get from your
+friendly Gnu mirror. This program takes Wine's "configure.in"
+file and produces a "configure" shell script that users use to
+configure Wine to their system.
+
+There _are_ exceptions to the "avoid #ifdef MyOS" rule. Wine,
+for example, needs the internals of the signal stack -- that
+cannot easily be described in terms of features.
+
+Let's now turn to specific porting problems and how to solve
+them.
+
+
+
+MyOS doesn't have the `foo.h' header!
+------------------------------------
+
+This first step is to make Autoconf check for this header.
+In configure.in you add a segment like this in the section
+that checks for header files (search for "header files"):
+
+ AC_CHECK_HEADER(foo.h, AC_DEFINE(HAVE_FOO_H))
+
+If your operating system supports a header file with the
+same contents but a different name, say bar.h, add a check
+for that also.
+
+Now you can change
+
+ #include <foo.h>
+
+to
+
+ #ifdef HAVE_FOO_H
+ #include <foo.h>
+ #elif defined (HAVE_BAR_H)
+ #include <bat.h>
+ #endif
+
+If your system doesn't have a corresponding header file even
+though it has the library functions being used, you might
+have to add an "#else" section to the conditional. Avoid
+this if you can.
+
+You will also need to add "#undef HAVE_FOO_H" (etc.) to
+include/config.h.in
+
+Finish up with "make configure" and "./configure".
+
+
+MyOS doesn't have the `bar' function!
+------------------------------------
+
+A typical example of this is the `memmove'. To solve this
+problem you would add `memmove' to the list of functions
+that Autoconf checks for. In configure.in you search for
+AC_CHECK_FUNCS and add `memmove'. (You will notice that
+someone already did this for this particular function.)
+
+Secondly, you will also need to add "#undef HAVE_BAR"
+to include/config.h.in
+
+The next step depends on the nature of the missing function.
+
+Case 1: It's easy to write a complete emulation of the
+ function. (`memmove' belongs to this case.)
+
+ You add your emulation in misc/port.c surrounded by
+ "#ifndef HAVE_MEMMOVE" and "#endif".
+
+ You might have to add a prototype for your function. If so,
+ include/miscemu.h might be the place. Don't forget to protect
+ that definition by "#ifndef HAVE_MEMMOVE" and "#endif" also!
+
+Case 2: A general emulation is hard, but Wine is only using
+ a special case.
+
+ An example is the various "wait" calls used in SIGNAL_child
+ from loader/signal.c. Here we have a multi-branch case on
+ features:
+
+ #ifdef HAVE_THIS
+ ...
+ #elif defined (HAVE_THAT)
+ ...
+ #elif defined (HAVE_SOMETHING_ELSE)
+ ...
+ #endif
+
+ Note that this is very different from testing on operating
+ systems. If a new version of your operating systems comes
+ out and adds a new function, this code will magically start
+ using it.
+
+Finish up with "make configure" and "./configure".
+
+
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 2ace4e0..5cd8e76 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -8,6 +8,7 @@
#include <sys/types.h>
#include <ctype.h>
#include <dirent.h>
+#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
@@ -373,15 +374,15 @@
#ifdef VFAT_IOCTL_READDIR_BOTH
if (dir->fd != -1)
{
- if (ioctl( dir->fd, VFAT_IOCTL_READDIR_BOTH, (long)dir->dirent ) == -1)
- return FALSE;
- if (!dir->dirent[0].d_reclen) return FALSE;
- if (!DOSFS_ToDosFCBFormat( dir->dirent[0].d_name, dir->short_name ))
- dir->short_name[0] = '\0';
- *short_name = dir->short_name;
- if (dir->dirent[1].d_name[0]) *long_name = dir->dirent[1].d_name;
- else *long_name = dir->dirent[0].d_name;
- return TRUE;
+ if (ioctl( dir->fd, VFAT_IOCTL_READDIR_BOTH, (long)dir->dirent ) != -1) {
+ if (!dir->dirent[0].d_reclen) return FALSE;
+ if (!DOSFS_ToDosFCBFormat( dir->dirent[0].d_name, dir->short_name ))
+ dir->short_name[0] = '\0';
+ *short_name = dir->short_name;
+ if (dir->dirent[1].d_name[0]) *long_name = dir->dirent[1].d_name;
+ else *long_name = dir->dirent[0].d_name;
+ return TRUE;
+ }
}
#endif /* VFAT_IOCTL_READDIR_BOTH */
@@ -518,8 +519,8 @@
if (!(dir = DOSFS_OpenDir( path )))
{
- dprintf_dosfs( stddeb, "DOSFS_FindUnixName(%s,%s): can't open dir\n",
- path, name );
+ dprintf_dosfs( stddeb, "DOSFS_FindUnixName(%s,%s): can't open dir: %s\n",
+ path, name, strerror(errno) );
return FALSE;
}
@@ -853,16 +854,18 @@
p = buffer;
*p++ = 'A' + drive;
*p++ = ':';
- if (IS_END_OF_NAME(*name)) /* Absolute path */
+ if (IS_END_OF_NAME(*name) && (*name)) /* Absolute path */
{
while ((*name == '\\') || (*name == '/')) name++;
}
- else /* Relative path */
+ else /* Relative path or empty path */
{
*p++ = '\\';
lstrcpyn32A( p, DRIVE_GetDosCwd(drive), sizeof(buffer) - 3 );
if (*p) p += strlen(p); else p--;
}
+ if (!*name) /* empty path */
+ *p++ = '\\';
*p = '\0';
while (*name)
diff --git a/files/drive.c b/files/drive.c
index f874df8..0fd582d 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -653,6 +653,57 @@
/***********************************************************************
+ * GetDiskFreeSpaceEx32A (KERNEL32.871)
+ */
+BOOL32 WINAPI GetDiskFreeSpaceEx32A( LPCSTR root,
+ LPULARGE_INTEGER avail,
+ LPULARGE_INTEGER total,
+ LPULARGE_INTEGER totalfree)
+{
+ int drive;
+ DWORD size,available;
+
+ if (!root) drive = DRIVE_GetCurrentDrive();
+ else
+ {
+ if ((root[1]) && ((root[1] != ':') || (root[2] != '\\')))
+ {
+ fprintf( stderr, "GetDiskFreeSpaceExA: invalid root '%s'\n",
+ root );
+ return FALSE;
+ }
+ drive = toupper(root[0]) - 'A';
+ }
+ if (!DRIVE_GetFreeSpace(drive, &size, &available)) return FALSE;
+ /*FIXME: Do we have the number of bytes available to the user? */
+ avail->HighPart = total->HighPart = 0;
+ avail->LowPart = available;
+ total->LowPart = size;
+ if(totalfree)
+ {
+ totalfree->HighPart =0;
+ totalfree->LowPart= available;
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * GetDiskFreeSpaceEx32W (KERNEL32.873)
+ */
+BOOL32 WINAPI GetDiskFreeSpaceEx32W( LPCWSTR root, LPULARGE_INTEGER avail,
+ LPULARGE_INTEGER total,
+ LPULARGE_INTEGER totalfree)
+{
+ LPSTR xroot;
+ BOOL32 ret;
+
+ xroot = HEAP_strdupWtoA( GetProcessHeap(), 0, root);
+ ret = GetDiskFreeSpaceEx32A( xroot, avail, total, totalfree);
+ HeapFree( GetProcessHeap(), 0, xroot );
+ return ret;
+}
+
+/***********************************************************************
* GetDriveType16 (KERNEL.136)
*/
UINT16 WINAPI GetDriveType16( UINT16 drive )
diff --git a/files/file.c b/files/file.c
index cdbbe55..10380e8 100644
--- a/files/file.c
+++ b/files/file.c
@@ -147,7 +147,7 @@
int save_errno = errno; /* errno gets overwritten by printf */
dprintf_file(stddeb, "FILE_SetDosError: errno = %d %s\n", errno,
- sys_errlist[errno] );
+ strerror(errno) );
switch (save_errno)
{
case EAGAIN:
@@ -531,7 +531,7 @@
char temppath[144];
if (!(drive & ~TF_FORCEDRIVE)) /* drive 0 means current default drive */
- drive |= DRIVE_GetCurrentDrive();
+ drive |= DRIVE_GetCurrentDrive() + 'A';
if ((drive & TF_FORCEDRIVE) &&
!DRIVE_IsValid( toupper(drive & ~TF_FORCEDRIVE) - 'A' ))
@@ -542,12 +542,17 @@
}
if (drive & TF_FORCEDRIVE)
- sprintf(temppath,"%c:", drive & ~TF_FORCEDRIVE );
+ {
+ sprintf( temppath, "%c:\\", drive & ~TF_FORCEDRIVE );
+ lstrcpyn32A( temppath + 3,
+ DRIVE_GetDosCwd( toupper(drive & ~TF_FORCEDRIVE) - 'A'),
+ 129 );
+ }
else
{
GetTempPath32A( 132, temppath );
- strcat( temppath, "\\" );
}
+ strcat( temppath, "\\" );
return (UINT16)GetTempFileName32A( temppath, prefix, unique, buffer );
}
@@ -1603,6 +1608,8 @@
/* check if lock overlaps a current lock for the same file */
for (curr = locks; curr; curr = curr->next) {
if (strcmp(curr->unix_name, file->unix_name) == 0) {
+ if ((f->l_start == curr->base) && (f->l_len == curr->len))
+ return TRUE;/* region is identic */
if ((f->l_start < (curr->base + curr->len)) &&
((f->l_start + f->l_len) > curr->base)) {
/* region overlaps */
diff --git a/files/profile.c b/files/profile.c
index 875a590..545049d 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -942,6 +942,8 @@
LPCSTR def_val, LPSTR buffer,
INT32 len, LPCSTR filename )
{
+ if (!filename)
+ filename = "win.ini";
if (PROFILE_Open( filename ))
return PROFILE_GetString( section, entry, def_val, buffer, len );
lstrcpyn32A( buffer, def_val, len );
@@ -1021,6 +1023,27 @@
return res;
}
+/***********************************************************************
+ * WritePrivateProfileSection32A (KERNEL32)
+ */
+BOOL32 WINAPI WritePrivateProfileSection32A( LPCSTR section,
+ LPCSTR string, LPCSTR filename )
+{
+ char *p =(char*)string;
+
+ fprintf( stdnimp,"WritePrivateProfileSection32A empty stup\n");
+ if (debugging_profile) {
+ fprintf(stddeb,"file(%s) => [%s]\n", filename,section);
+ while (*(p+1)) {
+ fprintf(stddeb,"%s\n",p);
+ p += strlen(p);
+ p += 1;
+ }
+ }
+
+ return FALSE;
+}
+
/***********************************************************************
* WriteOutProfiles (KERNEL.315)
diff --git a/graphics/Makefile.in b/graphics/Makefile.in
index 5912d90..3784c52 100644
--- a/graphics/Makefile.in
+++ b/graphics/Makefile.in
@@ -7,12 +7,14 @@
C_SRCS = \
bitblt.c \
+ cache.c \
driver.c \
env.c \
escape.c \
fontengine.c \
mapping.c \
painting.c \
+ path.c \
wing.c
all: $(MODULE).o
diff --git a/graphics/cache.c b/graphics/cache.c
new file mode 100644
index 0000000..5d0f184
--- /dev/null
+++ b/graphics/cache.c
@@ -0,0 +1,41 @@
+/*
+ * Wine internally cached objects to speedup some things and prevent
+ * infinite duplication of trivial code and data.
+ *
+ * Copyright 1997 Bertho A. Stultiens
+ *
+ */
+
+#include "windows.h"
+#include "cache.h"
+
+static const WORD wPattern55AA[] =
+{
+ 0x5555, 0xaaaa, 0x5555, 0xaaaa,
+ 0x5555, 0xaaaa, 0x5555, 0xaaaa
+};
+
+static HBRUSH32 hPattern55AABrush = 0;
+static HBITMAP32 hPattern55AABitmap = 0;
+
+
+/*********************************************************************
+ * CACHE_GetPattern55AABrush
+ */
+HBRUSH32 CACHE_GetPattern55AABrush(void)
+{
+ if (!hPattern55AABrush)
+ hPattern55AABrush = CreatePatternBrush32(CACHE_GetPattern55AABitmap());
+ return hPattern55AABrush;
+}
+
+
+/*********************************************************************
+ * CACHE_GetPattern55AABitmap
+ */
+HBITMAP32 CACHE_GetPattern55AABitmap(void)
+{
+ if (!hPattern55AABitmap)
+ hPattern55AABitmap = CreateBitmap32( 8, 8, 1, 1, wPattern55AA );
+ return hPattern55AABitmap;
+}
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index b187bce..f60fe08 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -12,15 +12,13 @@
#include "stddebug.h"
#include "debug.h"
-static BOOL32 MFDRV_DeleteDC( DC *dc );
-
static const DC_FUNCTIONS MFDRV_Funcs =
{
MFDRV_Arc, /* pArc */
MFDRV_BitBlt, /* pBitBlt */
MFDRV_Chord, /* pChord */
- NULL, /* pCreateDC */
- MFDRV_DeleteDC, /* pDeleteDC */
+ NULL, /* no implementation */ /* pCreateDC */
+ NULL, /* no implementation */ /* pDeleteDC */
NULL, /* pDeleteObject */
MFDRV_Ellipse, /* pEllipse */
NULL, /* pEnumDeviceFonts */
@@ -30,7 +28,7 @@
MFDRV_ExtFloodFill, /* pExtFloodFill */
MFDRV_ExtTextOut, /* pExtTextOut */
NULL, /* pGetCharWidth */
- NULL /* no implementation */, /* pGetPixel */
+ NULL, /* no implementation */ /* pGetPixel */
NULL, /* pGetTextExtentPoint */
NULL, /* pGetTextMetrics */
NULL, /* pIntersectClipRect */
@@ -131,6 +129,7 @@
if (physDev->mh) HeapFree( SystemHeap, 0, physDev->mh );
HeapFree( SystemHeap, 0, physDev );
dc->physDev = NULL;
+ GDI_FreeObject(dc->hSelf);
return TRUE;
}
@@ -154,13 +153,13 @@
physDev->mh->mtType = METAFILE_DISK;
if ((hFile = _lcreat32( filename, 0 )) == HFILE_ERROR32)
{
- DeleteDC32( dc->hSelf );
+ MFDRV_DeleteDC( dc );
return 0;
}
if (_lwrite32( hFile, (LPSTR)physDev->mh,
sizeof(*physDev->mh)) == HFILE_ERROR32)
{
- DeleteDC32( dc->hSelf );
+ MFDRV_DeleteDC( dc );
return 0;
}
physDev->mh->mtNoParameters = hFile; /* store file descriptor here */
@@ -186,7 +185,7 @@
dprintf_metafile( stddeb, "CloseMetaFile(%04x)\n", hdc );
- if (!(dc = DC_GetDCPtr( hdc ))) return 0;
+ if (!(dc = (DC *) GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC ))) return 0;
physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
/* Construct the end of metafile record - this is documented
@@ -195,7 +194,7 @@
if (!MF_MetaParam0(dc, META_EOF))
{
- DeleteDC32( hdc );
+ MFDRV_DeleteDC( dc );
return 0;
}
@@ -205,13 +204,13 @@
physDev->mh->mtNoParameters = 0;
if (_llseek32(hFile, 0L, 0) == HFILE_ERROR32)
{
- DeleteDC32( hdc );
+ MFDRV_DeleteDC( dc );
return 0;
}
if (_lwrite32( hFile, (LPSTR)physDev->mh,
sizeof(*physDev->mh)) == HFILE_ERROR32)
{
- DeleteDC32( hdc );
+ MFDRV_DeleteDC( dc );
return 0;
}
_lclose32(hFile);
@@ -223,7 +222,7 @@
physDev->mh->mtSize * sizeof(WORD),
GetCurrentPDB(), FALSE, FALSE, FALSE, NULL );
physDev->mh = NULL; /* So it won't be deleted */
- DeleteDC32( hdc );
+ MFDRV_DeleteDC( dc );
return hmf;
}
diff --git a/graphics/painting.c b/graphics/painting.c
index 15cb841..9b169e4 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -2,6 +2,7 @@
* Misc. graphics operations
*
* Copyright 1993, 1994 Alexandre Julliard
+ * Copyright 1997 Bertho A. Stultiens
*/
#include <math.h>
@@ -20,18 +21,13 @@
#include "metafile.h"
#include "syscolor.h"
#include "palette.h"
+#include "cache.h"
#include "color.h"
#include "region.h"
+#include "path.h"
#include "stddebug.h"
#include "debug.h"
-BOOL32 DrawDiagEdge32(HDC32 hdc, RECT32 *rect, UINT32 edge, UINT32 flags);
-BOOL32 DrawRectEdge32(HDC32 hdc, RECT32 *rect, UINT32 edge, UINT32 flags);
-BOOL32 DrawFrameButton32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
-BOOL32 DrawFrameCaption32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
-BOOL32 DrawFrameMenu32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
-BOOL32 DrawFrameScroll32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
-
/***********************************************************************
* LineTo16 (GDI.19)
*/
@@ -48,6 +44,10 @@
{
DC * dc = DC_GetDCPtr( hdc );
+ if(dc && PATH_IsPathOpen(dc->w.path))
+ if(!PATH_LineTo(hdc, x, y))
+ return FALSE;
+
return dc && dc->funcs->pLineTo &&
dc->funcs->pLineTo(dc,x,y);
}
@@ -87,6 +87,10 @@
{
DC * dc = DC_GetDCPtr( hdc );
+ if(dc && PATH_IsPathOpen(dc->w.path))
+ if(!PATH_MoveTo(hdc))
+ return FALSE;
+
return dc && dc->funcs->pMoveToEx &&
dc->funcs->pMoveToEx(dc,x,y,pt);
}
@@ -680,7 +684,7 @@
/**********************************************************************
- * DrawFrameControl32 (USER32.152)
+ * DrawAnimatedRects32 (USER32.153)
*/
BOOL32 WINAPI DrawAnimatedRects32( HWND32 hwnd, int idAni,
const LPRECT32 lprcFrom,
@@ -691,13 +695,238 @@
return TRUE;
}
-BOOL32 WINAPI DrawState32A(
- HDC32 hdc,HBRUSH32 hbrush,DRAWSTATEPROC drawstateproc,
- LPARAM lparam,WPARAM32 wparam,INT32 x,INT32 y,INT32 z,INT32 a,UINT32 b
-) {
- fprintf(stderr,"DrawStateA(%x,%x,%p,0x%08lx,0x%08x,%d,%d,%d,%d,%d),stub\n",
- hdc,hbrush,drawstateproc,lparam,wparam,x,y,z,a,b
- );
- return TRUE;
+
+/**********************************************************************
+ * PAINTING_DrawStateJam
+ *
+ * Jams in the requested type in the dc
+ */
+static BOOL32 PAINTING_DrawStateJam(HDC32 hdc, UINT32 opcode,
+ DRAWSTATEPROC32 func, LPARAM lp, WPARAM32 wp,
+ LPRECT32 rc, UINT32 dtflags,
+ BOOL32 unicode, BOOL32 _32bit)
+{
+ HDC32 memdc;
+ HBITMAP32 hbmsave;
+ BOOL32 retval;
+ INT32 cx = rc->right - rc->left;
+ INT32 cy = rc->bottom - rc->top;
+
+ switch(opcode)
+ {
+ case DST_TEXT:
+ case DST_PREFIXTEXT:
+ if(unicode)
+ return DrawText32W(hdc, (LPWSTR)lp, (INT32)wp, rc, dtflags);
+ else if(_32bit)
+ return DrawText32A(hdc, (LPSTR)lp, (INT32)wp, rc, dtflags);
+ else
+ return DrawText32A(hdc, (LPSTR)PTR_SEG_TO_LIN(lp), (INT32)wp, rc, dtflags);
+
+ case DST_ICON:
+ return DrawIcon32(hdc, rc->left, rc->top, (HICON32)lp);
+
+ case DST_BITMAP:
+ memdc = CreateCompatibleDC32(hdc);
+ if(!memdc) return FALSE;
+ hbmsave = (HBITMAP32)SelectObject32(memdc, (HBITMAP32)lp);
+ if(!hbmsave)
+ {
+ DeleteDC32(memdc);
+ return FALSE;
+ }
+ retval = BitBlt32(hdc, rc->left, rc->top, cx, cy, memdc, 0, 0, SRCCOPY);
+ SelectObject32(memdc, hbmsave);
+ DeleteDC32(memdc);
+ return retval;
+
+ case DST_COMPLEX:
+ if(func)
+ if(_32bit)
+ return func(hdc, lp, wp, cx, cy);
+ else
+ return (BOOL32)((DRAWSTATEPROC16)func)((HDC16)hdc, (LPARAM)lp, (WPARAM16)wp, (INT16)cx, (INT16)cy);
+ else
+ return FALSE;
+ }
+ return FALSE;
}
+/**********************************************************************
+ * PAINTING_DrawState32()
+ */
+static BOOL32 PAINTING_DrawState32(HDC32 hdc, HBRUSH32 hbr,
+ DRAWSTATEPROC32 func, LPARAM lp, WPARAM32 wp,
+ INT32 x, INT32 y, INT32 cx, INT32 cy,
+ UINT32 flags, BOOL32 unicode, BOOL32 _32bit)
+{
+ HBITMAP32 hbm, hbmsave;
+ HFONT32 hfsave;
+ HBRUSH32 hbsave;
+ HDC32 memdc;
+ RECT32 rc;
+ UINT32 dtflags = DT_NOCLIP;
+ COLORREF fg, bg;
+ UINT32 opcode = flags & 0xf;
+ INT32 len = wp;
+ BOOL32 retval, tmp;
+
+ if((opcode == DST_TEXT || opcode == DST_PREFIXTEXT) && !len) /* The string is '\0' terminated */
+ {
+ if(unicode)
+ len = lstrlen32W((LPWSTR)lp);
+ else if(_32bit)
+ len = lstrlen32A((LPSTR)lp);
+ else
+ len = lstrlen32A((LPSTR)PTR_SEG_TO_LIN(lp));
+ }
+
+ /* Find out what size the image has if not given by caller */
+ if(!cx || !cy)
+ {
+ SIZE32 s;
+ CURSORICONINFO *ici;
+ BITMAPOBJ *bmp;
+
+ switch(opcode)
+ {
+ case DST_TEXT:
+ case DST_PREFIXTEXT:
+ if(unicode)
+ retval = GetTextExtentPoint32W(hdc, (LPWSTR)lp, len, &s);
+ else if(_32bit)
+ retval = GetTextExtentPoint32A(hdc, (LPSTR)lp, len, &s);
+ else
+ retval = GetTextExtentPoint32A(hdc, PTR_SEG_TO_LIN(lp), len, &s);
+ if(!retval) return FALSE;
+ break;
+
+ case DST_ICON:
+ ici = (CURSORICONINFO *)GlobalLock16((HGLOBAL16)lp);
+ if(!ici) return FALSE;
+ s.cx = ici->nWidth;
+ s.cy = ici->nHeight;
+ GlobalUnlock16((HGLOBAL16)lp);
+ break;
+
+ case DST_BITMAP:
+ bmp = (BITMAPOBJ *)GDI_GetObjPtr((HBITMAP16)lp, BITMAP_MAGIC);
+ if(!bmp) return FALSE;
+ s.cx = bmp->bitmap.bmWidth;
+ s.cy = bmp->bitmap.bmHeight;
+ break;
+
+ case DST_COMPLEX: /* cx and cy must be set in this mode */
+ return FALSE;
+ }
+
+ if(!cx) cx = s.cx;
+ if(!cy) cy = s.cy;
+ }
+
+ rc.left = x;
+ rc.top = y;
+ rc.right = x + cx;
+ rc.bottom = y + cy;
+
+ if(flags & DSS_RIGHT) /* This one is not documented in the win32.hlp file */
+ dtflags |= DT_RIGHT;
+ if(opcode == DST_TEXT)
+ dtflags |= DT_NOPREFIX;
+
+ /* For DSS_NORMAL we just jam in the image and return */
+ if((flags & 0x7ff0) == DSS_NORMAL)
+ {
+ return PAINTING_DrawStateJam(hdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
+ }
+
+ /* For all other states we need to convert the image to B/W in a local bitmap */
+ /* before it is displayed */
+ fg = SetTextColor32(hdc, RGB(0, 0, 0));
+ bg = SetBkColor32(hdc, RGB(255, 255, 255));
+ hbm = NULL; hbmsave = NULL; memdc = NULL; memdc = NULL; hbsave = NULL;
+ retval = FALSE; /* assume failure */
+
+ /* From here on we must use "goto cleanup" when something goes wrong */
+ hbm = CreateBitmap32(cx, cy, 1, 1, NULL);
+ if(!hbm) goto cleanup;
+ memdc = CreateCompatibleDC32(hdc);
+ if(!memdc) goto cleanup;
+ hbmsave = (HBITMAP32)SelectObject32(memdc, hbm);
+ if(!hbmsave) goto cleanup;
+ rc.left = rc.top = 0;
+ rc.right = cx;
+ rc.bottom = cy;
+ if(!FillRect32(memdc, &rc, (HBRUSH32)GetStockObject32(WHITE_BRUSH))) goto cleanup;
+ SetBkColor32(memdc, RGB(255, 255, 255));
+ SetTextColor32(memdc, RGB(0, 0, 0));
+ hfsave = (HFONT32)SelectObject32(memdc, GetCurrentObject(hdc, OBJ_FONT));
+ if(!hfsave && (opcode == DST_TEXT || opcode == DST_PREFIXTEXT)) goto cleanup;
+ tmp = PAINTING_DrawStateJam(memdc, opcode, func, lp, len, &rc, dtflags, unicode, _32bit);
+ if(hfsave) SelectObject32(memdc, hfsave);
+ if(!tmp) goto cleanup;
+
+ /* These states cause the image to be dithered */
+ if(flags & (DSS_UNION|DSS_DISABLED))
+ {
+ hbsave = (HBRUSH32)SelectObject32(memdc, CACHE_GetPattern55AABrush());
+ if(!hbsave) goto cleanup;
+ tmp = PatBlt32(memdc, 0, 0, cx, cy, 0x00FA0089);
+ if(hbsave) SelectObject32(memdc, hbsave);
+ if(!tmp) goto cleanup;
+ }
+
+ hbsave = (HBRUSH32)SelectObject32(hdc, hbr ? hbr : GetStockObject32(WHITE_BRUSH));
+ if(!hbsave) goto cleanup;
+
+ if(!BitBlt32(hdc, x, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
+
+ /* DSS_DEFAULT makes the image boldface */
+ if(flags & DSS_DEFAULT)
+ {
+ if(!BitBlt32(hdc, x+1, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
+ }
+
+ retval = TRUE; /* We succeeded */
+
+cleanup:
+ SetTextColor32(hdc, fg);
+ SetBkColor32(hdc, bg);
+
+ if(hbsave) SelectObject32(hdc, hbsave);
+ if(hbmsave) SelectObject32(memdc, hbmsave);
+ if(hbm) DeleteObject32(hbm);
+ if(memdc) DeleteDC32(memdc);
+
+ return retval;
+}
+
+/**********************************************************************
+ * DrawState32A() (USER32.162)
+ */
+BOOL32 WINAPI DrawState32A(HDC32 hdc, HBRUSH32 hbr,
+ DRAWSTATEPROC32 func, LPARAM ldata, WPARAM32 wdata,
+ INT32 x, INT32 y, INT32 cx, INT32 cy, UINT32 flags)
+{
+ return PAINTING_DrawState32(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, FALSE, TRUE);
+}
+
+/**********************************************************************
+ * DrawState32W() (USER32.163)
+ */
+BOOL32 WINAPI DrawState32W(HDC32 hdc, HBRUSH32 hbr,
+ DRAWSTATEPROC32 func, LPARAM ldata, WPARAM32 wdata,
+ INT32 x, INT32 y, INT32 cx, INT32 cy, UINT32 flags)
+{
+ return PAINTING_DrawState32(hdc, hbr, func, ldata, wdata, x, y, cx, cy, flags, TRUE, TRUE);
+}
+
+/**********************************************************************
+ * DrawState16() (USER.449)
+ */
+BOOL16 WINAPI DrawState16(HDC16 hdc, HBRUSH16 hbr,
+ DRAWSTATEPROC16 func, LPARAM ldata, WPARAM16 wdata,
+ INT16 x, INT16 y, INT16 cx, INT16 cy, UINT16 flags)
+{
+ return PAINTING_DrawState32(hdc, hbr, (DRAWSTATEPROC32)func, ldata, wdata, x, y, cx, cy, flags, FALSE, FALSE);
+}
diff --git a/graphics/path.c b/graphics/path.c
new file mode 100644
index 0000000..e4e4013
--- /dev/null
+++ b/graphics/path.c
@@ -0,0 +1,704 @@
+/*
+ * Graphics paths (BeginPath, EndPath etc.)
+ *
+ * Copyright 1997 Martin Boehme
+ */
+
+#include <assert.h>
+#include <malloc.h>
+
+#include "windows.h"
+#include "winerror.h"
+
+#include "dc.h"
+#include "debug.h"
+#include "path.h"
+
+/* Notes on the implementation
+ *
+ * The implementation is based on dynamically resizable arrays of points and
+ * flags. I dithered for a bit before deciding on this implementation, and
+ * I had even done a bit of work on a linked list version before switching
+ * to arrays. It's a bit of a tradeoff. When you use linked lists, the
+ * implementation of FlattenPath is easier, because you can rip the
+ * PT_BEZIERTO entries out of the middle of the list and link the
+ * corresponding PT_LINETO entries in. However, when you use arrays,
+ * PathToRegion becomes easier, since you can essentially just pass your array
+ * of points to CreatePolyPolygonRgn. Also, if I'd used linked lists, I would
+ * have had the extra effort of creating a chunk-based allocation scheme
+ * in order to use memory effectively. That's why I finally decided to use
+ * arrays. Note by the way that the array based implementation has the same
+ * linear time complexity that linked lists would have since the arrays grow
+ * exponentially.
+ *
+ * The points are stored in the path in device coordinates. This is
+ * consistent with the way Windows does things (for instance, see the Win32
+ * SDK documentation for GetPath).
+ *
+ * The word "stroke" appears in several places (e.g. in the flag
+ * GdiPath.newStroke). A stroke consists of a PT_MOVETO followed by one or
+ * more PT_LINETOs or PT_BEZIERTOs, up to, but not including, the next
+ * PT_MOVETO. Note that this is not the same as the definition of a figure;
+ * a figure can contain several strokes.
+ *
+ * I modified the drawing functions (MoveTo, LineTo etc.) to test whether
+ * the path is open and to call the corresponding function in path.c if this
+ * is the case. A more elegant approach would be to modify the function
+ * pointers in the DC_FUNCTIONS structure; however, this would be a lot more
+ * complex. Also, the performance degradation caused by my approach in the
+ * case where no path is open is so small that it cannot be measured.
+ *
+ * Martin Boehme
+ */
+
+/* FIXME: A lot of stuff isn't implemented yet. There is much more to come. */
+
+#define NUM_ENTRIES_INITIAL 16 /* Initial size of points / flags arrays */
+#define GROW_FACTOR_NUMER 2 /* Numerator of grow factor for the array */
+#define GROW_FACTOR_DENOM 1 /* Denominator of grow factor */
+
+
+static BOOL32 PATH_PathToRegion(const GdiPath *pPath, INT32 nPolyFillMode,
+ HRGN32 *pHrgn);
+static void PATH_EmptyPath(GdiPath *pPath);
+static BOOL32 PATH_AddEntry(GdiPath *pPath, POINT32 point, BYTE flags);
+static BOOL32 PATH_ReserveEntries(GdiPath *pPath, INT32 numEntries);
+static BOOL32 PATH_GetPathFromHDC(HDC32 hdc, GdiPath **ppPath);
+
+/***********************************************************************
+ * BeginPath32 (GDI32.9)
+ */
+BOOL32 WINAPI BeginPath32(HDC32 hdc)
+{
+ GdiPath *pPath;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ /* If path is already open, do nothing */
+ if(pPath->state==PATH_Open)
+ return TRUE;
+
+ /* Make sure that path is empty */
+ PATH_EmptyPath(pPath);
+
+ /* Initialize variables for new path */
+ pPath->newStroke=TRUE;
+ pPath->state=PATH_Open;
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * EndPath32 (GDI32.78)
+ */
+BOOL32 WINAPI EndPath32(HDC32 hdc)
+{
+ GdiPath *pPath;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ /* Check that path is currently being constructed */
+ if(pPath->state!=PATH_Open)
+ {
+ SetLastError(ERROR_CAN_NOT_COMPLETE);
+ return FALSE;
+ }
+
+ /* Set flag to indicate that path is finished */
+ pPath->state=PATH_Closed;
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * AbortPath32 (GDI32.1)
+ */
+BOOL32 WINAPI AbortPath32(HDC32 hdc)
+/* FIXME: Check that SetLastError is being called correctly */
+{
+ GdiPath *pPath;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Remove all entries from the path */
+ PATH_EmptyPath(pPath);
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * CloseFigure32 (GDI32.16)
+ */
+BOOL32 WINAPI CloseFigure32(HDC32 hdc)
+/* FIXME: Check that SetLastError is being called correctly */
+{
+ GdiPath *pPath;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Check that path is open */
+ if(pPath->state!=PATH_Open)
+ {
+ SetLastError(ERROR_CAN_NOT_COMPLETE);
+ return FALSE;
+ }
+
+ /* Set PT_CLOSEFIGURE on the last entry and start a new stroke */
+ if(pPath->numEntriesUsed)
+ {
+ pPath->pFlags[pPath->numEntriesUsed-1]|=PT_CLOSEFIGURE;
+ pPath->newStroke=TRUE;
+ }
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * GetPath32 (GDI32.210)
+ */
+INT32 WINAPI GetPath32(HDC32 hdc, LPPOINT32 pPoints, LPBYTE pTypes,
+ INT32 nSize)
+{
+ GdiPath *pPath;
+ BOOL32 temp_flag;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+
+ /* Check that path is closed */
+ if(pPath->state!=PATH_Closed)
+ {
+ SetLastError(ERROR_CAN_NOT_COMPLETE);
+ return -1;
+ }
+
+ if(nSize==0)
+ return pPath->numEntriesUsed;
+ else if(nSize<pPath->numEntriesUsed)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+ else
+ {
+ memcpy(pPoints, pPath->pPoints, sizeof(POINT32)*pPath->numEntriesUsed);
+ memcpy(pTypes, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
+
+ /* Convert the points to logical coordinates */
+ temp_flag=DPtoLP32(hdc, pPoints, pPath->numEntriesUsed);
+
+ /* Since hdc is valid, conversion should never fail */
+ assert(temp_flag);
+
+ return pPath->numEntriesUsed;
+ }
+}
+
+
+/***********************************************************************
+ * PathToRegion32 (GDI32.261)
+ */
+HRGN32 WINAPI PathToRegion32(HDC32 hdc)
+/* FIXME: Check that SetLastError is being called correctly */
+/* The documentation does not state this explicitly, but a test under Windows
+ * shows that the region which is returned should be in device coordinates.
+ */
+{
+ GdiPath *pPath;
+ HRGN32 hrgnRval;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ /* Check that path is closed */
+ if(pPath->state!=PATH_Closed)
+ {
+ SetLastError(ERROR_CAN_NOT_COMPLETE);
+ return 0;
+ }
+
+ /* FIXME: Should we empty the path even if conversion failed? */
+ if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnRval))
+ PATH_EmptyPath(pPath);
+ else
+ hrgnRval=0;
+
+ return hrgnRval;
+}
+
+
+/***********************************************************************
+ * FillPath32 (GDI32.100)
+ */
+BOOL32 WINAPI FillPath32(HDC32 hdc)
+/* FIXME: Check that SetLastError is being called correctly */
+{
+ GdiPath *pPath;
+ INT32 mapMode;
+ POINT32 ptViewportExt, ptViewportOrg, ptWindowExt, ptWindowOrg;
+ HRGN32 hrgn;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Check that path is closed */
+ if(pPath->state!=PATH_Closed)
+ {
+ SetLastError(ERROR_CAN_NOT_COMPLETE);
+ return FALSE;
+ }
+
+ /* Construct a region from the path and fill it */
+ if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgn))
+ {
+ /* Since PaintRgn interprets the region as being in logical coordinates
+ * but the points we store for the path are already in device
+ * coordinates, we have to set the mapping mode to MM_TEXT temporarily.
+ */
+
+ /* Save the information about the old mapping mode */
+ mapMode=GetMapMode32(hdc);
+ GetViewportExtEx32(hdc, &ptViewportExt);
+ GetViewportOrgEx32(hdc, &ptViewportOrg);
+ GetWindowExtEx32(hdc, &ptWindowExt);
+ GetWindowOrgEx32(hdc, &ptWindowOrg);
+
+ /* FIXME: Once world transforms become available, we will have to do
+ * a GetWorldTransform, too (along with a SetWorldTransform later on).
+ * Moral: Perhaps I should have used SaveDC right away. The reason why
+ * I didn't is that I wanted to avoid the overhead of a full SaveDC
+ * (especially since SaveDC now saves the current path as well).
+ */
+
+ /* Set MM_TEXT */
+ SetMapMode32(hdc, MM_TEXT);
+
+ /* Paint the region */
+ PaintRgn32(hdc, hrgn);
+
+ /* Restore the old mapping mode */
+ SetMapMode32(hdc, mapMode);
+ SetViewportExtEx32(hdc, ptViewportExt.x, ptViewportExt.y, NULL);
+ SetViewportOrgEx32(hdc, ptViewportOrg.x, ptViewportOrg.y, NULL);
+ SetWindowExtEx32(hdc, ptWindowExt.x, ptWindowExt.y, NULL);
+ SetWindowOrgEx32(hdc, ptWindowOrg.x, ptWindowOrg.y, NULL);
+
+ /* Empty the path */
+ PATH_EmptyPath(pPath);
+ return TRUE;
+ }
+ else
+ {
+ /* FIXME: Should the path be emptied even if conversion failed? */
+ /* PATH_EmptyPath(pPath); */
+ return FALSE;
+ }
+}
+
+
+/***********************************************************************
+ * SelectClipPath32 (GDI32.296)
+ */
+BOOL32 WINAPI SelectClipPath32(HDC32 hdc, int iMode)
+/* FIXME: Check that SetLastError is being called correctly */
+{
+ GdiPath *pPath;
+ HRGN32 hrgnPath, hrgnClip;
+ BOOL32 success = FALSE;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Check that path is closed */
+ if(pPath->state!=PATH_Closed)
+ {
+ SetLastError(ERROR_CAN_NOT_COMPLETE);
+ return FALSE;
+ }
+
+ /* Construct a region from the path */
+ if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath))
+ {
+ hrgnClip=CreateRectRgn32(0, 0, 0, 0);
+ if(hrgnClip!=NULL)
+ {
+ success=(GetClipRgn32(hdc, hrgnClip)!=-1) &&
+ (CombineRgn32(hrgnClip, hrgnClip, hrgnPath, iMode)!=ERROR) &&
+ (SelectClipRgn32(hdc, hrgnClip)!=ERROR);
+ DeleteObject32(hrgnClip);
+ }
+
+ DeleteObject32(hrgnPath);
+
+ /* Empty the path */
+ if(success)
+ PATH_EmptyPath(pPath);
+ /* FIXME: Should this function delete the path even if it failed? */
+
+ return success;
+ }
+ else
+ return FALSE;
+}
+
+
+/***********************************************************************
+ * Exported functions
+ */
+
+/* PATH_InitGdiPath
+ *
+ * Initializes the GdiPath structure.
+ */
+void PATH_InitGdiPath(GdiPath *pPath)
+{
+ assert(pPath!=NULL);
+
+ pPath->state=PATH_Null;
+ pPath->pPoints=NULL;
+ pPath->pFlags=NULL;
+ pPath->numEntriesUsed=0;
+ pPath->numEntriesAllocated=0;
+}
+
+/* PATH_DestroyGdiPath
+ *
+ * Destroys a GdiPath structure (frees the memory in the arrays).
+ */
+void PATH_DestroyGdiPath(GdiPath *pPath)
+{
+ assert(pPath!=NULL);
+
+ free(pPath->pPoints);
+ free(pPath->pFlags);
+}
+
+/* PATH_AssignGdiPath
+ *
+ * Copies the GdiPath structure "pPathSrc" to "pPathDest". A deep copy is
+ * performed, i.e. the contents of the pPoints and pFlags arrays are copied,
+ * not just the pointers. Since this means that the arrays in pPathDest may
+ * need to be resized, pPathDest should have been initialized using
+ * PATH_InitGdiPath (in C++, this function would be an assignment operator,
+ * not a copy constructor).
+ * Returns TRUE if successful, else FALSE.
+ */
+BOOL32 PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc)
+{
+ assert(pPathDest!=NULL && pPathSrc!=NULL);
+
+ /* Make sure destination arrays are big enough */
+ if(!PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed))
+ return FALSE;
+
+ /* Perform the copy operation */
+ memcpy(pPathDest->pPoints, pPathSrc->pPoints,
+ sizeof(POINT32)*pPathSrc->numEntriesUsed);
+ memcpy(pPathDest->pFlags, pPathSrc->pFlags,
+ sizeof(INT32)*pPathSrc->numEntriesUsed);
+ pPathDest->state=pPathSrc->state;
+ pPathDest->numEntriesUsed=pPathSrc->numEntriesUsed;
+ pPathDest->newStroke=pPathSrc->newStroke;
+
+ return TRUE;
+}
+
+/* PATH_MoveTo
+ *
+ * Should be called when a MoveTo is performed on a DC that has an
+ * open path. This starts a new stroke. Returns TRUE if successful, else
+ * FALSE.
+ */
+BOOL32 PATH_MoveTo(HDC32 hdc)
+{
+ GdiPath *pPath;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ return FALSE;
+
+ /* Check that path is open */
+ if(pPath->state!=PATH_Open)
+ /* FIXME: Do we have to call SetLastError? */
+ return FALSE;
+
+ /* Start a new stroke */
+ pPath->newStroke=TRUE;
+
+ return TRUE;
+}
+
+/* PATH_LineTo
+ *
+ * Should be called when a LineTo is performed on a DC that has an
+ * open path. This adds a PT_LINETO entry to the path (and possibly
+ * a PT_MOVETO entry, if this is the first LineTo in a stroke).
+ * Returns TRUE if successful, else FALSE.
+ */
+BOOL32 PATH_LineTo(HDC32 hdc, INT32 x, INT32 y)
+{
+ GdiPath *pPath;
+ POINT32 point, pointCurPos;
+
+ /* Get pointer to path */
+ if(!PATH_GetPathFromHDC(hdc, &pPath))
+ return FALSE;
+
+ /* Check that path is open */
+ if(pPath->state!=PATH_Open)
+ /* FIXME: Do we have to call SetLastError? */
+ return FALSE;
+
+ /* Convert point to device coordinates */
+ point.x=x;
+ point.y=y;
+ if(!LPtoDP32(hdc, &point, 1))
+ return FALSE;
+
+ /* Add a PT_MOVETO if necessary */
+ if(pPath->newStroke)
+ {
+ pPath->newStroke=FALSE;
+ if(!GetCurrentPositionEx32(hdc, &pointCurPos) ||
+ !LPtoDP32(hdc, &pointCurPos, 1))
+ return FALSE;
+ if(!PATH_AddEntry(pPath, pointCurPos, PT_MOVETO))
+ return FALSE;
+ }
+
+ /* Add a PT_LINETO entry */
+ return PATH_AddEntry(pPath, point, PT_LINETO);
+}
+
+
+/***********************************************************************
+ * Internal functions
+ */
+
+/* PATH_PathToRegion
+ *
+ * Creates a region from the specified path using the specified polygon
+ * filling mode. The path is left unchanged. A handle to the region that
+ * was created is stored in *pHrgn. If successful, TRUE is returned; if an
+ * error occurs, SetLastError is called with the appropriate value and
+ * FALSE is returned.
+ */
+static BOOL32 PATH_PathToRegion(const GdiPath *pPath, INT32 nPolyFillMode,
+ HRGN32 *pHrgn)
+{
+ int numStrokes, iStroke, i;
+ INT32 *pNumPointsInStroke;
+ HRGN32 hrgn;
+
+ assert(pPath!=NULL);
+ assert(pHrgn!=NULL);
+
+ /* FIXME: What happens when number of points is zero? */
+
+ /* First pass: Find out how many strokes there are in the path */
+ /* FIXME: We could eliminate this with some bookkeeping in GdiPath */
+ numStrokes=0;
+ for(i=0; i<pPath->numEntriesUsed; i++)
+ if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO)
+ numStrokes++;
+
+ /* Allocate memory for number-of-points-in-stroke array */
+ pNumPointsInStroke=(int *)malloc(sizeof(int)*numStrokes);
+ if(!pNumPointsInStroke)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ /* Second pass: remember number of points in each polygon */
+ iStroke=-1; /* Will get incremented to 0 at beginning of first stroke */
+ for(i=0; i<pPath->numEntriesUsed; i++)
+ {
+ /* Is this the beginning of a new stroke? */
+ if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO)
+ {
+ iStroke++;
+ pNumPointsInStroke[iStroke]=0;
+ }
+
+ pNumPointsInStroke[iStroke]++;
+ }
+
+ /* Create a region from the strokes */
+ hrgn=CreatePolyPolygonRgn32(pPath->pPoints, pNumPointsInStroke,
+ numStrokes, nPolyFillMode);
+ if(hrgn==NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ /* Free memory for number-of-points-in-stroke array */
+ free(pNumPointsInStroke);
+
+ /* Success! */
+ *pHrgn=hrgn;
+ return TRUE;
+}
+
+/* PATH_EmptyPath
+ *
+ * Removes all entries from the path and sets the path state to PATH_Null.
+ */
+static void PATH_EmptyPath(GdiPath *pPath)
+{
+ assert(pPath!=NULL);
+
+ pPath->state=PATH_Null;
+ pPath->numEntriesUsed=0;
+}
+
+/* PATH_AddEntry
+ *
+ * Adds an entry to the path. For "flags", pass either PT_MOVETO, PT_LINETO
+ * or PT_BEZIERTO, optionally ORed with PT_CLOSEFIGURE. Returns TRUE if
+ * successful, FALSE otherwise (e.g. if not enough memory was available).
+ */
+BOOL32 PATH_AddEntry(GdiPath *pPath, POINT32 point, BYTE flags)
+{
+ assert(pPath!=NULL);
+
+ /* Check that path is open */
+ if(pPath->state!=PATH_Open)
+ return FALSE;
+
+ /* Reserve enough memory for an extra path entry */
+ if(!PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1))
+ return FALSE;
+
+ /* Store information in path entry */
+ pPath->pPoints[pPath->numEntriesUsed]=point;
+ pPath->pFlags[pPath->numEntriesUsed]=flags;
+
+ /* Increment entry count */
+ pPath->numEntriesUsed++;
+
+ return TRUE;
+}
+
+/* PATH_ReserveEntries
+ *
+ * Ensures that at least "numEntries" entries (for points and flags) have
+ * been allocated; allocates larger arrays and copies the existing entries
+ * to those arrays, if necessary. Returns TRUE if successful, else FALSE.
+ */
+static BOOL32 PATH_ReserveEntries(GdiPath *pPath, INT32 numEntries)
+{
+ INT32 numEntriesToAllocate;
+ POINT32 *pPointsNew;
+ BYTE *pFlagsNew;
+
+ assert(pPath!=NULL);
+ assert(numEntries>=0);
+
+ /* Do we have to allocate more memory? */
+ if(numEntries > pPath->numEntriesAllocated)
+ {
+ /* Find number of entries to allocate. We let the size of the array
+ * grow exponentially, since that will guarantee linear time
+ * complexity. */
+ if(pPath->numEntriesAllocated)
+ {
+ numEntriesToAllocate=pPath->numEntriesAllocated;
+ while(numEntriesToAllocate<numEntries)
+ numEntriesToAllocate=numEntriesToAllocate*GROW_FACTOR_NUMER/
+ GROW_FACTOR_DENOM;
+ }
+ else
+ numEntriesToAllocate=NUM_ENTRIES_INITIAL;
+
+ /* Allocate new arrays */
+ pPointsNew=(POINT32 *)malloc(numEntriesToAllocate * sizeof(POINT32));
+ if(!pPointsNew)
+ return FALSE;
+ pFlagsNew=(BYTE *)malloc(numEntriesToAllocate * sizeof(BYTE));
+ if(!pFlagsNew)
+ {
+ free(pPointsNew);
+ return FALSE;
+ }
+
+ /* Copy old arrays to new arrays and discard old arrays */
+ if(pPath->pPoints)
+ {
+ assert(pPath->pFlags);
+
+ memcpy(pPointsNew, pPath->pPoints,
+ sizeof(POINT32)*pPath->numEntriesUsed);
+ memcpy(pFlagsNew, pPath->pFlags,
+ sizeof(BYTE)*pPath->numEntriesUsed);
+
+ free(pPath->pPoints);
+ free(pPath->pFlags);
+ }
+ pPath->pPoints=pPointsNew;
+ pPath->pFlags=pFlagsNew;
+ pPath->numEntriesAllocated=numEntriesToAllocate;
+ }
+
+ return TRUE;
+}
+
+/* PATH_GetPathFromHDC
+ *
+ * Retrieves a pointer to the GdiPath structure contained in an HDC and
+ * places it in *ppPath. TRUE is returned if successful, FALSE otherwise.
+ */
+static BOOL32 PATH_GetPathFromHDC(HDC32 hdc, GdiPath **ppPath)
+{
+ DC *pDC;
+
+ pDC=DC_GetDCPtr(hdc);
+ if(pDC)
+ {
+ *ppPath=&pDC->w.path;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
diff --git a/graphics/win16drv/graphics.c b/graphics/win16drv/graphics.c
index ec2a72e..2452542 100644
--- a/graphics/win16drv/graphics.c
+++ b/graphics/win16drv/graphics.c
@@ -4,8 +4,11 @@
* Copyright 1997 John Harvey
*/
+#include <stdio.h>
#include "heap.h"
#include "win16drv.h"
+#include "stddebug.h"
+#include "debug.h"
/**********************************************************************
* WIN16DRV_MoveToEx
@@ -57,9 +60,9 @@
WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
BOOL32 bRet = 0;
POINT16 points[2];
- printf("In WIN16drv_Rectangle, x %d y %d DCOrgX %d y %d\n",
+ dprintf_win16drv(stddeb, "In WIN16DRV_Rectangle, x %d y %d DCOrgX %d y %d\n",
left, top, dc->w.DCOrgX, dc->w.DCOrgY);
- printf("In WIN16drv_Rectangle, VPortOrgX %d y %d\n",
+ dprintf_win16drv(stddeb, "In WIN16DRV_Rectangle, VPortOrgX %d y %d\n",
dc->vportOrgX, dc->vportOrgY);
points[0].x = XLPTODP(dc, left);
points[0].y = YLPTODP(dc, top);
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 6281186..e00e638 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -386,8 +386,8 @@
return TRUE;
}
-extern BOOL32 WIN16DRV_PatBlt( struct tagDC *dc, INT32 left, INT32 top,
- INT32 width, INT32 height, DWORD rop )
+BOOL32 WIN16DRV_PatBlt( struct tagDC *dc, INT32 left, INT32 top,
+ INT32 width, INT32 height, DWORD rop )
{
WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
diff --git a/graphics/wing.c b/graphics/wing.c
index 58be554..f2b71dd 100644
--- a/graphics/wing.c
+++ b/graphics/wing.c
@@ -44,7 +44,7 @@
static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };
-static void __initWinG()
+static void __initWinG(void)
{
if( __WinGOK < 0 )
{
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index ec80312..9348d91 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -250,11 +250,14 @@
bottom -= (width + 1) / 2;
}
- if (DC_SetupGCForBrush( dc ))
- XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
- dc->w.DCOrgX + left + (width + 1) / 2,
- dc->w.DCOrgY + top + (width + 1) / 2,
- right-left-width-1, bottom-top-width-1);
+ if ((right > left + width) && (bottom > top + width))
+ {
+ if (DC_SetupGCForBrush( dc ))
+ XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+ dc->w.DCOrgX + left + (width + 1) / 2,
+ dc->w.DCOrgY + top + (width + 1) / 2,
+ right-left-width-1, bottom-top-width-1);
+ }
if (DC_SetupGCForPen( dc ))
XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + left, dc->w.DCOrgY + top,
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index 6cfd5a1..e415104 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -108,8 +108,6 @@
*/
BOOL32 X11DRV_Init(void)
{
- extern BOOL32 COLOR_Init();
-
/* FIXME: colormap management should be merged with the X11DRV */
if( !COLOR_Init() ) return FALSE;
diff --git a/graphics/x11drv/pen.c b/graphics/x11drv/pen.c
index 8516569..3a424cf 100644
--- a/graphics/x11drv/pen.c
+++ b/graphics/x11drv/pen.c
@@ -13,6 +13,7 @@
static const char PEN_dot[] = { 1,1 }; /* -- -- -- -- -- -- */
static const char PEN_dashdot[] = { 4,3,2,3 }; /* ---- -- ---- -- */
static const char PEN_dashdotdot[] = { 4,2,2,2,2,2 }; /* ---- -- -- ---- */
+static const char PEN_alternate[] = { 1,1 }; /* FIXME */
/***********************************************************************
* PEN_SelectObject
@@ -22,12 +23,15 @@
HPEN32 prevHandle = dc->w.hPen;
dc->w.hPen = hpen;
- dc->u.x.pen.style = pen->logpen.lopnStyle;
+ dc->u.x.pen.style = pen->logpen.lopnStyle & PS_STYLE_MASK;
+ dc->u.x.pen.endcap = pen->logpen.lopnStyle & PS_ENDCAP_MASK;
+ dc->u.x.pen.linejoin = pen->logpen.lopnStyle & PS_JOIN_MASK;
+
dc->u.x.pen.width = pen->logpen.lopnWidth.x * dc->vportExtX / dc->wndExtX;
if (dc->u.x.pen.width < 0) dc->u.x.pen.width = -dc->u.x.pen.width;
if (dc->u.x.pen.width == 1) dc->u.x.pen.width = 0; /* Faster */
dc->u.x.pen.pixel = COLOR_ToPhysical( dc, pen->logpen.lopnColor );
- switch(pen->logpen.lopnStyle)
+ switch(pen->logpen.lopnStyle & PS_STYLE_MASK)
{
case PS_DASH:
dc->u.x.pen.dashes = (char *)PEN_dash;
@@ -45,6 +49,14 @@
dc->u.x.pen.dashes = (char *)PEN_dashdotdot;
dc->u.x.pen.dash_len = 6;
break;
+ case PS_ALTERNATE:
+ /* FIXME: should be alternating _pixels_ that are set */
+ dc->u.x.pen.dashes = (char *)PEN_alternate;
+ dc->u.x.pen.dash_len = 2;
+ break;
+ case PS_USERSTYLE:
+ /* FIXME */
+ break;
}
return prevHandle;
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 9b988cf..be3bb66 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -170,13 +170,14 @@
return checksum;
}
-static UINT16 __genericCheckSum( UINT16* ptr, int size )
+static UINT16 __genericCheckSum( const void *ptr, int size )
{
- UINT16 checksum = 0;
- unsigned i;
+ unsigned int checksum = 0;
+ const char *p = (const char *)ptr;
+ while (size-- > 0)
+ checksum ^= (checksum << 3) + (checksum >> 29) + *p++;
- for( i = 0, size >>= 1; i < size; i++ ) checksum ^= *ptr++;
- return checksum;
+ return checksum & 0xffff;
}
/*************************************************************************
@@ -613,7 +614,7 @@
fi->df.dfExternalLeading = (INT16)el;
fi->df.dfPoints = (INT16)(((INT32)(fi->df.dfPixHeight -
- fi->df.dfInternalLeading) * 72) / fi->df.dfVertRes);
+ fi->df.dfInternalLeading) * 72 + (fi->df.dfVertRes >> 1)) / fi->df.dfVertRes);
if( xfs->min_bounds.width != xfs->max_bounds.width )
fi->df.dfPitchAndFamily |= TMPF_FIXED_PITCH; /* au contraire! */
@@ -831,25 +832,25 @@
}
for( up = 0; relocTable[up]; up++ )
- if( PROFILE_GetWineIniString( INIFontSection, relocTable[up], "", buffer, 128 ) )
- {
- while( *buffer && isspace(*buffer) ) buffer++;
- for( fr = NULL, pfr = fontList; pfr; pfr = pfr->next )
+ if( PROFILE_GetWineIniString( INIFontSection, relocTable[up], "", buffer, 128 ) )
{
- i = lstrlen32A( pfr->resource );
- if( !lstrncmpi32A( pfr->resource, buffer, i) )
- {
- if( fr )
- {
- fr->next = pfr->next;
- pfr->next = fontList;
- fontList = pfr;
- }
- break;
- }
- fr = pfr;
+ while( *buffer && isspace(*buffer) ) buffer++;
+ for( fr = NULL, pfr = fontList; pfr; pfr = pfr->next )
+ {
+ i = lstrlen32A( pfr->resource );
+ if( !lstrncmpi32A( pfr->resource, buffer, i) )
+ {
+ if( fr )
+ {
+ fr->next = pfr->next;
+ pfr->next = fontList;
+ fontList = pfr;
+ }
+ break;
+ }
+ fr = pfr;
+ }
}
- }
}
/***********************************************************************
@@ -1078,7 +1079,7 @@
pfi->df.dfFace = pfr->lfFaceName;
pfi->df.dfHorizRes = pfi->df.dfVertRes = res;
pfi->df.dfPoints = (INT16)(((INT32)(pfi->df.dfPixHeight -
- pfi->df.dfInternalLeading) * 72) / res );
+ pfi->df.dfInternalLeading) * 72 + (res >> 1)) / res );
pfi->next = pfi + 1;
if( j > pfr->count ) break;
@@ -1244,9 +1245,10 @@
/* Make sure this is a valid key */
if((strncasecmp(key, INISubSection, 5) == 0) ||
- (strcasecmp(key, INIDefault) == 0) ||
- (strcasecmp(key, INIGlobalMetrics) == 0) ||
- (strcasecmp(key, INIResolution) == 0) )
+ (strcasecmp( key, INIDefault) == 0) ||
+ (strcasecmp( key, INIDefaultFixed) == 0) ||
+ (strcasecmp( key, INIGlobalMetrics) == 0) ||
+ (strcasecmp( key, INIResolution) == 0) )
{
/* Valid key; make sure the value doesn't contain a wildcard */
if(strchr(value, '*')) {
@@ -1331,7 +1333,7 @@
#endif
j = lstrlen32A( x_pattern[i] );
- if( j ) x_checksum ^= __genericCheckSum( (UINT16*)(x_pattern[i]), j );
+ if( j ) x_checksum ^= __genericCheckSum( x_pattern[i], j );
}
x_checksum |= X_PFONT_MAGIC;
@@ -1557,7 +1559,8 @@
if( plf->lfCharSet == DEFAULT_CHARSET )
{
- if( (pfi->df.dfCharSet!= ANSI_CHARSET) && (pfi->df.dfCharSet!=DEFAULT_CHARSET) ) penalty += 0x200;
+ if( (pfi->df.dfCharSet!= ANSI_CHARSET) && (pfi->df.dfCharSet!=DEFAULT_CHARSET) )
+ penalty += 0x200;
}
else if (plf->lfCharSet != pfi->df.dfCharSet) penalty += 0x200;
@@ -1650,9 +1653,11 @@
{
BOOL32 skipRaster = (pfm->flags & FO_MATCH_NORASTER);
UINT32 current_score, score = (UINT32)(-1);
+ UINT16 origflags = pfm->flags; /* Preserve FO_MATCH_XYINDEP */
fontMatch fm = *pfm;
- for( fm.pfi = pfm->pfr->fi; fm.pfi && score; fm.pfi = fm.pfi->next )
+ for( fm.pfi = pfm->pfr->fi; fm.pfi && score; fm.pfi = fm.pfi->next,
+ fm.flags = origflags )
{
if( skipRaster && !(fm.pfi->fi_flags & FI_SCALABLE) )
continue;
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index 63fb303..26e1e7a 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -6,56 +6,39 @@
MODULE = if1632
DLLS = \
- advapi32.spec \
- comctl32.spec \
- comdlg32.spec \
commdlg.spec \
compobj.spec \
- crtdll.spec \
ddeml.spec \
gdi.spec \
- gdi32.spec \
kernel.spec \
- kernel32.spec \
keyboard.spec \
- lz32.spec \
lzexpand.spec \
mmsystem.spec \
mouse.spec \
- mpr.spec \
- ntdll.spec \
ole2.spec \
ole2conv.spec \
ole2disp.spec \
ole2nls.spec \
ole2prox.spec \
- ole32.spec \
+ ole2thk.spec \
olecli.spec \
- olecli32.spec \
olesvr.spec \
- olesvr32.spec \
shell.spec \
- shell32.spec \
sound.spec \
storage.spec \
stress.spec \
system.spec \
toolhelp.spec \
user.spec \
- user32.spec \
ver.spec \
- version.spec \
- w32skrnl.spec \
w32sys.spec \
win32s16.spec \
win87em.spec \
winaspi.spec \
+ windebug.spec \
wing.spec \
- winmm.spec \
winsock.spec \
- winspool.spec \
- wprocs.spec \
- wsock32.spec
+ wprocs.spec
SPEC_FILES = $(DLLS:.spec=.s)
@@ -68,7 +51,6 @@
GEN_ASM_SRCS = \
$(SPEC_FILES) \
- call32.s \
callfrom16.s \
callto16.s
@@ -86,9 +68,6 @@
callfrom16.s: $(SPEC_FILES)
$(BUILD) -o $@ -callfrom16 `cat $(SPEC_FILES) | grep CallFrom16_ | sed 's/.*CallFrom16_\(.*\)/\1/' | sort | uniq`
-call32.s: $(BUILD)
- $(BUILD) -o $@ -call32
-
callto16.s: $(SRCDIR)/thunk.c $(BUILD)
$(BUILD) -o $@ -callto16 $(SRCDIR)/thunk.c
diff --git a/if1632/builtin.c b/if1632/builtin.c
index f514004..273908a 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -8,6 +8,7 @@
#include <ctype.h>
#include <string.h>
#include "windows.h"
+#include "builtin32.h"
#include "gdi.h"
#include "global.h"
#include "heap.h"
@@ -34,158 +35,89 @@
typedef struct
{
- const char *name; /* DLL name */
- int base; /* Ordinal base */
- int nb_funcs; /* Number of functions */
- int nb_names; /* Number of function names */
- const void **functions; /* Pointer to function table */
- const char * const *names; /* Pointer to names table */
- const WORD *ordinals; /* Pointer to ordinals table */
- const BYTE *args; /* Pointer to argument lengths */
- const DWORD *argtypes; /* Pointer to argument types bitmask */
-} WIN32_DESCRIPTOR;
-
-typedef union
-{
- const char *name; /* DLL name */
- WIN16_DESCRIPTOR win16; /* Descriptor for Win16 DLL */
- WIN32_DESCRIPTOR win32; /* Descriptor for Win32 DLL */
-} DLL_DESCRIPTOR;
-
-typedef struct
-{
- BYTE call; /* 0xe8 call callfrom32 (relative) */
- DWORD callfrom32 WINE_PACKED; /* RELAY_CallFrom32 relative addr */
- BYTE ret; /* 0xc2 ret $n or 0xc3 ret */
- WORD args; /* nb of args to remove from the stack */
-} DEBUG_ENTRY_POINT;
-
-typedef struct
-{
- const DLL_DESCRIPTOR *descr; /* DLL descriptor */
- DEBUG_ENTRY_POINT *dbg_funcs; /* Relay debugging functions table */
- int flags; /* flags (see below) */
-} BUILTIN_DLL;
+ const WIN16_DESCRIPTOR *descr; /* DLL descriptor */
+ int flags; /* flags (see below) */
+} BUILTIN16_DLL;
/* DLL flags */
#define DLL_FLAG_NOT_USED 0x01 /* Use original Windows DLL if possible */
#define DLL_FLAG_ALWAYS_USED 0x02 /* Always use built-in DLL */
-#define DLL_FLAG_WIN32 0x04 /* DLL is a Win32 DLL */
/* 16-bit DLLs */
-extern const DLL_DESCRIPTOR KERNEL_Descriptor;
-extern const DLL_DESCRIPTOR USER_Descriptor;
-extern const DLL_DESCRIPTOR GDI_Descriptor;
-extern const DLL_DESCRIPTOR WIN87EM_Descriptor;
-extern const DLL_DESCRIPTOR MMSYSTEM_Descriptor;
-extern const DLL_DESCRIPTOR SHELL_Descriptor;
-extern const DLL_DESCRIPTOR SOUND_Descriptor;
-extern const DLL_DESCRIPTOR KEYBOARD_Descriptor;
-extern const DLL_DESCRIPTOR WINSOCK_Descriptor;
-extern const DLL_DESCRIPTOR STRESS_Descriptor;
-extern const DLL_DESCRIPTOR SYSTEM_Descriptor;
-extern const DLL_DESCRIPTOR TOOLHELP_Descriptor;
-extern const DLL_DESCRIPTOR MOUSE_Descriptor;
-extern const DLL_DESCRIPTOR COMMDLG_Descriptor;
-extern const DLL_DESCRIPTOR OLE2_Descriptor;
-extern const DLL_DESCRIPTOR OLE2CONV_Descriptor;
-extern const DLL_DESCRIPTOR OLE2DISP_Descriptor;
-extern const DLL_DESCRIPTOR OLE2NLS_Descriptor;
-extern const DLL_DESCRIPTOR OLE2PROX_Descriptor;
-extern const DLL_DESCRIPTOR OLECLI_Descriptor;
-extern const DLL_DESCRIPTOR OLESVR_Descriptor;
-extern const DLL_DESCRIPTOR COMPOBJ_Descriptor;
-extern const DLL_DESCRIPTOR STORAGE_Descriptor;
-extern const DLL_DESCRIPTOR WPROCS_Descriptor;
-extern const DLL_DESCRIPTOR DDEML_Descriptor;
-extern const DLL_DESCRIPTOR LZEXPAND_Descriptor;
-extern const DLL_DESCRIPTOR VER_Descriptor;
-extern const DLL_DESCRIPTOR W32SYS_Descriptor;
-extern const DLL_DESCRIPTOR WIN32S16_Descriptor;
-extern const DLL_DESCRIPTOR WING_Descriptor;
-extern const DLL_DESCRIPTOR WINASPI_Descriptor;
-
-/* 32-bit DLLs */
-
-extern const DLL_DESCRIPTOR ADVAPI32_Descriptor;
-extern const DLL_DESCRIPTOR COMCTL32_Descriptor;
-extern const DLL_DESCRIPTOR COMDLG32_Descriptor;
-extern const DLL_DESCRIPTOR CRTDLL_Descriptor;
-extern const DLL_DESCRIPTOR GDI32_Descriptor;
-extern const DLL_DESCRIPTOR KERNEL32_Descriptor;
-extern const DLL_DESCRIPTOR LZ32_Descriptor;
-extern const DLL_DESCRIPTOR MPR_Descriptor;
-extern const DLL_DESCRIPTOR NTDLL_Descriptor;
-extern const DLL_DESCRIPTOR OLE32_Descriptor;
-extern const DLL_DESCRIPTOR OLECLI32_Descriptor;
-extern const DLL_DESCRIPTOR OLESVR32_Descriptor;
-extern const DLL_DESCRIPTOR SHELL32_Descriptor;
-extern const DLL_DESCRIPTOR USER32_Descriptor;
-extern const DLL_DESCRIPTOR VERSION_Descriptor;
-extern const DLL_DESCRIPTOR W32SKRNL_Descriptor;
-extern const DLL_DESCRIPTOR WINMM_Descriptor;
-extern const DLL_DESCRIPTOR WINSPOOL_Descriptor;
-extern const DLL_DESCRIPTOR WSOCK32_Descriptor;
+extern const WIN16_DESCRIPTOR COMMDLG_Descriptor;
+extern const WIN16_DESCRIPTOR COMPOBJ_Descriptor;
+extern const WIN16_DESCRIPTOR DDEML_Descriptor;
+extern const WIN16_DESCRIPTOR GDI_Descriptor;
+extern const WIN16_DESCRIPTOR KERNEL_Descriptor;
+extern const WIN16_DESCRIPTOR KEYBOARD_Descriptor;
+extern const WIN16_DESCRIPTOR LZEXPAND_Descriptor;
+extern const WIN16_DESCRIPTOR MMSYSTEM_Descriptor;
+extern const WIN16_DESCRIPTOR MOUSE_Descriptor;
+extern const WIN16_DESCRIPTOR OLE2CONV_Descriptor;
+extern const WIN16_DESCRIPTOR OLE2DISP_Descriptor;
+extern const WIN16_DESCRIPTOR OLE2NLS_Descriptor;
+extern const WIN16_DESCRIPTOR OLE2PROX_Descriptor;
+extern const WIN16_DESCRIPTOR OLE2THK_Descriptor;
+extern const WIN16_DESCRIPTOR OLE2_Descriptor;
+extern const WIN16_DESCRIPTOR OLECLI_Descriptor;
+extern const WIN16_DESCRIPTOR OLESVR_Descriptor;
+extern const WIN16_DESCRIPTOR SHELL_Descriptor;
+extern const WIN16_DESCRIPTOR SOUND_Descriptor;
+extern const WIN16_DESCRIPTOR STORAGE_Descriptor;
+extern const WIN16_DESCRIPTOR STRESS_Descriptor;
+extern const WIN16_DESCRIPTOR SYSTEM_Descriptor;
+extern const WIN16_DESCRIPTOR TOOLHELP_Descriptor;
+extern const WIN16_DESCRIPTOR USER_Descriptor;
+extern const WIN16_DESCRIPTOR VER_Descriptor;
+extern const WIN16_DESCRIPTOR W32SYS_Descriptor;
+extern const WIN16_DESCRIPTOR WIN32S16_Descriptor;
+extern const WIN16_DESCRIPTOR WIN87EM_Descriptor;
+extern const WIN16_DESCRIPTOR WINASPI_Descriptor;
+extern const WIN16_DESCRIPTOR WINDEBUG_Descriptor;
+extern const WIN16_DESCRIPTOR WING_Descriptor;
+extern const WIN16_DESCRIPTOR WINSOCK_Descriptor;
+extern const WIN16_DESCRIPTOR WPROCS_Descriptor;
/* Table of all built-in DLLs */
-static BUILTIN_DLL BuiltinDLLs[] =
+static BUILTIN16_DLL BuiltinDLLs[] =
{
- /* Win16 DLLs */
- { &KERNEL_Descriptor, NULL, DLL_FLAG_ALWAYS_USED },
- { &USER_Descriptor, NULL, DLL_FLAG_ALWAYS_USED },
- { &GDI_Descriptor, NULL, DLL_FLAG_ALWAYS_USED },
- { &SYSTEM_Descriptor, NULL, DLL_FLAG_ALWAYS_USED },
- { &WIN87EM_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &SHELL_Descriptor, NULL, 0 },
- { &SOUND_Descriptor, NULL, 0 },
- { &KEYBOARD_Descriptor, NULL, 0 },
- { &WINSOCK_Descriptor, NULL, 0 },
- { &STRESS_Descriptor, NULL, 0 },
- { &MMSYSTEM_Descriptor, NULL, 0 },
- { &TOOLHELP_Descriptor, NULL, 0 },
- { &MOUSE_Descriptor, NULL, 0 },
- { &COMMDLG_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &OLE2_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &OLE2CONV_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &OLE2DISP_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &OLE2NLS_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &OLE2PROX_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &OLECLI_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &OLESVR_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &COMPOBJ_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &STORAGE_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &WPROCS_Descriptor, NULL, DLL_FLAG_ALWAYS_USED },
- { &DDEML_Descriptor, NULL, DLL_FLAG_NOT_USED },
- { &LZEXPAND_Descriptor, NULL, 0 },
- { &VER_Descriptor, NULL, 0 },
- { &W32SYS_Descriptor, NULL, 0 },
- { &WIN32S16_Descriptor, NULL, 0 },
- { &WING_Descriptor, NULL, 0 },
- { &WINASPI_Descriptor, NULL, 0 },
- /* Win32 DLLs */
- { &ADVAPI32_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &COMCTL32_Descriptor, NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
- { &COMDLG32_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &CRTDLL_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &GDI32_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &KERNEL32_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &LZ32_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &MPR_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &NTDLL_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &OLE32_Descriptor, NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
- { &OLECLI32_Descriptor, NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
- { &OLESVR32_Descriptor, NULL, DLL_FLAG_WIN32 | DLL_FLAG_NOT_USED },
- { &SHELL32_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &USER32_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &VERSION_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &W32SKRNL_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &WINMM_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &WINSPOOL_Descriptor, NULL, DLL_FLAG_WIN32 },
- { &WSOCK32_Descriptor, NULL, DLL_FLAG_WIN32 },
+ { &KERNEL_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &USER_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &GDI_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &SYSTEM_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &WPROCS_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &WINDEBUG_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &COMMDLG_Descriptor, DLL_FLAG_NOT_USED },
+ { &COMPOBJ_Descriptor, DLL_FLAG_NOT_USED },
+ { &DDEML_Descriptor, DLL_FLAG_NOT_USED },
+ { &KEYBOARD_Descriptor, 0 },
+ { &LZEXPAND_Descriptor, 0 },
+ { &MMSYSTEM_Descriptor, 0 },
+ { &MOUSE_Descriptor, 0 },
+ { &OLE2CONV_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2DISP_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2NLS_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2PROX_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2THK_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLECLI_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLESVR_Descriptor, DLL_FLAG_NOT_USED },
+ { &SHELL_Descriptor, 0 },
+ { &SOUND_Descriptor, 0 },
+ { &STORAGE_Descriptor, DLL_FLAG_NOT_USED },
+ { &STRESS_Descriptor, 0 },
+ { &TOOLHELP_Descriptor, 0 },
+ { &VER_Descriptor, 0 },
+ { &W32SYS_Descriptor, 0 },
+ { &WIN32S16_Descriptor, 0 },
+ { &WIN87EM_Descriptor, DLL_FLAG_NOT_USED },
+ { &WINASPI_Descriptor, 0 },
+ { &WING_Descriptor, 0 },
+ { &WINSOCK_Descriptor, 0 },
/* Last entry */
- { NULL, NULL, 0 }
+ { NULL, 0 }
};
/* Ordinal number for interrupt 0 handler in WPROCS.DLL */
@@ -243,210 +175,21 @@
/***********************************************************************
- * BUILTIN_DoLoadModule32
- *
- * Load a built-in Win32 module. Helper function for BUILTIN_LoadModule
- * and BUILTIN_Init.
- */
-static HMODULE32 BUILTIN_DoLoadModule32( BUILTIN_DLL *dll )
-{
- extern void RELAY_CallFrom32();
-
- HMODULE16 hModule;
- NE_MODULE *pModule;
- OFSTRUCT ofs;
- IMAGE_DATA_DIRECTORY *dir;
- IMAGE_DOS_HEADER *dos;
- IMAGE_NT_HEADERS *nt;
- IMAGE_SECTION_HEADER *sec;
- IMAGE_EXPORT_DIRECTORY *exp;
- LPVOID *funcs;
- LPSTR *names;
- DEBUG_ENTRY_POINT *entry;
- PE_MODREF *pem;
- INT32 i, size;
- BYTE *addr;
-
- /* Allocate the module */
-
- size = (sizeof(IMAGE_DOS_HEADER)
- + sizeof(IMAGE_NT_HEADERS)
- + 2 * sizeof(IMAGE_SECTION_HEADER)
- + sizeof(IMAGE_EXPORT_DIRECTORY)
- + dll->descr->win32.nb_funcs * sizeof(LPVOID)
- + dll->descr->win32.nb_names * sizeof(LPSTR));
- if (debugging_relay)
- size += dll->descr->win32.nb_funcs * sizeof(DEBUG_ENTRY_POINT);
- addr = VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
- if (!addr) return 0;
- dos = (IMAGE_DOS_HEADER *)addr;
- nt = (IMAGE_NT_HEADERS *)(dos + 1);
- sec = (IMAGE_SECTION_HEADER *)(nt + 1);
- exp = (IMAGE_EXPORT_DIRECTORY *)(sec + 2);
- funcs = (LPVOID *)(exp + 1);
- names = (LPSTR *)(funcs + dll->descr->win32.nb_funcs);
- entry = (DEBUG_ENTRY_POINT *)(names + dll->descr->win32.nb_names);
-
- /* Build the DOS and NT headers */
-
- dos->e_magic = IMAGE_DOS_SIGNATURE;
- dos->e_lfanew = sizeof(*dos);
-
- nt->Signature = IMAGE_NT_SIGNATURE;
- nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
- nt->FileHeader.NumberOfSections = 2; /* exports + code */
- nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader);
- nt->FileHeader.Characteristics = IMAGE_FILE_DLL;
-
- nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
- nt->OptionalHeader.SizeOfCode = 0x1000;
- nt->OptionalHeader.SizeOfInitializedData = 0;
- nt->OptionalHeader.SizeOfUninitializedData = 0;
- nt->OptionalHeader.ImageBase = (DWORD)addr;
- nt->OptionalHeader.SectionAlignment = 0x1000;
- nt->OptionalHeader.FileAlignment = 0x1000;
- nt->OptionalHeader.MajorOperatingSystemVersion = 1;
- nt->OptionalHeader.MinorOperatingSystemVersion = 0;
- nt->OptionalHeader.MajorSubsystemVersion = 4;
- nt->OptionalHeader.MinorSubsystemVersion = 0;
- nt->OptionalHeader.SizeOfImage = size;
- nt->OptionalHeader.SizeOfHeaders = (BYTE *)exp - addr;
- nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
-
- /* Build the export directory */
-
- dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
- dir->VirtualAddress = (BYTE *)exp - addr;
- dir->Size = sizeof(*exp)
- + dll->descr->win32.nb_funcs * sizeof(LPVOID)
- + dll->descr->win32.nb_names * sizeof(LPSTR);
-
- /* Build the exports section */
-
- strcpy( sec->Name, ".edata" );
- sec->Misc.VirtualSize = dir->Size;
- sec->VirtualAddress = (BYTE *)exp - addr;
- sec->SizeOfRawData = dir->Size;
- sec->PointerToRawData = (BYTE *)exp - addr;
- sec->Characteristics = (IMAGE_SCN_CNT_INITIALIZED_DATA |
- IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
- IMAGE_SCN_MEM_WRITE);
-
- /* Build the code section */
-
- sec++;
- strcpy( sec->Name, ".code" );
- if (debugging_relay)
- sec->SizeOfRawData = dll->descr->win32.nb_funcs * sizeof(DEBUG_ENTRY_POINT);
- else
- sec->SizeOfRawData = 1;
- sec->Misc.VirtualSize = sec->SizeOfRawData;
- sec->VirtualAddress = (BYTE *)entry - addr;
- sec->PointerToRawData = (BYTE *)entry - addr;
- sec->Characteristics = (IMAGE_SCN_CNT_INITIALIZED_DATA |
- IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ);
-
- /* Build the exports section data */
-
- exp->Name = (BYTE *)dll->descr->name - addr; /*??*/
- exp->Base = dll->descr->win32.base;
- exp->NumberOfFunctions = dll->descr->win32.nb_funcs;
- exp->NumberOfNames = dll->descr->win32.nb_names;
- exp->AddressOfFunctions = (LPDWORD *)((BYTE *)funcs - addr);
- exp->AddressOfNames = (LPDWORD *)((BYTE *)names - addr);
- exp->AddressOfNameOrdinals = (LPWORD *)((BYTE *)dll->descr->win32.ordinals - addr);
-
- /* Build the funcs table */
-
- if (debugging_relay)
- {
- dll->dbg_funcs = entry;
- for (i = 0; i < dll->descr->win32.nb_funcs; i++, funcs++, entry++)
- {
- BYTE args = dll->descr->win32.args[i];
- entry->call = 0xe8; /* call */
- switch(args)
- {
- case 0xfe: /* register func */
- entry->callfrom32 = (DWORD)dll->descr->win32.functions[i] -
- (DWORD)&entry->ret;
- entry->ret = 0x90; /* nop */
- entry->args = 0;
- *funcs = (LPVOID)((BYTE *)entry - addr);
- break;
- case 0xff: /* stub or extern */
- if (dll->descr->win32.functions[i])
- *funcs = (LPVOID)((BYTE *)dll->descr->win32.functions[i]
- - addr);
- break;
- default: /* normal function (stdcall or cdecl) */
- entry->callfrom32 = (DWORD)RELAY_CallFrom32 -
- (DWORD)&entry->ret;
- entry->ret = (args & 0x80) ? 0xc3 : 0xc2; /*ret/ret $n*/
- entry->args = (args & 0x7f) * sizeof(int);
- *funcs = (LPVOID)((BYTE *)entry - addr);
- break;
- }
- }
- }
- else
- {
- for (i = 0; i < dll->descr->win32.nb_funcs; i++, funcs++)
- if (dll->descr->win32.functions[i])
- *funcs = (LPVOID)((BYTE *)dll->descr->win32.functions[i]
- - addr);
- }
-
- /* Build the names table */
-
- for (i = 0; i < exp->NumberOfNames; i++, names++)
- if (dll->descr->win32.names[i])
- *names = (LPSTR)((BYTE *)dll->descr->win32.names[i] - addr);
-
- /* Create a modref */
-
- pem = (PE_MODREF *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(*pem) );
- pem->module = (HMODULE32)addr;
- pem->pe_export = exp;
- pem->next = pCurrentProcess->modref_list;
- pCurrentProcess->modref_list = pem;
-
- /* Create a Win16 dummy module */
-
- sprintf( ofs.szPathName, "%s.DLL", dll->descr->name );
- hModule = MODULE_CreateDummyModule( &ofs );
- pModule = (NE_MODULE *)GlobalLock16( hModule );
- pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN |
- NE_FFLAGS_LIBMODULE | NE_FFLAGS_WIN32;
- pModule->module32 = (HMODULE32)addr;
- return pModule->module32;
-}
-
-
-/***********************************************************************
* BUILTIN_Init
*
* Load all built-in modules marked as 'always used'.
*/
BOOL32 BUILTIN_Init(void)
{
- BUILTIN_DLL *dll;
+ BUILTIN16_DLL *dll;
NE_MODULE *pModule;
WORD vector;
HMODULE16 hModule;
for (dll = BuiltinDLLs; dll->descr; dll++)
{
- if (!(dll->flags & DLL_FLAG_ALWAYS_USED)) continue;
- if (dll->flags & DLL_FLAG_WIN32)
- {
- if (!BUILTIN_DoLoadModule32( dll )) return FALSE;
- }
- else
- {
- if (!BUILTIN_DoLoadModule16( &dll->descr->win16 )) return FALSE;
- }
+ if (dll->flags & DLL_FLAG_ALWAYS_USED)
+ if (!BUILTIN_DoLoadModule16( dll->descr )) return FALSE;
}
/* Set the USER and GDI heap selectors */
@@ -488,7 +231,7 @@
*/
HMODULE32 BUILTIN_LoadModule( LPCSTR name, BOOL32 force )
{
- BUILTIN_DLL *table;
+ BUILTIN16_DLL *table;
char dllname[16], *p;
/* Fix the name in case we have a full path and extension */
@@ -499,13 +242,10 @@
for (table = BuiltinDLLs; table->descr; table++)
if (!lstrcmpi32A( table->descr->name, dllname )) break;
- if (!table->descr) return 0;
+ if (!table->descr) return BUILTIN32_LoadModule( name, force );
if ((table->flags & DLL_FLAG_NOT_USED) && !force) return 0;
- if (table->flags & DLL_FLAG_WIN32)
- return BUILTIN_DoLoadModule32( table );
- else
- return BUILTIN_DoLoadModule16( &table->descr->win16 );
+ return BUILTIN_DoLoadModule16( table->descr );
}
@@ -584,45 +324,6 @@
}
-/***********************************************************************
- * BUILTIN_GetEntryPoint32
- *
- * Return the name of the DLL entry point corresponding
- * to a relay entry point address. This is used only by relay debugging.
- *
- * This function _must_ return the real entry point to call
- * after the debug info is printed.
- */
-FARPROC32 BUILTIN_GetEntryPoint32( char *buffer, void *relay, DWORD *typemask )
-{
- BUILTIN_DLL *dll;
- int ordinal, i;
- const WIN32_DESCRIPTOR *descr;
-
- /* First find the module */
-
- for (dll = BuiltinDLLs; dll->descr; dll++)
- if ((dll->flags & DLL_FLAG_WIN32) &&
- ((void *)dll->dbg_funcs <= relay) &&
- ((void *)(dll->dbg_funcs + dll->descr->win32.nb_funcs) > relay))
- break;
- assert(dll->descr);
- descr = &dll->descr->win32;
-
- /* Now find the function */
-
- ordinal = ((DWORD)relay-(DWORD)dll->dbg_funcs) / sizeof(DEBUG_ENTRY_POINT);
- for (i = 0; i < descr->nb_names; i++)
- if (descr->ordinals[i] == ordinal) break;
- assert( i < descr->nb_names );
-
- sprintf( buffer, "%s.%d: %s", descr->name, ordinal + descr->base,
- descr->names[i] );
- *typemask = descr->argtypes[ordinal];
- return (FARPROC32)descr->functions[ordinal];
-}
-
-
/**********************************************************************
* BUILTIN_DefaultIntHandler
*
@@ -644,7 +345,7 @@
*/
BOOL32 BUILTIN_ParseDLLOptions( const char *str )
{
- BUILTIN_DLL *dll;
+ BUILTIN16_DLL *dll;
const char *p;
while (*str)
@@ -685,7 +386,7 @@
void BUILTIN_PrintDLLs(void)
{
int i;
- BUILTIN_DLL *dll;
+ BUILTIN16_DLL *dll;
fprintf(stderr,"Example: -dll -ole2 Do not use emulated OLE2.DLL\n");
fprintf(stderr,"Available DLLs:\n");
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index c7fa8da..db1dae2 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -213,16 +213,16 @@
213 stub KERNEL_213
214 stub KERNEL_214
216 pascal RegEnumKey(long long ptr long) RegEnumKey16
-217 pascal RegOpenKey(long ptr ptr) RegOpenKey16
-218 pascal RegCreateKey(long ptr ptr) RegCreateKey16
-219 pascal RegDeleteKey(long ptr) RegDeleteKey16
+217 pascal RegOpenKey(long str ptr) RegOpenKey16
+218 pascal RegCreateKey(long str ptr) RegCreateKey16
+219 pascal RegDeleteKey(long str) RegDeleteKey16
220 pascal RegCloseKey(long) RegCloseKey
-221 pascal RegSetValue(long ptr long ptr long) RegSetValue16
-222 pascal RegDeleteValue(long ptr) RegDeleteValue16
+221 pascal RegSetValue(long str long ptr long) RegSetValue16
+222 pascal RegDeleteValue(long str) RegDeleteValue16
223 pascal RegEnumValue(long long ptr ptr ptr ptr ptr ptr) RegEnumValue16
-224 pascal RegQueryValue(long ptr ptr ptr) RegQueryValue16
-225 pascal RegQueryValueEx(long ptr ptr ptr ptr ptr) RegQueryValueEx16
-226 pascal RegSetValueEx(long ptr long long ptr long) RegSetValueEx16
+224 pascal RegQueryValue(long str ptr ptr) RegQueryValue16
+225 pascal RegQueryValueEx(long str ptr ptr ptr ptr) RegQueryValueEx16
+226 pascal RegSetValueEx(long str long long ptr long) RegSetValueEx16
227 pascal RegFlushKey(long) RegFlushKey
228 stub K228
229 stub K229
@@ -298,7 +298,7 @@
420 pascal GetFileAttributes(ptr) GetFileAttributes16
421 pascal16 SetFileAttributes(ptr long) SetFileAttributes16
422 pascal16 GetDiskFreeSpace(ptr ptr ptr ptr ptr) GetDiskFreeSpace16
-431 stub KERNEL_431
+431 pascal16 KERNEL_431(str word) KERNEL_431
432 stub FileTimeToLocalFileTime
435 stub KERNEL_435
439 stub KERNEL_439
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index c0178e1..cd9889a 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -12,14 +12,14 @@
32 stub STACKENTER
33 stub STACKLEAVE
34 stub MMDRVINSTALL
-101 pascal JOYGETNUMDEVS() JoyGetNumDevs
-102 pascal JOYGETDEVCAPS(word ptr word) JoyGetDevCaps
-103 pascal JOYGETPOS(word ptr) JoyGetPos
-104 pascal JOYGETTHRESHOLD(word ptr) JoyGetThreshold
-105 pascal JOYRELEASECAPTURE(word) JoyReleaseCapture
-106 pascal JOYSETCAPTURE(word word word word) JoySetCapture
-107 pascal JOYSETTHRESHOLD(word word) JoySetThreshold
-109 pascal JOYSETCALIBRATION(word) JoySetCalibration
+101 pascal joyGetNumDevs() joyGetNumDevs16
+102 pascal joyGetDevCaps(word ptr word) joyGetDevCaps16
+103 pascal joyGetPos(word ptr) joyGetPos16
+104 pascal joyGetThreshold(word ptr) joyGetThreshold16
+105 pascal joyReleaseCapture(word) joyReleaseCapture16
+106 pascal joySetCapture(word word word word) joySetCapture16
+107 pascal joySetThreshold(word word) joySetThreshold16
+109 pascal joySetCalibration(word) joySetCalibration16
110 stub JOYGETPOSEX
111 stub JOYCONFIGCHANGED
201 pascal midiOutGetNumDevs() midiOutGetNumDevs16
@@ -99,20 +99,20 @@
512 pascal waveInGetPosition(word ptr word) waveInGetPosition16
513 pascal waveInGetID(word ptr) waveInGetID16
514 pascal waveInMessage(word word long long) waveInMessage16
-601 pascal timeGetSystemTime(ptr word) timeGetSystemTime
-602 pascal timeSetEvent(word word segptr long word) timeSetEvent
-603 pascal timeKillEvent(word) timeKillEvent
-604 pascal timeGetDevCaps(ptr word) timeGetDevCaps
-605 pascal timeBeginPeriod(word) timeBeginPeriod
-606 pascal timeEndPeriod(word) timeEndPeriod
+601 pascal timeGetSystemTime(ptr word) timeGetSystemTime16
+602 pascal timeSetEvent(word word segptr long word) timeSetEvent16
+603 pascal timeKillEvent(word) timeKillEvent16
+604 pascal timeGetDevCaps(ptr word) timeGetDevCaps16
+605 pascal timeBeginPeriod(word) timeBeginPeriod16
+606 pascal timeEndPeriod(word) timeEndPeriod16
607 pascal timeGetTime() timeGetTime
701 pascal MCISENDCOMMAND(word word long long) mciSendCommand
702 pascal MCISENDSTRING(str ptr word word) mciSendString
-703 pascal MCIGETDEVICEID(ptr) mciGetDeviceID
-705 stub MCILOADCOMMANDRESOURCE
+703 pascal mciGetDeviceID(ptr) mciGetDeviceID
+705 pascal mciLoadCommandResource(word str word) mciLoadCommandResource16
706 pascal mciGetErrorString(long ptr word) mciGetErrorString16
-707 stub MCISETDRIVERDATA
-708 stub MCIGETDRIVERDATA
+707 pascal mciSetDriverData(word long) mciSetDriverData16
+708 pascal mciGetDriverData(word) mciGetDriverData16
710 stub MCIDRIVERYIELD
711 stub MCIDRIVERNOTIFY
712 stub MCIEXECUTE
@@ -131,9 +131,9 @@
807 pascal mixerGetLineControls(word ptr long) mixerGetLineControls16
808 pascal mixerGetControlDetails(word ptr long) mixerGetControlDetails16
809 pascal mixerSetControlDetails(word ptr long) mixerSetControlDetails16
-900 stub MMTASKCREATE
+900 pascal mmTaskCreate(ptr long long) mmTaskCreate16
902 stub MMTASKBLOCK
-903 stub MMTASKSIGNAL
+903 pascal mmTaskSignal(word) mmTaskSignal16
904 stub MMGETCURRENTTASK
905 stub MMTASKYIELD
1100 pascal DRVOPEN(str str long) DrvOpen
@@ -141,12 +141,12 @@
1102 pascal DRVSENDMESSAGE(word word long long) DrvSendMessage
1103 pascal DRVGETMODULEHANDLE(word) DrvGetModuleHandle
1104 pascal DRVDEFDRIVERPROC(long word word long long) DrvDefDriverProc
-1120 stub MMTHREADCREATE
-1121 stub MMTHREADSIGNAL
+1120 pascal mmThreadCreate(ptr ptr long long) mmThreadCreate16
+1121 pascal mmThreadSignal(word) mmThreadSignal16
1122 stub MMTHREADBLOCK
1123 stub MMTHREADISCURRENT
1124 stub MMTHREADISVALID
-1125 stub MMTHREADGETTASK
+1125 pascal mmThreadGetTask(word) mmThreadGetTask16
1150 stub MMSHOWMMCPLPROPERTYSHEET
1210 pascal mmioOpen(str ptr long) mmioOpen16
1211 pascal MMIOCLOSE(word word) mmioClose
diff --git a/if1632/ole2thk.spec b/if1632/ole2thk.spec
new file mode 100644
index 0000000..e945a98
--- /dev/null
+++ b/if1632/ole2thk.spec
@@ -0,0 +1,10 @@
+name ole2thk
+type win16
+
+1 stub WEP
+2 stub ROT16_ISRUNNING16
+3 stub ISWIN32SHANDLE
+4 stub ___EXPORTEDSTUB
+5 stub COTHKCOMMON
+6 stub ROT16_GETTIMEOFLASTCHANGE16
+7 stub ROT16_GETOBJECT16
diff --git a/if1632/relay.c b/if1632/relay.c
index a49114d..6596be5 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -232,208 +232,6 @@
}
-/***********************************************************************
- * RELAY_CallFrom32
- *
- * Stack layout on entry to this function:
- * ... ...
- * (esp+12) arg2
- * (esp+8) arg1
- * (esp+4) ret_addr
- * (esp) return addr to relay code
- */
-int RELAY_CallFrom32( int ret_addr, ... )
-{
- int i, ret;
- char buffer[80];
- FARPROC32 func;
- DWORD mask, typemask;
-
- int *args = &ret_addr;
- /* Relay addr is the return address for this function */
- BYTE *relay_addr = (BYTE *)args[-1];
- WORD nb_args = *(WORD *)(relay_addr + 1) / sizeof(int);
-
- assert(debugging_relay);
- func = BUILTIN_GetEntryPoint32( buffer, relay_addr - 5, &typemask );
- printf( "Call %s(", buffer );
- args++;
- for (i = 0, mask = 3; i < nb_args; i++, mask <<= 2)
- {
- if (i) printf( "," );
- if ((typemask & mask) && HIWORD(args[i]))
- {
- if (typemask & (2<<(2*i)))
- {
- char buff[80];
- lstrcpynWtoA( buff, (LPWSTR)args[i], sizeof(buff) );
- printf( "%08x L\"%s\"", args[i], buff );
- }
- else printf( "%08x \"%s\"", args[i], (char *)args[i] );
- }
- else printf( "%08x", args[i] );
- }
- printf( ") ret=%08x\n", ret_addr );
- if (*relay_addr == 0xc3) /* cdecl */
- {
- LRESULT (*cfunc)() = (LRESULT(*)())func;
- switch(nb_args)
- {
- case 0: ret = cfunc(); break;
- case 1: ret = cfunc(args[0]); break;
- case 2: ret = cfunc(args[0],args[1]); break;
- case 3: ret = cfunc(args[0],args[1],args[2]); break;
- case 4: ret = cfunc(args[0],args[1],args[2],args[3]); break;
- case 5: ret = cfunc(args[0],args[1],args[2],args[3],args[4]); break;
- case 6: ret = cfunc(args[0],args[1],args[2],args[3],args[4],
- args[5]); break;
- case 7: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6]); break;
- case 8: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7]); break;
- case 9: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8]); break;
- case 10: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9]); break;
- case 11: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10]); break;
- case 12: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],
- args[11]); break;
- case 13: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],args[11],
- args[12]); break;
- case 14: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],args[11],
- args[12],args[13]); break;
- case 15: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],args[11],
- args[12],args[13],args[14]); break;
- default:
- fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
- nb_args );
- assert(FALSE);
- }
- }
- else /* stdcall */
- {
- switch(nb_args)
- {
- case 0: ret = func(); break;
- case 1: ret = func(args[0]); break;
- case 2: ret = func(args[0],args[1]); break;
- case 3: ret = func(args[0],args[1],args[2]); break;
- case 4: ret = func(args[0],args[1],args[2],args[3]); break;
- case 5: ret = func(args[0],args[1],args[2],args[3],args[4]); break;
- case 6: ret = func(args[0],args[1],args[2],args[3],args[4],
- args[5]); break;
- case 7: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6]); break;
- case 8: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7]); break;
- case 9: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8]); break;
- case 10: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9]); break;
- case 11: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10]); break;
- case 12: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],
- args[11]); break;
- case 13: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],args[11],
- args[12]); break;
- case 14: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],args[11],
- args[12],args[13]); break;
- case 15: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
- args[6],args[7],args[8],args[9],args[10],args[11],
- args[12],args[13],args[14]); break;
- default:
- fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
- nb_args );
- assert(FALSE);
- }
- }
- printf( "Ret %s() retval=%08x ret=%08x\n", buffer, ret, ret_addr );
- return ret;
-}
-
-
-/***********************************************************************
- * RELAY_CallFrom32Regs
- *
- * 'stack' points to the relay addr on the stack.
- * Stack layout:
- * ... ...
- * (esp+216) ret_addr
- * (esp+212) return to relay debugging code (only when debugging_relay)
- * (esp+208) entry point to call
- * (esp+4) CONTEXT
- * (esp) return addr to relay code
- */
-void RELAY_CallFrom32Regs( CONTEXT context,
- void (CALLBACK *entry_point)(CONTEXT *),
- BYTE *relay_addr, int ret_addr )
-{
- if (!debugging_relay)
- {
- /* Simply call the entry point */
- entry_point( &context );
- }
- else
- {
- char buffer[80];
- DWORD typemask;
-
- __RESTORE_ES;
- /* Fixup the context structure because of the extra parameter */
- /* pushed by the relay debugging code */
-
- EIP_reg(&context) = ret_addr;
- ESP_reg(&context) += sizeof(int);
-
- BUILTIN_GetEntryPoint32( buffer, relay_addr - 5, &typemask );
- printf("Call %s(regs) ret=%08x\n", buffer, ret_addr );
- printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
- EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
- EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
- printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
- EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
- DS_reg(&context), ES_reg(&context), FS_reg(&context),
- GS_reg(&context), EFL_reg(&context) );
-
- /* Now call the real function */
- entry_point( &context );
-
- printf("Ret %s() retval=regs ret=%08x\n", buffer, ret_addr );
- printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
- EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
- EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
- printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
- EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
- DS_reg(&context), ES_reg(&context), FS_reg(&context),
- GS_reg(&context), EFL_reg(&context) );
- }
-}
-
-
-/***********************************************************************
- * RELAY_Unimplemented32
- *
- * This function is called for unimplemented 32-bit entry points (declared
- * as 'stub' in the spec file).
- */
-void RELAY_Unimplemented32( const char *dll_name, int ordinal,
- const char *func_name, int ret_addr )
-{
- __RESTORE_ES; /* Just in case */
- fprintf( stderr, "No handler for Win32 routine %s.%d: %s (called from %08x)\n",
- dll_name, ordinal, func_name, ret_addr );
- TASK_KillCurrentTask(1);
-}
-
-
/**********************************************************************
* Catch (KERNEL.55)
*
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 4a9a446..5bb6eba 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -1,10 +1,10 @@
/*
- * Emulator and Win95 thunks
+ * Emulator thunks
*
* Copyright 1996, 1997 Alexandre Julliard
- * Copyright 1997 Marcus Meissner
*/
+#include <stdio.h>
#include "windows.h"
#include "callback.h"
#include "resource.h"
@@ -26,8 +26,8 @@
/* by the build program to generate the file if1632/callto16.S */
/* ### start build ### */
-extern LONG CALLBACK CallTo16_regs_short(const CONTEXT *context, INT32 offset);
-extern LONG CALLBACK CallTo16_regs_long (const CONTEXT *context, INT32 offset);
+extern LONG CALLBACK CallTo16_sreg_(const CONTEXT *context, INT32 offset);
+extern LONG CALLBACK CallTo16_lreg_(const CONTEXT *context, INT32 offset);
extern WORD CALLBACK CallTo16_word_ (FARPROC16);
extern WORD CALLBACK CallTo16_word_w (FARPROC16,WORD);
extern LONG CALLBACK CallTo16_long_l (FARPROC16,LONG);
@@ -98,7 +98,8 @@
/* Callbacks function table for the emulator */
static const CALLBACKS_TABLE CALLBACK_EmulatorTable =
{
- (void *)CallTo16_regs_short, /* CallRegisterProc */
+ (void *)CallTo16_sreg_, /* CallRegisterShortProc */
+ (void *)CallTo16_lreg_, /* CallRegisterLongProc */
THUNK_CallTaskReschedule, /* CallTaskRescheduleProc */
CallFrom16_long_wwwll, /* CallFrom16WndProc */
THUNK_CallWndProc16, /* CallWndProc */
@@ -110,6 +111,7 @@
(void *)CallTo16_word_ww, /* CallBootAppProc */
(void *)CallTo16_word_www, /* CallLoadAppSegProc */
(void *)CallTo16_word_, /* CallSystemTimerProc */
+ (void *)CallTo16_long_l, /* CallWOWCallbackProc */
(void *)CallTo16_long_l, /* CallASPIPostProc */
(void *)CallTo16_word_lwll, /* CallDrvControlProc */
(void *)CallTo16_word_lwlll, /* CallDrvEnableProc */
@@ -183,7 +185,7 @@
return;
}
}
- fprintf( stderr, "THUNK_Free: invalid thunk addr %p\n", thunk );
+ dprintf_thunk( stddeb, "THUNK_Free: invalid thunk addr %p\n", thunk );
}
@@ -246,7 +248,7 @@
args[4] = hwnd;
/* args[5] and args[6] are used by relay code to store the stack pointer */
- ret = CallTo16_regs_short( &context, -(5 * sizeof(WORD)) );
+ ret = CallTo16_sreg_( &context, -(5 * sizeof(WORD)) );
if (offset) STACK16_POP(offset);
return ret;
}
@@ -572,598 +574,3 @@
}
return NULL;
}
-
-
-/***********************************************************************
- * *
- * Win95 internal thunks *
- * *
- ***********************************************************************/
-
-/***********************************************************************
- * Generates a FT_Prolog call.
- *
- * 0FB6D1 movzbl edx,cl
- * 8B1495xxxxxxxx mov edx,[4*edx + xxxxxxxx]
- * 68xxxxxxxx push FT_Prolog
- * C3 lret
- */
-static void _write_ftprolog(LPBYTE thunk,DWORD thunkstart) {
- LPBYTE x;
-
- x = thunk;
- *x++ = 0x0f;*x++=0xb6;*x++=0xd1; /* movzbl edx,cl */
- *x++ = 0x8B;*x++=0x14;*x++=0x95;*(DWORD*)x= thunkstart;
- x+=4; /* mov edx, [4*edx + thunkstart] */
- *x++ = 0x68; *(DWORD*)x = (DWORD)GetProcAddress32(GetModuleHandle32A("KERNEL32"),"FT_Prolog");
- x+=4; /* push FT_Prolog */
- *x++ = 0xC3; /* lret */
- /* fill rest with 0xCC / int 3 */
-}
-
-/***********************************************************************
- * FT_PrologPrime (KERNEL32.89)
- */
-void WINAPI FT_PrologPrime(DWORD startind,LPBYTE thunk) {
- _write_ftprolog(thunk,*(DWORD*)(startind+thunk));
-}
-
-/***********************************************************************
- * Generates a QT_Thunk style call.
- *
- * 33C9 xor ecx, ecx
- * 8A4DFC mov cl , [ebp-04]
- * 8B148Dxxxxxxxx mov edx, [4*ecx + (EAX+EDX)]
- * B8yyyyyyyy mov eax, QT_Thunk
- * FFE0 jmp eax
- */
-static void _write_qtthunk(LPBYTE start,DWORD thunkstart) {
- LPBYTE x;
-
- x = start;
- *x++ = 0x33;*x++=0xC9; /* xor ecx,ecx */
- *x++ = 0x8A;*x++=0x4D;*x++=0xFC; /* movb cl,[ebp-04] */
- *x++ = 0x8B;*x++=0x14;*x++=0x8D;*(DWORD*)x= thunkstart;
- x+=4; /* mov edx, [4*ecx + (EAX+EDX) */
- *x++ = 0xB8; *(DWORD*)x = (DWORD)GetProcAddress32(GetModuleHandle32A("KERNEL32"),"QT_Thunk");
- x+=4; /* mov eax , QT_Thunk */
- *x++ = 0xFF; *x++ = 0xE0; /* jmp eax */
- /* should fill the rest of the 32 bytes with 0xCC */
-}
-
-/***********************************************************************
- * ThunkConnect32 (KERNEL32)
- * Connects a 32bit and a 16bit thunkbuffer.
- */
-struct thunkstruct
-{
- char magic[4];
- DWORD length;
- DWORD ptr;
- DWORD x0C;
-
- DWORD x10;
- DWORD x14;
- DWORD x18;
- DWORD x1C;
- DWORD x20;
-};
-
-UINT32 WINAPI ThunkConnect32( struct thunkstruct *ths, LPSTR thunkfun16,
- LPSTR module16, LPSTR module32, HMODULE32 hmod32,
- DWORD dllinitarg1 )
-{
- HINSTANCE16 hmm;
- SEGPTR thkbuf;
- struct thunkstruct *ths16;
-
- fprintf(stdnimp,"ThunkConnect32(<struct>,%s,%s,%s,%x,%lx)\n",
- thunkfun16,module32,module16,hmod32,dllinitarg1
- );
- fprintf(stdnimp," magic = %c%c%c%c\n",
- ths->magic[0],
- ths->magic[1],
- ths->magic[2],
- ths->magic[3]
- );
- fprintf(stdnimp," length = %lx\n",ths->length);
- if (lstrncmp32A(ths->magic,"SL01",4)&&lstrncmp32A(ths->magic,"LS01",4))
- return 0;
- hmm=LoadModule16(module16,NULL);
- if (hmm<=32)
- return 0;
- thkbuf=(SEGPTR)WIN32_GetProcAddress16(hmm,thunkfun16);
- if (!thkbuf)
- return 0;
- ths16=(struct thunkstruct*)PTR_SEG_TO_LIN(thkbuf);
- if (lstrncmp32A(ths16->magic,ths->magic,4))
- return 0;
-
- if (!lstrncmp32A(ths->magic,"SL01",4)) {
- if (ths16->length != ths->length)
- return 0;
- ths->x0C = (DWORD)ths16;
-
- fprintf(stderr," ths16 magic is 0x%08lx\n",*(DWORD*)ths16->magic);
- if (*((DWORD*)ths16->magic) != 0x0000304C)
- return 0;
- if (!*(WORD*)(((LPBYTE)ths16)+0x12))
- return 0;
-
- }
- if (!lstrncmp32A(ths->magic,"LS01",4)) {
- if (ths16->length != ths->length)
- return 0;
- ths->ptr = (DWORD)PTR_SEG_TO_LIN(ths16->ptr);
- /* code offset for QT_Thunk is at 0x1C... */
- _write_qtthunk (((LPBYTE)ths) + ths->x1C,ths->ptr);
- /* code offset for FT_Prolog is at 0x20... */
- _write_ftprolog(((LPBYTE)ths) + ths->x20,ths->ptr);
- return 1;
- }
- return TRUE;
-}
-
-
-/**********************************************************************
- * QT_Thunk (KERNEL32)
- *
- * The target address is in EDX.
- * The 16 bit arguments start at ESP+4.
- * The number of 16bit argumentbytes is EBP-ESP-0x44 (68 Byte thunksetup).
- * [ok]
- */
-VOID WINAPI QT_Thunk(CONTEXT *context)
-{
- CONTEXT context16;
- DWORD argsize;
-
- memcpy(&context16,context,sizeof(context16));
-
- CS_reg(&context16) = HIWORD(EDX_reg(context));
- IP_reg(&context16) = LOWORD(EDX_reg(context));
-
- argsize = EBP_reg(context)-ESP_reg(context)-0x44;
-
- /* additional 4 bytes used by the relaycode for storing the stackptr */
- memcpy( ((LPBYTE)CURRENT_STACK16)-argsize-4,
- (LPBYTE)ESP_reg(context)+4,
- argsize
- );
- EAX_reg(context) = CallTo16_regs_short(&context16,-argsize);
-}
-
-
-/**********************************************************************
- * WOWCallback16 (KERNEL32.62)
- */
-DWORD WINAPI WOWCallback16(FARPROC16 fproc,DWORD arg)
-{
- DWORD ret;
- fprintf(stderr,"WOWCallback16(%p,0x%08lx) ",fproc,arg);
- ret = CallTo16_long_l(fproc,arg);
- fprintf(stderr,"... returns %ld\n",ret);
- return ret;
-}
-
-/***********************************************************************
- * _KERNEL32_52 (KERNEL32.52)
- * Returns a pointer to ThkBuf in the 16bit library SYSTHUNK.DLL.
- * [ok probably]
- */
-LPVOID WINAPI _KERNEL32_52()
-{
- HMODULE32 hmod = LoadLibrary16("systhunk.dll");
-
- if (hmod<=32)
- return 0;
- return PTR_SEG_TO_LIN(WIN32_GetProcAddress16(hmod,"ThkBuf"));
-}
-
-/***********************************************************************
- * _KERNEL32_43 (KERNEL32.42)
- * A thunkbuffer link routine
- * The thunkbuf looks like:
- *
- * 00: DWORD length ? don't know exactly
- * 04: SEGPTR ptr ? where does it point to?
- * The pointer ptr is written into the first DWORD of 'thunk'.
- * (probably correct implemented)
- * [ok probably]
- */
-DWORD WINAPI _KERNEL32_43(LPDWORD thunk,LPCSTR thkbuf,DWORD len,
- LPCSTR dll16,LPCSTR dll32)
-{
- HINSTANCE16 hmod;
- LPDWORD addr;
- SEGPTR segaddr;
-
- hmod = LoadLibrary16(dll16);
- if (hmod<32) {
- fprintf(stderr,"KERNEL32_43->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
- return 0;
- }
- segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
- if (!segaddr) {
- fprintf(stderr,"KERNEL32_43->no %s exported from %s!\n",thkbuf,dll16);
- return 0;
- }
- addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
- if (addr[0] != len) {
- fprintf(stderr,"KERNEL32_43->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
- return 0;
- }
- if (!addr[1])
- return 0;
- *(DWORD*)thunk = addr[1];
- return addr[1];
-}
-
-/***********************************************************************
- * _KERNEL32_45 (KERNEL32.44)
- * Another 32->16 thunk, the difference to QT_Thunk is, that the called routine
- * uses 0x66 lret, and that we have to pass CX in DI.
- * (there seems to be some kind of BL/BX return magic too...)
- *
- * [doesn't crash anymore]
- */
-VOID WINAPI _KERNEL32_45(CONTEXT *context)
-{
- CONTEXT context16;
- LPBYTE curstack;
- DWORD ret,stacksize;
-
- fprintf(stderr,"KERNEL32_45(%%eax=0x%08lx(%%cx=0x%04lx,%%edx=0x%08lx))\n",
- (DWORD)EAX_reg(context),(DWORD)CX_reg(context),(DWORD)EDX_reg(context)
- );
- stacksize = EBP_reg(context)-ESP_reg(context);
- fprintf(stderr," stacksize = %ld\n",stacksize);
-
- memcpy(&context16,context,sizeof(context16));
-
- DI_reg(&context16) = CX_reg(context);
- CS_reg(&context16) = HIWORD(EAX_reg(context));
- IP_reg(&context16) = LOWORD(EAX_reg(context));
-
- curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
- memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
- ret = CallTo16_regs_long(&context16,0);
- STACK16_POP(stacksize);
-
- fprintf(stderr,". returned %08lx\n",ret);
- EAX_reg(context) = ret;
-}
-
-/***********************************************************************
- * _KERNEL32_40 (KERNEL32.40)
- * YET Another 32->16 thunk, the difference to the others is still mysterious
- * target address is EDX
- *
- * [crashes]
- */
-VOID WINAPI _KERNEL32_40(CONTEXT *context)
-{
- CONTEXT context16;
- LPBYTE curstack;
- DWORD ret,stacksize;
-
- fprintf(stderr,"_KERNEL32_40(EDX=0x%08lx)\n",
- EDX_reg(context)
- );
- stacksize = EBP_reg(context)-ESP_reg(context);
- fprintf(stderr," stacksize = %ld\n",stacksize);
- fprintf(stderr,"on top of stack: 0x%04x\n",*(WORD*)ESP_reg(context));
-
- memcpy(&context16,context,sizeof(context16));
-
- CS_reg(&context16) = HIWORD(EDX_reg(context));
- IP_reg(&context16) = LOWORD(EDX_reg(context));
-
- curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
- memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
- ret = CallTo16_regs_short(&context16,0);
- STACK16_POP(stacksize);
-
- fprintf(stderr,". returned %08lx\n",ret);
- EAX_reg(context) = ret;
-}
-
-/***********************************************************************
- * (KERNEL32.41)
- * A thunk setup routine.
- * Expects a pointer to a preinitialized thunkbuffer in the first argument
- * looking like:
- * 00..03: unknown (pointer, check _41, _43, _46)
- * 04: EB1E jmp +0x20
- *
- * 06..23: unknown (space for replacement code, check .90)
- *
- * 24:>E800000000 call offset 29
- * 29:>58 pop eax ( target of call )
- * 2A: 2D25000000 sub eax,0x00000025 ( now points to offset 4 )
- * 2F: BAxxxxxxxx mov edx,xxxxxxxx
- * 34: 68yyyyyyyy push KERNEL32.90
- * 39: C3 ret
- *
- * 3A: EB1E jmp +0x20
- * 3E ... 59: unknown (space for replacement code?)
- * 5A: E8xxxxxxxx call <32bitoffset xxxxxxxx>
- * 5F: 5A pop edx
- * 60: 81EA25xxxxxx sub edx, 0x25xxxxxx
- * 66: 52 push edx
- * 67: 68xxxxxxxx push xxxxxxxx
- * 6C: 68yyyyyyyy push KERNEL32.89
- * 71: C3 ret
- * 72: end?
- * This function checks if the code is there, and replaces the yyyyyyyy entries
- * by the functionpointers.
- * The thunkbuf looks like:
- *
- * 00: DWORD length ? don't know exactly
- * 04: SEGPTR ptr ? where does it point to?
- * The segpointer ptr is written into the first DWORD of 'thunk'.
- * [ok probably]
- */
-
-LPVOID WINAPI _KERNEL32_41(LPBYTE thunk,LPCSTR thkbuf,DWORD len,LPCSTR dll16,
- LPCSTR dll32)
-{
- HMODULE32 hkrnl32 = GetModuleHandle32A("KERNEL32");
- HMODULE16 hmod;
- LPDWORD addr,addr2;
- DWORD segaddr;
-
- /* FIXME: add checks for valid code ... */
- /* write pointers to kernel32.89 and kernel32.90 (+ordinal base of 1) */
- *(DWORD*)(thunk+0x35) = (DWORD)GetProcAddress32(hkrnl32,(LPSTR)90);
- *(DWORD*)(thunk+0x6D) = (DWORD)GetProcAddress32(hkrnl32,(LPSTR)89);
-
-
- hmod = LoadLibrary16(dll16);
- if (hmod<32) {
- fprintf(stderr,"KERNEL32_41->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
- return NULL;
- }
- segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
- if (!segaddr) {
- fprintf(stderr,"KERNEL32_41->no %s exported from %s!\n",thkbuf,dll16);
- return NULL;
- }
- addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
- if (addr[0] != len) {
- fprintf(stderr,"KERNEL32_41->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
- return NULL;
- }
- addr2 = PTR_SEG_TO_LIN(addr[1]);
- if (HIWORD(addr2))
- *(DWORD*)thunk = (DWORD)addr2;
- return addr2;
-}
-
-/***********************************************************************
- * (KERNEL32.90)
- * QT Thunk priming function
- * Rewrites the first part of the thunk to use the QT_Thunk interface
- * and jumps to the start of that code.
- * [ok]
- */
-VOID WINAPI _KERNEL32_90(CONTEXT *context)
-{
- _write_qtthunk((LPBYTE)EAX_reg(context),*(DWORD*)(EAX_reg(context)+EDX_reg(context)));
- /* we just call the real QT_Thunk right now
- * we can bypass the relaycode, for we already have the registercontext
- */
- EDX_reg(context) = *(DWORD*)((*(DWORD*)(EAX_reg(context)+EDX_reg(context)))+4*(((BYTE*)EBP_reg(context))[-4]));
- return QT_Thunk(context);
-}
-
-/***********************************************************************
- * (KERNEL32.45)
- * Another thunkbuf link routine.
- * The start of the thunkbuf looks like this:
- * 00: DWORD length
- * 04: SEGPTR address for thunkbuffer pointer
- * [ok probably]
- */
-VOID WINAPI _KERNEL32_46(LPBYTE thunk,LPSTR thkbuf,DWORD len,LPSTR dll16,
- LPSTR dll32)
-{
- LPDWORD addr;
- HMODULE16 hmod;
- SEGPTR segaddr;
-
- hmod = LoadLibrary16(dll16);
- if (hmod < 32) {
- fprintf(stderr,"KERNEL32_46->couldn't load %s, error %d\n",dll16,hmod);
- return;
- }
- segaddr = (SEGPTR)WIN32_GetProcAddress16(hmod,thkbuf);
- if (!segaddr) {
- fprintf(stderr,"KERNEL32_46-> haven't found %s in %s!\n",thkbuf,dll16);
- return;
- }
- addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
- if (addr[0] != len) {
- fprintf(stderr,"KERNEL32_46-> length of thkbuf differs from expected length! (%ld vs %ld)\n",addr[0],len);
- return;
- }
- *(DWORD*)PTR_SEG_TO_LIN(addr[1]) = (DWORD)thunk;
-}
-
-/**********************************************************************
- * _KERNEL32_87
- * Check if thunking is initialized (ss selector set up etc.)
- * We do that differently, so just return TRUE.
- * [ok]
- */
-BOOL32 WINAPI _KERNEL32_87()
-{
- return TRUE;
-}
-
-/**********************************************************************
- * _KERNEL32_88
- * One of the real thunking functions. This one seems to be for 32<->32
- * thunks. It should probably be capable of crossing processboundaries.
- *
- * And YES, I've seen nr=48 (somewhere in the Win95 32<->16 OLE coupling)
- * [ok]
- */
-DWORD WINAPIV _KERNEL32_88( DWORD nr, DWORD flags, FARPROC32 fun, ... )
-{
- DWORD i,ret;
- DWORD *args = ((DWORD *)&fun) + 1;
-
- fprintf(stderr,"KERNEL32_88(%ld,0x%08lx,%p,[ ",nr,flags,fun);
- for (i=0;i<nr/4;i++) fprintf(stderr,"0x%08lx,",args[i]);
- fprintf(stderr,"])");
- switch (nr) {
- case 0: ret = fun();
- break;
- case 4: ret = fun(args[0]);
- break;
- case 8: ret = fun(args[0],args[1]);
- break;
- case 12: ret = fun(args[0],args[1],args[2]);
- break;
- case 16: ret = fun(args[0],args[1],args[2],args[3]);
- break;
- case 20: ret = fun(args[0],args[1],args[2],args[3],args[4]);
- break;
- case 24: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5]);
- break;
- case 28: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
- break;
- case 32: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
- break;
- case 36: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
- break;
- case 40: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
- break;
- case 44: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
- break;
- case 48: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]);
- break;
- default:
- fprintf(stderr," unsupported nr of arguments, %ld\n",nr);
- ret = 0;
- break;
-
- }
- fprintf(stderr," returning %ld ...\n",ret);
- return ret;
-}
-
-/**********************************************************************
- * KERNEL_619 (KERNEL)
- * Seems to store y and z depending on x in some internal lists...
- */
-WORD WINAPI _KERNEL_619(WORD x,DWORD y,DWORD z)
-{
- fprintf(stderr,"KERNEL_619(0x%04x,0x%08lx,0x%08lx)\n",x,y,z);
- return x;
-}
-
-/**********************************************************************
- * AllocSLCallback (KERNEL32)
- *
- * Win95 uses some structchains for callbacks. It allocates them
- * in blocks of 100 entries, size 32 bytes each, layout:
- * blockstart:
- * 0: PTR nextblockstart
- * 4: entry *first;
- * 8: WORD sel ( start points to blockstart)
- * A: WORD unknown
- * 100xentry:
- * 00..17: Code
- * 18: PDB *owning_process;
- * 1C: PTR blockstart
- *
- * We ignore this for now. (Just a note for further developers)
- * FIXME: use this method, so we don't waste selectors...
- *
- * Following code is then generated by AllocSLCallback. The code is 16 bit, so
- * the 0x66 prefix switches from word->long registers.
- *
- * 665A pop edx
- * 6668x arg2 x pushl <arg2>
- * 6652 push edx
- * EAx arg1 x jmpf <arg1>
- *
- * returns the startaddress of this thunk.
- *
- * Note, that they look very similair to the ones allocates by THUNK_Alloc.
- */
-DWORD WINAPI
-AllocSLCallback(DWORD finalizer,DWORD callback) {
- LPBYTE x,thunk = HeapAlloc( GetProcessHeap(), 0, 32 );
- WORD sel;
-
- x=thunk;
- *x++=0x66;*x++=0x5a; /* popl edx */
- *x++=0x66;*x++=0x68;*(DWORD*)x=finalizer;x+=4; /* pushl finalizer */
- *x++=0x66;*x++=0x52; /* pushl edx */
- *x++=0xea;*(DWORD*)x=callback;x+=4; /* jmpf callback */
-
- *(DWORD*)(thunk+18) = GetCurrentProcessId();
-
- sel = SELECTOR_AllocBlock( thunk , 32, SEGMENT_CODE, FALSE, FALSE );
- return (sel<<16)|0;
-}
-
-void WINAPI
-FreeSLCallback(DWORD x) {
- fprintf(stderr,"FreeSLCallback(0x%08lx)\n",x);
-}
-
-/**********************************************************************
- * KERNEL_358 (KERNEL)
- * Allocates a code segment which starts at the address passed in x. limit
- * 0xfffff, and returns the pointer to the start.
- */
-DWORD WINAPI
-_KERNEL_358(DWORD x) {
- WORD sel;
-
- fprintf(stderr,"_KERNEL_358(0x%08lx),stub\n",x);
- if (!HIWORD(x))
- return x;
-
- sel = SELECTOR_AllocBlock( PTR_SEG_TO_LIN(x) , 0xffff, SEGMENT_CODE, FALSE, FALSE );
- return (sel<<16)|(0x0000);
-}
-
-/**********************************************************************
- * KERNEL_359 (KERNEL)
- * Frees the code segment of the passed linear pointer (This has usually
- * been allocated by _KERNEL_358).
- */
-VOID WINAPI
-_KERNEL_359(DWORD x) {
- DWORD savedsssp;
-
- fprintf(stderr,"_KERNEL_359(0x%08lx),stub\n",x);
- if ((HIWORD(x) & 7)!=7)
- return;
- savedsssp = IF1632_Saved16_ss_sp;IF1632_Saved16_ss_sp = 0;
- SELECTOR_FreeBlock(x>>16,1);
- IF1632_Saved16_ss_sp = savedsssp;
- return;
-}
-
-/**********************************************************************
- * KERNEL_472 (KERNEL)
- * something like GetCurrenthInstance.
- */
-VOID WINAPI
-_KERNEL_472(CONTEXT *context) {
- fprintf(stderr,"_KERNEL_472(0x%08lx),stub\n",EAX_reg(context));
- if (!EAX_reg(context)) {
- TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
- AX_reg(context)=pTask->hInstance;
- return;
- }
- if (!HIWORD(EAX_reg(context)))
- return; /* returns the passed value */
- /* hmm ... fixme */
-}
diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec
index c3837e9..9940d99 100644
--- a/if1632/toolhelp.spec
+++ b/if1632/toolhelp.spec
@@ -17,9 +17,9 @@
63 pascal16 TaskFirst(ptr) TaskFirst
64 pascal16 TaskNext(ptr) TaskNext
65 pascal16 TaskFindHandle(ptr word) TaskFindHandle
-66 stub STACKTRACEFIRST
-67 stub STACKTRACECSIPFIRST
-68 stub STACKTRACENEXT
+66 pascal16 StackTraceFirst(ptr word) StackTraceFirst
+67 pascal16 StackTraceCSIPFirst(ptr word word word word) StackTraceCSIPFirst
+68 pascal16 StackTraceNext(ptr) StackTraceNext
69 pascal16 ClassFirst(ptr) ClassFirst
70 pascal16 ClassNext(ptr) ClassNext
71 pascal16 SystemHeapInfo(ptr) SystemHeapInfo
diff --git a/if1632/user.spec b/if1632/user.spec
index fef3bfc..814a19f 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -346,7 +346,7 @@
383 stub GetWindowContextHelpID
384 stub SetMenuContextHelpID
385 stub GetMenuContextHelpID
-389 stub LoadImage
+389 pascal LoadImage(word segstr word word word word) LoadImage16
390 stub CopyImage
391 stub SignalProc32
394 pascal16 DrawIconEx(word word word word word word word word word) DrawIconEx16
@@ -373,7 +373,7 @@
417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions
418 pascal16 SetMenuItemBitmaps(word word word word word) SetMenuItemBitmaps16
420 pascal16 wsprintf() WIN16_wsprintf16
-421 pascal16 wvsprintf(ptr ptr ptr) wvsprintf16
+421 pascal16 wvsprintf(ptr str ptr) wvsprintf16
422 pascal16 DlgDirSelectEx(word ptr word word) DlgDirSelectEx16
423 pascal16 DlgDirSelectComboBoxEx(word ptr word word) DlgDirSelectComboBoxEx16
427 pascal16 FindWindowEx(word word segstr str) FindWindowEx16
diff --git a/if1632/win32s16.spec b/if1632/win32s16.spec
index 2457c88..a82aff2 100644
--- a/if1632/win32s16.spec
+++ b/if1632/win32s16.spec
@@ -2,7 +2,7 @@
type win16
1 stub WEP
-2 stub BOOTTASK
+2 pascal16 BootTask() BootTask
3 stub CREATEPROCESS
4 stub WAITFORDEBUGEVENT
5 pascal CONTINUEDEBUGEVENT(long long long) ContinueDebugEvent
@@ -48,8 +48,8 @@
45 stub FAPILOG16
46 stub ALLOCCALLBACK
47 stub LINEARTOHUGESELECTOROFFSET
-48 stub UTSELECTOROFFSETTOLINEAR
-49 stub UTLINEARTOSELECTOROFFSET
+48 pascal UTSelectorOffsetToLinear(ptr) UTSelectorOffsetToLinear
+49 pascal UTLinearToSelectorOffset(ptr) UTLinearToSelectorOffset
50 stub SELFOREIGNTIB
51 stub MYGLOBALREALLOC
52 stub CREATEPEHEADER
diff --git a/if1632/windebug.spec b/if1632/windebug.spec
new file mode 100644
index 0000000..7b4fb6b
--- /dev/null
+++ b/if1632/windebug.spec
@@ -0,0 +1,6 @@
+name windebug
+type win16
+
+ 1 stub WINDEBUG
+ 2 stub WEP
+ 3 pascal WinNotify() WinNotify
diff --git a/if1632/winsock.spec b/if1632/winsock.spec
index 2548e10..e8564bb 100644
--- a/if1632/winsock.spec
+++ b/if1632/winsock.spec
@@ -16,7 +16,7 @@
8 pascal htonl(long) WINSOCK_htonl
9 pascal16 htons(word) WINSOCK_htons
10 pascal inet_addr(ptr) WINSOCK_inet_addr
-11 pascal inet_ntoa(long) WINSOCK_inet_ntoa
+11 pascal inet_ntoa(long) WINSOCK_inet_ntoa16
12 pascal16 ioctlsocket(word long ptr) WINSOCK_ioctlsocket16
13 pascal16 listen(word word) WINSOCK_listen16
14 pascal ntohl(long) WINSOCK_ntohl
@@ -36,20 +36,20 @@
55 pascal getservbyname(ptr ptr) WINSOCK_getservbyname16
56 pascal getservbyport(word ptr) WINSOCK_getservbyport16
57 pascal gethostname(ptr word) WINSOCK_gethostname16
-101 pascal16 WSAAsyncSelect(word word word long) WSAAsyncSelect
+101 pascal16 WSAAsyncSelect(word word word long) WSAAsyncSelect16
102 pascal16 WSAAsyncGetHostByAddr(word word ptr word word segptr word)
- WSAAsyncGetHostByAddr
+ WSAAsyncGetHostByAddr16
103 pascal16 WSAAsyncGetHostByName(word word ptr segptr word)
- WSAAsyncGetHostByName
+ WSAAsyncGetHostByName16
104 pascal16 WSAAsyncGetProtoByNumber(word word word segptr word)
- WSAAsyncGetProtoByNumber
+ WSAAsyncGetProtoByNumber16
105 pascal16 WSAAsyncGetProtoByName(word word ptr segptr word)
- WSAAsyncGetProtoByName
+ WSAAsyncGetProtoByName16
106 pascal16 WSAAsyncGetServByPort(word word word ptr segptr word)
- WSAAsyncGetServByPort
+ WSAAsyncGetServByPort16
107 pascal16 WSAAsyncGetServByName(word word ptr ptr segptr word)
- WSAAsyncGetServByName
-108 pascal16 WSACancelAsyncRequest(word) WSACancelAsyncRequest
+ WSAAsyncGetServByName16
+108 pascal16 WSACancelAsyncRequest(word) WSACancelAsyncRequest16
109 pascal16 WSASetBlockingHook(segptr) WSASetBlockingHook16
110 pascal16 WSAUnhookBlockingHook() WSAUnhookBlockingHook16
111 pascal16 WSAGetLastError() WSAGetLastError
diff --git a/include/builtin32.h b/include/builtin32.h
new file mode 100644
index 0000000..56532a3
--- /dev/null
+++ b/include/builtin32.h
@@ -0,0 +1,31 @@
+/*
+ * Win32 built-in DLLs definitions
+ *
+ * Copyright 1997 Alexandre Julliard
+ */
+
+#ifndef __WINE_BUILTIN32_H
+#define __WINE_BUILTIN32_H
+
+typedef void (*ENTRYPOINT32)();
+
+typedef struct
+{
+ const char *name; /* DLL name */
+ int base; /* Ordinal base */
+ int nb_funcs; /* Number of functions */
+ int nb_names; /* Number of function names */
+ int nb_reg_funcs; /* Number of register functions */
+ const ENTRYPOINT32 *functions; /* Pointer to function table */
+ const char * const *names; /* Pointer to names table */
+ const unsigned short *ordinals; /* Pointer to ordinals table */
+ const unsigned char *args; /* Pointer to argument lengths */
+ const unsigned int *argtypes; /* Pointer to argument types bitmask */
+} BUILTIN32_DESCRIPTOR;
+
+extern ENTRYPOINT32 BUILTIN32_GetEntryPoint( char *buffer, void *relay,
+ unsigned int *typemask );
+extern void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR *descr,
+ int ordinal );
+
+#endif /* __WINE_BUILTIN32_H */
diff --git a/include/cache.h b/include/cache.h
new file mode 100644
index 0000000..aa10b03
--- /dev/null
+++ b/include/cache.h
@@ -0,0 +1,17 @@
+/*
+ * Wine internally cached objects to speedup some things and prevent
+ * infinite duplication of trivial code and data.
+ *
+ * Copyright 1997 Bertho A. Stultiens
+ *
+ */
+
+#ifndef __WINE_CACHE_H
+#define __WINE_CACHE_H
+
+#include "wintypes.h"
+
+HBRUSH32 CACHE_GetPattern55AABrush(void);
+HBITMAP32 CACHE_GetPattern55AABitmap(void);
+
+#endif /* __WINE_CACHE_H */
diff --git a/include/callback.h b/include/callback.h
index 86b604f..c02abcc 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -19,7 +19,8 @@
typedef struct
{
- VOID (CALLBACK *CallRegisterProc)( CONTEXT *, INT32 );
+ LONG (CALLBACK *CallRegisterShortProc)( CONTEXT *, INT32 );
+ LONG (CALLBACK *CallRegisterLongProc)( CONTEXT *, INT32 );
VOID (CALLBACK *CallTaskRescheduleProc)(void);
VOID (CALLBACK *CallFrom16WndProc)(void);
LRESULT (CALLBACK *CallWndProc)( WNDPROC16, HWND16, UINT16,
@@ -36,6 +37,7 @@
VOID (CALLBACK *CallBootAppProc)( FARPROC16, HANDLE16, HFILE16 );
WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD );
VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 );
+ DWORD (CALLBACK *CallWOWCallbackProc)( FARPROC16, DWORD );
LRESULT (CALLBACK *CallASPIPostProc)( FARPROC16, SEGPTR );
/* Following are the graphics driver callbacks */
WORD (CALLBACK *CallDrvControlProc)( FARPROC16, SEGPTR, WORD,
diff --git a/include/color.h b/include/color.h
index 735e629..d226a19 100644
--- a/include/color.h
+++ b/include/color.h
@@ -14,6 +14,7 @@
#define PC_SYS_RESERVED 0x40 /* system palentry is not to be mapped to */
#define PC_SYS_MAPPED 0x10 /* logical palentry is a direct alias for system palentry */
+extern BOOL32 COLOR_Init(void);
extern void COLOR_Cleanup(void);
extern COLORREF COLOR_ToLogical(int pixel);
extern int COLOR_ToPhysical( DC *dc, COLORREF color );
@@ -22,11 +23,13 @@
extern Colormap COLOR_GetColormap();
extern UINT16 COLOR_GetSystemPaletteSize();
extern UINT16 COLOR_GetSystemPaletteFlags();
+extern const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void);
extern BOOL32 COLOR_GetMonoPlane( int* );
extern COLORREF COLOR_LookupNearestColor( PALETTEENTRY*, int, COLORREF );
extern int COLOR_PaletteLookupPixel( PALETTEENTRY*, int, int* , COLORREF, BOOL32 );
extern COLORREF COLOR_GetSystemPaletteEntry(UINT32);
+extern int COLOR_LookupSystemPixel(COLORREF col);
extern int COLOR_mapEGAPixel[16];
extern int* COLOR_PaletteToPixel;
diff --git a/include/compobj.h b/include/compobj.h
index 9aca771..6f2289f 100644
--- a/include/compobj.h
+++ b/include/compobj.h
@@ -11,7 +11,7 @@
BYTE Data4[8];
};
-typedef struct tagGUID GUID;
+typedef struct tagGUID GUID,*LPGUID;
typedef struct tagGUID CLSID,*LPCLSID,*REFCLSID;
typedef struct tagGUID IID,*REFIID,*LPIID;
diff --git a/include/config.h.in b/include/config.h.in
index 12cd82d..2d301c7 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -21,6 +21,9 @@
/* Define if you have the memmove function. */
#undef HAVE_MEMMOVE
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
/* Define if you have the tcgetattr function. */
#undef HAVE_TCGETATTR
diff --git a/include/cursoricon.h b/include/cursoricon.h
index 14c34b8..691487e 100644
--- a/include/cursoricon.h
+++ b/include/cursoricon.h
@@ -50,6 +50,9 @@
#pragma pack(4)
+extern HCURSOR16 CURSORICON_IconToCursor( HICON16 hIcon,
+ BOOL32 bSemiTransparent );
+
extern Cursor CURSORICON_XCursor; /* Current X cursor */
#endif /* __WINE_CURSORICON_H */
diff --git a/include/dce.h b/include/dce.h
index 11d235f..089ad22 100644
--- a/include/dce.h
+++ b/include/dce.h
@@ -22,6 +22,7 @@
#define DCX_DCEEMPTY 0x00000800
#define DCX_DCEBUSY 0x00001000
+#define DCX_DCEDIRTY 0x00002000
#define DCX_WINDOWPAINT 0x00020000
#define DCX_KEEPCLIPRGN 0x00040000
#define DCX_NOCLIPCHILDREN 0x00080000
diff --git a/include/debug.h b/include/debug.h
index 365c0ea..a34519d 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -78,6 +78,7 @@
#undef DEBUG_STRING
#undef DEBUG_TASK
#undef DEBUG_TEXT
+#undef DEBUG_THUNK
#undef DEBUG_TIMER
#undef DEBUG_TOOLHELP
#undef DEBUG_TWEAK
@@ -164,6 +165,7 @@
#define DEBUG_STRING
#define DEBUG_TASK
#define DEBUG_TEXT
+#define DEBUG_THUNK
#define DEBUG_TIMER
#define DEBUG_TOOLHELP
#define DEBUG_TWEAK
@@ -540,6 +542,11 @@
#else
0,
#endif
+#ifdef DEBUG_THUNK
+ 1,
+#else
+ 0,
+#endif
#ifdef DEBUG_TIMER
1,
#else
@@ -1539,8 +1546,21 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_timer if(!debug_msg_enabled[72]) ; else fprintf
-#define debugging_timer debug_msg_enabled[72]
+#define dprintf_thunk if(!debug_msg_enabled[72]) ; else fprintf
+#define debugging_thunk debug_msg_enabled[72]
+#else
+#ifdef DEBUG_THUNK
+#define dprintf_thunk fprintf
+#define debugging_thunk 1
+#else
+#define dprintf_thunk while(0) fprintf
+#define debugging_thunk 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_timer if(!debug_msg_enabled[73]) ; else fprintf
+#define debugging_timer debug_msg_enabled[73]
#else
#ifdef DEBUG_TIMER
#define dprintf_timer fprintf
@@ -1552,8 +1572,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_toolhelp if(!debug_msg_enabled[73]) ; else fprintf
-#define debugging_toolhelp debug_msg_enabled[73]
+#define dprintf_toolhelp if(!debug_msg_enabled[74]) ; else fprintf
+#define debugging_toolhelp debug_msg_enabled[74]
#else
#ifdef DEBUG_TOOLHELP
#define dprintf_toolhelp fprintf
@@ -1565,8 +1585,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_tweak if(!debug_msg_enabled[74]) ; else fprintf
-#define debugging_tweak debug_msg_enabled[74]
+#define dprintf_tweak if(!debug_msg_enabled[75]) ; else fprintf
+#define debugging_tweak debug_msg_enabled[75]
#else
#ifdef DEBUG_TWEAK
#define dprintf_tweak fprintf
@@ -1578,8 +1598,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_updown if(!debug_msg_enabled[75]) ; else fprintf
-#define debugging_updown debug_msg_enabled[75]
+#define dprintf_updown if(!debug_msg_enabled[76]) ; else fprintf
+#define debugging_updown debug_msg_enabled[76]
#else
#ifdef DEBUG_UPDOWN
#define dprintf_updown fprintf
@@ -1591,8 +1611,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_ver if(!debug_msg_enabled[76]) ; else fprintf
-#define debugging_ver debug_msg_enabled[76]
+#define dprintf_ver if(!debug_msg_enabled[77]) ; else fprintf
+#define debugging_ver debug_msg_enabled[77]
#else
#ifdef DEBUG_VER
#define dprintf_ver fprintf
@@ -1604,8 +1624,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_virtual if(!debug_msg_enabled[77]) ; else fprintf
-#define debugging_virtual debug_msg_enabled[77]
+#define dprintf_virtual if(!debug_msg_enabled[78]) ; else fprintf
+#define debugging_virtual debug_msg_enabled[78]
#else
#ifdef DEBUG_VIRTUAL
#define dprintf_virtual fprintf
@@ -1617,8 +1637,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_vxd if(!debug_msg_enabled[78]) ; else fprintf
-#define debugging_vxd debug_msg_enabled[78]
+#define dprintf_vxd if(!debug_msg_enabled[79]) ; else fprintf
+#define debugging_vxd debug_msg_enabled[79]
#else
#ifdef DEBUG_VXD
#define dprintf_vxd fprintf
@@ -1630,8 +1650,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_win if(!debug_msg_enabled[79]) ; else fprintf
-#define debugging_win debug_msg_enabled[79]
+#define dprintf_win if(!debug_msg_enabled[80]) ; else fprintf
+#define debugging_win debug_msg_enabled[80]
#else
#ifdef DEBUG_WIN
#define dprintf_win fprintf
@@ -1643,8 +1663,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_win16drv if(!debug_msg_enabled[80]) ; else fprintf
-#define debugging_win16drv debug_msg_enabled[80]
+#define dprintf_win16drv if(!debug_msg_enabled[81]) ; else fprintf
+#define debugging_win16drv debug_msg_enabled[81]
#else
#ifdef DEBUG_WIN16DRV
#define dprintf_win16drv fprintf
@@ -1656,8 +1676,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_win32 if(!debug_msg_enabled[81]) ; else fprintf
-#define debugging_win32 debug_msg_enabled[81]
+#define dprintf_win32 if(!debug_msg_enabled[82]) ; else fprintf
+#define debugging_win32 debug_msg_enabled[82]
#else
#ifdef DEBUG_WIN32
#define dprintf_win32 fprintf
@@ -1669,8 +1689,8 @@
#endif
#ifdef DEBUG_RUNTIME
-#define dprintf_winsock if(!debug_msg_enabled[82]) ; else fprintf
-#define debugging_winsock debug_msg_enabled[82]
+#define dprintf_winsock if(!debug_msg_enabled[83]) ; else fprintf
+#define debugging_winsock debug_msg_enabled[83]
#else
#ifdef DEBUG_WINSOCK
#define dprintf_winsock fprintf
@@ -1757,6 +1777,7 @@
"string",
"task",
"text",
+ "thunk",
"timer",
"toolhelp",
"tweak",
diff --git a/include/gdi.h b/include/gdi.h
index d744a41..ed90b94 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -11,6 +11,7 @@
#include "ldt.h"
#include "local.h"
#include "x11drv.h"
+#include "path.h"
/* GDI objects magic numbers */
#define PEN_MAGIC 0x4f47
@@ -100,6 +101,8 @@
HBITMAP16 hFirstBitmap; /* Bitmap selected at creation of the DC */
HANDLE16 hDevice;
HPALETTE16 hPalette;
+
+ GdiPath path;
WORD ROPmode;
WORD polyFillMode;
@@ -246,7 +249,7 @@
/* Stock objects handles */
-#define NB_STOCK_OBJECTS (SYSTEM_FIXED_FONT + 1)
+#define NB_STOCK_OBJECTS (DEFAULT_GUI_FONT + 1)
#define STOCK_WHITE_BRUSH ((HBRUSH16)(FIRST_STOCK_HANDLE+WHITE_BRUSH))
#define STOCK_LTGRAY_BRUSH ((HBRUSH16)(FIRST_STOCK_HANDLE+LTGRAY_BRUSH))
@@ -265,11 +268,12 @@
#define STOCK_DEVICE_DEFAULT_FONT ((HFONT16)(FIRST_STOCK_HANDLE+DEVICE_DEFAULT_FONT))
#define STOCK_DEFAULT_PALETTE ((HPALETTE16)(FIRST_STOCK_HANDLE+DEFAULT_PALETTE))
#define STOCK_SYSTEM_FIXED_FONT ((HFONT16)(FIRST_STOCK_HANDLE+SYSTEM_FIXED_FONT))
+#define STOCK_DEFAULT_GUI_FONT ((HFONT16)(FIRST_STOCK_HANDLE+DEFAULT_GUI_FONT))
#define FIRST_STOCK_FONT STOCK_OEM_FIXED_FONT
-#define LAST_STOCK_FONT STOCK_SYSTEM_FIXED_FONT
+#define LAST_STOCK_FONT STOCK_DEFAULT_GUI_FONT
-#define LAST_STOCK_HANDLE ((DWORD)STOCK_SYSTEM_FIXED_FONT)
+#define LAST_STOCK_HANDLE ((DWORD)STOCK_DEFAULT_GUI_FONT)
/* Device <-> logical coords conversion */
diff --git a/include/interfaces.h b/include/interfaces.h
index 5e912da..ef70a22 100644
--- a/include/interfaces.h
+++ b/include/interfaces.h
@@ -5,6 +5,13 @@
#include "ole2.h"
#include "compobj.h"
+#define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
+#define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn)
+#define PURE
+#define FAR
+#define THIS_ THIS,
+
+
DEFINE_OLEGUID(IID_IUnknown,0,0,0);
DEFINE_OLEGUID(IID_IClassFactory,1,0,0);
DEFINE_OLEGUID(IID_IMalloc,2,0,0);
@@ -18,28 +25,65 @@
DEFINE_OLEGUID(IID_IMessageFilter,0x16,0,0);
DEFINE_OLEGUID(IID_IStdMarshalInfo,0x18,0,0);
-typedef struct tagUNKNOWN *LPUNKNOWN,IUnknown;
+#define THIS LPUNKNOWN this
+typedef struct IUnknown *LPUNKNOWN,IUnknown;
typedef struct {
- HRESULT (CALLBACK *fnQueryInterface)(LPUNKNOWN this,REFIID refiid,LPVOID *obj);
- HRESULT (CALLBACK *fnAddRef)(LPUNKNOWN this);
- HRESULT (CALLBACK *fnRelease)(LPUNKNOWN this);
-} *LPUNKNOWN_VTABLE;
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID FAR* ppvObj) PURE;
+ STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG,Release) (THIS) PURE;
+} *LPUNKNOWN_VTABLE,IUnknown_VTable;
-struct tagUNKNOWN {
+struct IUnknown {
LPUNKNOWN_VTABLE lpvtbl;
- /* internal stuff. Not needed until we actually implement IUnknown */
+ DWORD ref;
};
+#undef THIS
-typedef struct tagCLASSFACTORY *LPCLASSFACTORY,IClassFactory;
+#define THIS LPCLASSFACTORY this
+typedef struct IClassFactory *LPCLASSFACTORY,IClassFactory;
typedef struct {
- HRESULT (CALLBACK *fnQueryInterface)(LPCLASSFACTORY this,REFIID refiid,LPVOID *obj);
- HRESULT (CALLBACK *fnAddRef)(LPCLASSFACTORY this);
- HRESULT (CALLBACK *fnRelease)(LPCLASSFACTORY this);
- HRESULT (CALLBACK *fnCreateInstance)(LPCLASSFACTORY this,LPUNKNOWN pUnkOuter,REFIID riid,LPVOID * ppvObject);
-} *LPCLASSFACTORY_VTABLE;
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID FAR* ppvObj) PURE;
+ STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG,Release) (THIS) PURE;
+ STDMETHOD(CreateInstance) (THIS_ LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppvObject) PURE;
+} *LPCLASSFACTORY_VTABLE,IClassFactory_VTable;
-struct tagCLASSFACTORY {
- LPCLASSFACTORY_VTABLE lpvtbl;
- /*internal stuff. Not needed until we actually implement IClassFactory*/
+struct IClassFactory {
+ LPCLASSFACTORY_VTABLE lpvtbl;
+ DWORD ref;
};
+#undef THIS
+
+#define THIS LPMALLOC this
+typedef struct IMalloc *LPMALLOC,IMalloc;
+typedef struct {
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid,LPVOID FAR* ppvObj) PURE;
+ STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+ STDMETHOD_(LPVOID,Alloc) ( THIS_ DWORD cb);
+ STDMETHOD_(LPVOID,Realloc) ( THIS_ LPVOID pv,DWORD cb);
+ STDMETHOD_(VOID,Free) ( THIS_ LPVOID pv);
+ STDMETHOD_(DWORD,GetSize) ( THIS_ LPVOID pv);
+ STDMETHOD_(LPINT32,DidAlloc) ( THIS_ LPVOID pv);
+ STDMETHOD_(LPVOID,HeapMinimize) ( THIS );
+} *LPMALLOC_VTABLE,IMalloc_VTable;
+
+struct IMalloc {
+ LPMALLOC_VTABLE lpvtbl;
+ DWORD ref;
+};
+#undef THIS
+
+/* private prototypes for the constructors */
+#ifdef __WINE__
+LPUNKNOWN IUnknown_Constructor();
+LPMALLOC IMalloc_Constructor();
+#endif
+
+#undef STDMETHOD
+#undef STDMETHOD_
+#undef PURE
+#undef FAR
+#undef THIS_
#endif /*_WINE_INTERFACES_H*/
diff --git a/include/mmsystem.h b/include/mmsystem.h
index fa5a50b..6845f35 100644
--- a/include/mmsystem.h
+++ b/include/mmsystem.h
@@ -18,6 +18,7 @@
#define MAXPNAMELEN 32 /* max product name length (including NULL) */
#define MAXERRORLENGTH 128 /* max error text length (including NULL) */
+#define MAX_JOYSTICKOEMVXDNAME 260
typedef WORD VERSION; /* major (high byte), minor (low byte) */
@@ -27,6 +28,9 @@
typedef UINT16 MCIDEVICEID16;
typedef UINT32 MCIDEVICEID32;
DECL_WINELIB_TYPE(MCIDEVICEID);
+typedef UINT16 MMRESULT16;
+typedef UINT32 MMRESULT32;
+DECL_WINELIB_TYPE(MMRESULT);
typedef struct {
UINT16 wType; /* indicates the contents of the union */
@@ -733,24 +737,45 @@
#define TIMERR_NOCANDO (TIMERR_BASE+1) /* request not completed */
#define TIMERR_STRUCT (TIMERR_BASE+33) /* time struct size */
-typedef void (CALLBACK *LPTIMECALLBACK) (UINT16 uTimerID, UINT16 uMessage, DWORD dwUser, DWORD dw1, DWORD dw2);
+typedef void (CALLBACK *LPTIMECALLBACK16)(UINT16 uTimerID, UINT16 uMessage, DWORD dwUser, DWORD dw1, DWORD dw2);
+typedef void (CALLBACK *LPTIMECALLBACK32)(UINT32 uTimerID, UINT32 uMessage, DWORD dwUser, DWORD dw1, DWORD dw2);
+DECL_WINELIB_TYPE(LPTIMECALLBACK);
#define TIME_ONESHOT 0 /* program timer for single event */
#define TIME_PERIODIC 1 /* program for continuous periodic event */
typedef struct {
- UINT16 wPeriodMin; /* minimum period supported */
- UINT16 wPeriodMax; /* maximum period supported */
-} TIMECAPS, *LPTIMECAPS;
+ UINT16 wPeriodMin; /* minimum period supported */
+ UINT16 wPeriodMax; /* maximum period supported */
+} TIMECAPS16,*LPTIMECAPS16;
-UINT16 WINAPI timeGetSystemTime(LPMMTIME16 lpTime, UINT16 uSize);
-DWORD WINAPI timeGetTime(void);
-UINT16 WINAPI timeSetEvent(UINT16 uDelay, UINT16 uResolution,
- LPTIMECALLBACK lpFunction, DWORD dwUser, UINT16 uFlags);
-UINT16 WINAPI timeKillEvent(UINT16 uTimerID);
-UINT16 WINAPI timeGetDevCaps(TIMECAPS * lpTimeCaps, UINT16 uSize);
-UINT16 WINAPI timeBeginPeriod(UINT16 uPeriod);
-UINT16 WINAPI timeEndPeriod(UINT16 uPeriod);
+typedef struct {
+ UINT32 wPeriodMin;
+ UINT32 wPeriodMax;
+} TIMECAPS32, *LPTIMECAPS32;
+
+DECL_WINELIB_TYPE(TIMECAPS);
+DECL_WINELIB_TYPE(LPTIMECAPS);
+
+MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16,UINT16);
+MMRESULT32 WINAPI timeGetSystemTime32(LPMMTIME32,UINT32);
+#define timeGetSystemTime WINELIB_NAME(timeGetSystemTime)
+DWORD WINAPI timeGetTime(); /* same for win32/win16 */
+MMRESULT16 WINAPI timeSetEvent16(UINT16,UINT16,LPTIMECALLBACK16,DWORD,UINT16);
+MMRESULT32 WINAPI timeSetEvent32(UINT32,UINT32,LPTIMECALLBACK32,DWORD,UINT32);
+#define timeSetEvent WINELIB_NAME(timeSetEvent)
+MMRESULT16 WINAPI timeKillEvent16(UINT16);
+MMRESULT32 WINAPI timeKillEvent32(UINT32);
+#define timeKillEvent WINELIB_NAME(timeKillEvent)
+MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16,UINT16);
+MMRESULT32 WINAPI timeGetDevCaps32(LPTIMECAPS32,UINT32);
+#define timeGetDevCaps WINELIB_NAME(timeGetDevCaps)
+MMRESULT16 WINAPI timeBeginPeriod16(UINT16);
+MMRESULT32 WINAPI timeBeginPeriod32(UINT32);
+#define timeBeginPeriod WINELIB_NAME(timeBeginPeriod)
+MMRESULT16 WINAPI timeEndPeriod16(UINT16);
+MMRESULT32 WINAPI timeEndPeriod32(UINT32);
+#define timeEndPeriod WINELIB_NAME(timeEndPeriod)
#define JOYERR_NOERROR (0) /* no error */
#define JOYERR_PARMS (JOYERR_BASE+5) /* bad parameters */
@@ -770,8 +795,8 @@
#define JOYSTICKID2 1
typedef struct {
- UINT16 wMid; /* manufacturer ID */
- UINT16 wPid; /* product ID */
+ WORD wMid; /* manufacturer ID */
+ WORD wPid; /* product ID */
char szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
UINT16 wXmin; /* minimum x position value */
UINT16 wXmax; /* maximum x position value */
@@ -782,23 +807,116 @@
UINT16 wNumButtons; /* number of buttons */
UINT16 wPeriodMin; /* minimum message period when captured */
UINT16 wPeriodMax; /* maximum message period when captured */
-} JOYCAPS, *LPJOYCAPS;
+ /* win95,nt4 additions: */
+ UINT16 wRmin; /* minimum r position value */
+ UINT16 wRmax; /* maximum r position value */
+ UINT16 wUmin; /* minimum u (5th axis) position value */
+ UINT16 wUmax; /* maximum u (5th axis) position value */
+ UINT16 wVmin; /* minimum v (6th axis) position value */
+ UINT16 wVmax; /* maximum v (6th axis) position value */
+ UINT16 wCaps; /* joystick capabilites */
+ UINT16 wMaxAxes; /* maximum number of axes supported */
+ UINT16 wNumAxes; /* number of axes in use */
+ UINT16 wMaxButtons; /* maximum number of buttons supported */
+ CHAR szRegKey[MAXPNAMELEN]; /* registry key */
+ CHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME]; /* OEM VxD in use */
+} JOYCAPS16, *LPJOYCAPS16;
+
+typedef struct {
+ WORD wMid;
+ WORD wPid;
+ CHAR szPname[MAXPNAMELEN];
+ UINT32 wXmin;
+ UINT32 wXmax;
+ UINT32 wYmin;
+ UINT32 wYmax;
+ UINT32 wZmin;
+ UINT32 wZmax;
+ UINT32 wNumButtons;
+ UINT32 wPeriodMin;
+ UINT32 wPeriodMax;
+ UINT32 wRmin;
+ UINT32 wRmax;
+ UINT32 wUmin;
+ UINT32 wUmax;
+ UINT32 wVmin;
+ UINT32 wVmax;
+ UINT32 wCaps;
+ UINT32 wMaxAxes;
+ UINT32 wNumAxes;
+ UINT32 wMaxButtons;
+ CHAR szRegKey[MAXPNAMELEN];
+ CHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME];
+} JOYCAPS32A, *LPJOYCAPS32A;
+
+typedef struct {
+ WORD wMid;
+ WORD wPid;
+ WCHAR szPname[MAXPNAMELEN];
+ UINT32 wXmin;
+ UINT32 wXmax;
+ UINT32 wYmin;
+ UINT32 wYmax;
+ UINT32 wZmin;
+ UINT32 wZmax;
+ UINT32 wNumButtons;
+ UINT32 wPeriodMin;
+ UINT32 wPeriodMax;
+ UINT32 wRmin;
+ UINT32 wRmax;
+ UINT32 wUmin;
+ UINT32 wUmax;
+ UINT32 wVmin;
+ UINT32 wVmax;
+ UINT32 wCaps;
+ UINT32 wMaxAxes;
+ UINT32 wNumAxes;
+ UINT32 wMaxButtons;
+ WCHAR szRegKey[MAXPNAMELEN];
+ WCHAR szOEMVxD[MAX_JOYSTICKOEMVXDNAME];
+} JOYCAPS32W, *LPJOYCAPS32W;
+DECL_WINELIB_TYPE_AW(JOYCAPS)
+DECL_WINELIB_TYPE_AW(LPJOYCAPS)
typedef struct {
UINT16 wXpos; /* x position */
UINT16 wYpos; /* y position */
UINT16 wZpos; /* z position */
UINT16 wButtons; /* button states */
-} JOYINFO, *LPJOYINFO;
+} JOYINFO16, *LPJOYINFO16;
-UINT16 WINAPI joyGetDevCaps(UINT16 uJoyID, JOYCAPS * lpCaps, UINT16 uSize);
-UINT16 WINAPI joyGetNumDevs(void);
-UINT16 WINAPI joyGetPos(UINT16 uJoyID, JOYINFO * lpInfo);
-UINT16 WINAPI joyGetThreshold(UINT16 uJoyID, UINT16 * lpuThreshold);
-UINT16 WINAPI joyReleaseCapture(UINT16 uJoyID);
-UINT16 WINAPI joySetCapture(HWND16 hwnd, UINT16 uJoyID, UINT16 uPeriod,
- BOOL16 bChanged);
-UINT16 WINAPI joySetThreshold(UINT16 uJoyID, UINT16 uThreshold);
+typedef struct {
+ UINT32 wXpos;
+ UINT32 wYpos;
+ UINT32 wZpos;
+ UINT32 wButtons;
+} JOYINFO32, *LPJOYINFO32;
+
+DECL_WINELIB_TYPE(JOYINFO)
+DECL_WINELIB_TYPE(LPJOYINFO)
+
+MMRESULT16 WINAPI joyGetDevCaps16 (UINT16,LPJOYCAPS16 ,UINT16);
+MMRESULT32 WINAPI joyGetDevCaps32A(UINT32,LPJOYCAPS32A,UINT32);
+MMRESULT32 WINAPI joyGetDevCaps32W(UINT32,LPJOYCAPS32W,UINT32);
+#define joyGetDevCaps WINELIB_NAME_AW(joyGetDevCaps)
+UINT16 WINAPI joyGetNumDevs16(void);
+UINT32 WINAPI joyGetNumDevs32(void);
+#define joyGetNumDevs WINELIB_NAME(joyGetNumDevs)
+MMRESULT16 WINAPI joyGetPos16(UINT16,LPJOYINFO16);
+MMRESULT32 WINAPI joyGetPos32(UINT32,LPJOYINFO32);
+#define joyGetPos WINELIB_NAME(joyGetPos)
+MMRESULT16 WINAPI joyGetThreshold16(UINT16,UINT16*);
+MMRESULT32 WINAPI joyGetThreshold32(UINT32,UINT32*);
+#define joyGetThreshold WINELIB_NAME(joyGetThreshold)
+MMRESULT16 WINAPI joyReleaseCapture16(UINT16);
+MMRESULT32 WINAPI joyReleaseCapture32(UINT32);
+#define joyReleaseCapture WINELIB_NAME(joyReleaseCapture)
+MMRESULT16 WINAPI joySetCapture16(HWND16,UINT16,UINT16,BOOL16);
+MMRESULT32 WINAPI joySetCapture32(HWND32,UINT32,UINT32,BOOL32);
+#define joySetCapture WINELIB_NAME(joySetCapture)
+MMRESULT16 WINAPI joySetThreshold16(UINT16,UINT16);
+MMRESULT32 WINAPI joySetThreshold32(UINT32,UINT32);
+#define joySetThreshold WINELIB_NAME(joySetThreshold)
typedef struct {
WORD wMid; /* manufacturer id */
@@ -2560,11 +2678,11 @@
} MIDIOPENDESC, *LPMIDIOPENDESC;
typedef struct {
- UINT16 wDelay;
- UINT16 wResolution;
- LPTIMECALLBACK lpFunction;
- DWORD dwUser;
- UINT16 wFlags;
+ UINT16 wDelay;
+ UINT16 wResolution;
+ LPTIMECALLBACK16 lpFunction;
+ DWORD dwUser;
+ UINT16 wFlags;
} TIMEREVENT, *LPTIMEREVENT;
typedef struct tMIXEROPENDESC
@@ -2603,6 +2721,16 @@
WORD wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
DWORD WINAPI auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
DWORD dwParam1, DWORD dwParam2);
+
+struct LINUX_MCIDRIVER {
+ HDRVR16 hdrv;
+ DRIVERPROC16 driverproc;
+ MCI_OPEN_DRIVER_PARMS modp;
+ MCI_OPEN_PARMS16 mop;
+ DWORD private;
+};
+
+#pragma pack(4)
DWORD WINAPI mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
DWORD dwParam1, DWORD dwParam2);
DWORD WINAPI midMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
diff --git a/include/ntdll.h b/include/ntdll.h
index 2f1bf8b..28f3583 100644
--- a/include/ntdll.h
+++ b/include/ntdll.h
@@ -156,6 +156,27 @@
LPWSTR Buffer;
} UNICODE_STRING,*LPUNICODE_STRING;
+
+BOOL32 WINAPI IsValidSid(LPSID);
+BOOL32 WINAPI EqualSid(LPSID,LPSID);
+BOOL32 WINAPI EqualPrefixSid(LPSID,LPSID);
+DWORD WINAPI GetSidLengthRequired(BYTE);
+BOOL32 WINAPI AllocateAndInitializeSid(LPSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,
+ DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,
+ DWORD,LPSID*);
+VOID* WINAPI FreeSid(LPSID);
+BOOL32 WINAPI InitializeSecurityDescriptor(SECURITY_DESCRIPTOR*,DWORD);
+BOOL32 WINAPI InitializeSid(LPSID,LPSID_IDENTIFIER_AUTHORITY,BYTE);
+DWORD* WINAPI GetSidSubAuthority(LPSID,DWORD);
+BYTE * WINAPI GetSidSubAuthorityCount(LPSID);
+DWORD WINAPI GetLengthSid(LPSID);
+BOOL32 WINAPI CopySid(DWORD,LPSID,LPSID);
+BOOL32 WINAPI LookupAccountSid32A(LPCSTR,PSID,LPCSTR,LPDWORD,LPCSTR,LPDWORD,
+ PSID_NAME_USE);
+BOOL32 WINAPI LookupAccountSid32W(LPCWSTR,PSID,LPCWSTR,LPDWORD,LPCWSTR,LPDWORD,
+ PSID_NAME_USE);
+LPSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(LPSID);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/path.h b/include/path.h
new file mode 100644
index 0000000..fbf00e1
--- /dev/null
+++ b/include/path.h
@@ -0,0 +1,45 @@
+/*
+ * Graphics paths (BeginPath, EndPath etc.)
+ *
+ * Copyright 1997 Martin Boehme
+ */
+
+#ifndef __WINE_PATH_H
+#define __WINE_PATH_H
+
+/* It should not be necessary to access the contents of the GdiPath
+ * structure directly; if you find that the exported functions don't
+ * allow you to do what you want, then please place a new exported
+ * function that does this job in path.c.
+ */
+
+typedef enum tagGdiPathState
+{
+ PATH_Null,
+ PATH_Open,
+ PATH_Closed
+} GdiPathState;
+
+typedef struct tagGdiPath
+{
+ GdiPathState state;
+ POINT32 *pPoints;
+ BYTE *pFlags;
+ int numEntriesUsed, numEntriesAllocated;
+ BOOL32 newStroke;
+} GdiPath;
+
+#define PATH_IsPathOpen(path) ((path).state==PATH_Open)
+/* Returns TRUE if the specified path is in the open state, i.e. in the
+ * state where points will be added to the path, or FALSE otherwise. This
+ * function is implemented as a macro for performance reasons.
+ */
+
+extern void PATH_InitGdiPath(GdiPath *pPath);
+extern void PATH_DestroyGdiPath(GdiPath *pPath);
+extern BOOL32 PATH_AssignGdiPath(GdiPath *pPathDest,
+ const GdiPath *pPathSrc);
+extern BOOL32 PATH_MoveTo(HDC32 hdc);
+extern BOOL32 PATH_LineTo(HDC32 hdc, INT32 x, INT32 y);
+
+#endif /* __WINE_PATH_H */
diff --git a/include/pe_image.h b/include/pe_image.h
index b432c83..b6876e9 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -41,6 +41,6 @@
struct _PDB32; /* forward definition */
extern void PE_InitializeDLLs(struct _PDB32*,DWORD,LPVOID);
-extern LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD);
+extern LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,BOOL32);
#endif /* __WINE_PE_IMAGE_H */
diff --git a/include/shell.h b/include/shell.h
index 2ddf3a3..ee0ba36 100644
--- a/include/shell.h
+++ b/include/shell.h
@@ -32,6 +32,16 @@
/* memory block with filenames follows */
} DROPFILESTRUCT, *LPDROPFILESTRUCT;
+typedef struct _NOTIFYICONDATA {
+ DWORD cbSize;
+ HWND32 hWnd;
+ UINT32 uID;
+ UINT32 uFlags;
+ UINT32 uCallbackMessage;
+ HICON32 hIcon;
+ CHAR szTip[64];
+} NOTIFYICONDATA, *PNOTIFYICONDATA;
+
typedef struct tagSHFILEINFO32A {
HICON32 hIcon; /* icon */
int iIcon; /* icon index */
@@ -59,8 +69,6 @@
LPARAM lParam;
} APPBARDATA, *PAPPBARDATA;
-DECL_WINELIB_TYPE(APPBARDATA);
-
#define SHGFI_ICON 0x000000100 /* get icon */
#define SHGFI_DISPLAYNAME 0x000000200 /* get display name */
#define SHGFI_TYPENAME 0x000000400 /* get type name */
@@ -87,4 +95,22 @@
#define SE_ERR_DDEBUSY 30
#define SE_ERR_NOASSOC 31
+#define CSIDL_DESKTOP 0x0000
+#define CSIDL_PROGRAMS 0x0002
+#define CSIDL_CONTROLS 0x0003
+#define CSIDL_PRINTERS 0x0004
+#define CSIDL_PERSONAL 0x0005
+#define CSIDL_FAVORITES 0x0006
+#define CSIDL_STARTUP 0x0007
+#define CSIDL_RECENT 0x0008
+#define CSIDL_SENDTO 0x0009
+#define CSIDL_BITBUCKET 0x000a
+#define CSIDL_STARTMENU 0x000b
+#define CSIDL_DESKTOPDIRECTORY 0x0010
+#define CSIDL_DRIVES 0x0011
+#define CSIDL_NETWORK 0x0012
+#define CSIDL_NETHOOD 0x0013
+#define CSIDL_FONTS 0x0014
+#define CSIDL_TEMPLATES 0x0015
+
#endif /* __WINE_SHELL_H */
diff --git a/include/shlobj.h b/include/shlobj.h
index bb06efe..d51a190 100644
--- a/include/shlobj.h
+++ b/include/shlobj.h
@@ -1,12 +1,19 @@
#ifndef _WINE_SHLOBJ_H
#define _WINE_SHLOBJ_H
+#include "shell.h"
#include "ole.h"
#include "ole2.h"
#include "compobj.h"
+#define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
+#define STDMETHOD_(type,xfn) type (CALLBACK *fn##xfn)
+#define PURE
+#define FAR
+#define THIS_ THIS,
+
+
typedef LPVOID LPBC; /* *IBindCtx really */
-typedef LPVOID LPSTRRET,LPENUMIDLIST;
/*
* shell32 classids
@@ -28,6 +35,21 @@
DEFINE_SHLGUID(IID_IEnumIDList, 0x000214F2L, 0, 0);
DEFINE_SHLGUID(IID_IFileViewerSite, 0x000214F3L, 0, 0);
+#define STRRET_WSTR 0x0000
+#define STRRET_OFFSET 0x0001
+#define STRRET_CSTR 0x0002
+
+typedef struct _STRRET
+{
+ UINT32 uType; /* STRRET_xxx */
+ union
+ {
+ LPWSTR pOleStr; /* OLESTR that will be freed */
+ UINT32 uOffset; /* Offset into SHITEMID (ANSI) */
+ char cStr[MAX_PATH]; /* Buffer to fill in */
+ } DUMMYUNIONNAME;
+} STRRET,*LPSTRRET;
+
typedef struct {
WORD cb; /* nr of bytes in this item */
BYTE abID[1];/* first byte in this item */
@@ -37,29 +59,198 @@
SHITEMID mkid; /* first itemid in list */
} ITEMIDLIST,*LPITEMIDLIST,*LPCITEMIDLIST;
-/* The IShellFolder interface ... the basic interface for a lot of stuff */
+/*****************************************************************************
+ * IEnumIDList interface
+ */
+#define THIS LPENUMIDLIST this
+
+typedef struct IEnumIDList IEnumIDList,*LPENUMIDLIST;
+typedef struct IEnumIDList_VTable {
+ /* *** IUnknown methods *** */
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+ STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+ /* *** IEnumIDList methods *** */
+ STDMETHOD(Next) (THIS_ ULONG celt,
+ LPITEMIDLIST *rgelt,
+ ULONG *pceltFetched) PURE;
+ STDMETHOD(Skip) (THIS_ ULONG celt) PURE;
+ STDMETHOD(Reset) (THIS) PURE;
+ STDMETHOD(Clone) (THIS_ IEnumIDList **ppenum) PURE;
+} IEnumIDList_VTable,*LPENUMIDLIST_VTABLE;
+
+struct IEnumIDList {
+ LPENUMIDLIST_VTABLE lpvtbl;
+ DWORD ref;
+};
+#undef THIS
+/************************************************************************
+ * The IShellFolder interface ... the basic interface for a lot of stuff
+ */
+
+#define THIS LPSHELLFOLDER this
+
+/* IShellFolder::GetDisplayNameOf/SetNameOf uFlags */
+typedef enum
+{
+ SHGDN_NORMAL = 0, /* default (display purpose) */
+ SHGDN_INFOLDER = 1, /* displayed under a folder (relative)*/
+ SHGDN_FORPARSING = 0x8000, /* for ParseDisplayName or path */
+} SHGNO;
+
+/* IShellFolder::EnumObjects */
+typedef enum tagSHCONTF
+{
+ SHCONTF_FOLDERS = 32, /* for shell browser */
+ SHCONTF_NONFOLDERS = 64, /* for default view */
+ SHCONTF_INCLUDEHIDDEN = 128, /* for hidden/system objects */
+} SHCONTF;
+
+/* from oleidl.h */
+#define DROPEFFECT_NONE 0
+#define DROPEFFECT_COPY 1
+#define DROPEFFECT_MOVE 2
+#define DROPEFFECT_LINK 4
+#define DROPEFFECT_SCROLL 0x80000000
+
+/* IShellFolder::GetAttributesOf flags */
+#define SFGAO_CANCOPY DROPEFFECT_COPY /* Objects can be copied */
+#define SFGAO_CANMOVE DROPEFFECT_MOVE /* Objects can be moved */
+#define SFGAO_CANLINK DROPEFFECT_LINK /* Objects can be linked */
+#define SFGAO_CANRENAME 0x00000010L /* Objects can be renamed */
+#define SFGAO_CANDELETE 0x00000020L /* Objects can be deleted */
+#define SFGAO_HASPROPSHEET 0x00000040L /* Objects have property sheets */
+#define SFGAO_DROPTARGET 0x00000100L /* Objects are drop target */
+#define SFGAO_CAPABILITYMASK 0x00000177L
+#define SFGAO_LINK 0x00010000L /* Shortcut (link) */
+#define SFGAO_SHARE 0x00020000L /* shared */
+#define SFGAO_READONLY 0x00040000L /* read-only */
+#define SFGAO_GHOSTED 0x00080000L /* ghosted icon */
+#define SFGAO_DISPLAYATTRMASK 0x000F0000L
+#define SFGAO_FILESYSANCESTOR 0x10000000L /* It contains file system folder */
+#define SFGAO_FOLDER 0x20000000L /* It's a folder. */
+#define SFGAO_FILESYSTEM 0x40000000L /* is a file system thing (file/folder/root) */
+#define SFGAO_HASSUBFOLDER 0x80000000L /* Expandable in the map pane */
+#define SFGAO_CONTENTSMASK 0x80000000L
+#define SFGAO_VALIDATE 0x01000000L /* invalidate cached information */
+#define SFGAO_REMOVABLE 0x02000000L /* is this removeable media? */
+
typedef struct tagSHELLFOLDER *LPSHELLFOLDER,IShellFolder;
-typedef struct {
- HRESULT (CALLBACK *fnQueryInterface)(LPSHELLFOLDER this,REFIID refiid,LPVOID *obj);
- HRESULT (CALLBACK *fnAddRef)(LPSHELLFOLDER this);
- HRESULT (CALLBACK *fnRelease)(LPSHELLFOLDER this);
- /* IShellFolder methods */
+typedef struct IShellFolder_VTable {
+ /* *** IUnknown methods *** */
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+ STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG,Release) (THIS) PURE;
- HRESULT (CALLBACK *fnParseDisplayName) (LPSHELLFOLDER this,HWND32 hwndOwner,LPBC pbcReserved,LPOLESTR lpszDisplayName,DWORD * pchEaten,LPITEMIDLIST * ppidl, DWORD *pdwAttributes) ;
-
- HRESULT (CALLBACK *fnEnumObjects)( LPSHELLFOLDER this,HWND32 hwndOwner, DWORD grfFlags, LPENUMIDLIST* ppenumIDList);
- HRESULT (CALLBACK *fnBindToObject)(LPSHELLFOLDER this, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut);
- HRESULT (CALLBACK *fnBindToStorage)(LPSHELLFOLDER this, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvObj);
- HRESULT (CALLBACK *fnCompareIDs) (LPSHELLFOLDER this, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
- HRESULT (CALLBACK *fnCreateViewObject) (LPSHELLFOLDER this, HWND32 hwndOwner, REFIID riid, LPVOID * ppvOut);
- HRESULT (CALLBACK *fnGetAttributesOf) (LPSHELLFOLDER this, UINT32 cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut);
- HRESULT (CALLBACK *fnGetUIObjectOf) (LPSHELLFOLDER this, HWND32 hwndOwner, UINT32 cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT32 * prgfInOut, LPVOID * ppvOut);
- HRESULT (CALLBACK *fnGetDisplayNameOf) (LPSHELLFOLDER this, LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName);
- HRESULT (CALLBACK *fnSetNameOf) (LPSHELLFOLDER this, HWND32 hwndOwner, LPCITEMIDLIST pidl, LPCOLESTR lpszName, DWORD uFlags, LPITEMIDLIST * ppidlOut);
-} *LPSHELLFOLDER_VTABLE;
+ /* *** IShellFolder methods *** */
+ STDMETHOD(ParseDisplayName) (THIS_ HWND32 hwndOwner,
+ LPBC pbcReserved, LPOLESTR lpszDisplayName,
+ ULONG * pchEaten, LPITEMIDLIST * ppidl, ULONG *pdwAttributes) PURE;
+ STDMETHOD(EnumObjects) ( THIS_ HWND32 hwndOwner, DWORD grfFlags, LPENUMIDLIST
+* ppenumIDList) PURE;
+ STDMETHOD(BindToObject) (THIS_ LPCITEMIDLIST pidl, LPBC pbcReserved,
+ REFIID riid, LPVOID * ppvOut) PURE;
+ STDMETHOD(BindToStorage) (THIS_ LPCITEMIDLIST pidl, LPBC pbcReserved,
+ REFIID riid, LPVOID * ppvObj) PURE;
+ STDMETHOD(CompareIDs) (THIS_ LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) PURE;
+ STDMETHOD(CreateViewObject) (THIS_ HWND32 hwndOwner, REFIID riid, LPVOID * ppvOut) PURE;
+ STDMETHOD(GetAttributesOf) (THIS_ UINT32 cidl, LPCITEMIDLIST * apidl,
+ ULONG * rgfInOut) PURE;
+ STDMETHOD(GetUIObjectOf) (THIS_ HWND32 hwndOwner, UINT32 cidl, LPCITEMIDLIST
+* apidl,
+ REFIID riid, UINT32 * prgfInOut, LPVOID * ppvOut) PURE;
+ STDMETHOD(GetDisplayNameOf) (THIS_ LPCITEMIDLIST pidl, DWORD uFlags, LPSTRRET lpName) PURE;
+ STDMETHOD(SetNameOf) (THIS_ HWND32 hwndOwner, LPCITEMIDLIST pidl,
+ LPCOLESTR lpszName, DWORD uFlags,
+ LPITEMIDLIST * ppidlOut) PURE;
+} *LPSHELLFOLDER_VTABLE,IShellFolder_VTable;
struct tagSHELLFOLDER {
- LPSHELLFOLDER_VTABLE *lpvtbl;
+ LPSHELLFOLDER_VTABLE lpvtbl;
+ DWORD ref;
};
+
+#undef THIS
+
+/****************************************************************************
+ * IShellLink interface
+ */
+
+#define THIS LPSHELLLINK this
+/* IShellLink::Resolve fFlags */
+typedef enum {
+ SLR_NO_UI = 0x0001,
+ SLR_ANY_MATCH = 0x0002,
+ SLR_UPDATE = 0x0004,
+} SLR_FLAGS;
+
+/* IShellLink::GetPath fFlags */
+typedef enum {
+ SLGP_SHORTPATH = 0x0001,
+ SLGP_UNCPRIORITY = 0x0002,
+} SLGP_FLAGS;
+
+
+
+typedef struct IShellLink IShellLink,*LPSHELLLINK;
+typedef struct IShellLink_VTable
+{
+ // *** IUnknown methods ***
+ STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+ STDMETHOD_(ULONG,AddRef) (THIS) PURE;
+ STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+ STDMETHOD(GetPath)(THIS_ LPSTR pszFile, INT32 cchMaxPath, WIN32_FIND_DATA32A *pfd, DWORD fFlags) PURE;
+
+ STDMETHOD(GetIDList)(THIS_ LPITEMIDLIST * ppidl) PURE;
+ STDMETHOD(SetIDList)(THIS_ LPCITEMIDLIST pidl) PURE;
+
+ STDMETHOD(GetDescription)(THIS_ LPSTR pszName, int cchMaxName) PURE;
+ STDMETHOD(SetDescription)(THIS_ LPCSTR pszName) PURE;
+
+ STDMETHOD(GetWorkingDirectory)(THIS_ LPSTR pszDir, int cchMaxPath) PURE;
+ STDMETHOD(SetWorkingDirectory)(THIS_ LPCSTR pszDir) PURE;
+
+ STDMETHOD(GetArguments)(THIS_ LPSTR pszArgs, int cchMaxPath) PURE;
+ STDMETHOD(SetArguments)(THIS_ LPCSTR pszArgs) PURE;
+
+ STDMETHOD(GetHotkey)(THIS_ WORD *pwHotkey) PURE;
+ STDMETHOD(SetHotkey)(THIS_ WORD wHotkey) PURE;
+
+ STDMETHOD(GetShowCmd)(THIS_ INT32 *piShowCmd) PURE;
+ STDMETHOD(SetShowCmd)(THIS_ INT32 iShowCmd) PURE;
+
+ STDMETHOD(GetIconLocation)(THIS_ LPSTR pszIconPath, INT32 cchIconPath, INT32 *piIcon) PURE;
+ STDMETHOD(SetIconLocation)(THIS_ LPCSTR pszIconPath, INT32 iIcon) PURE;
+
+ STDMETHOD(SetRelativePath)(THIS_ LPCSTR pszPathRel, DWORD dwReserved) PURE;
+
+ STDMETHOD(Resolve)(THIS_ HWND32 hwnd, DWORD fFlags) PURE;
+
+ STDMETHOD(SetPath)(THIS_ LPCSTR pszFile) PURE;
+} IShellLink_VTable,*LPSHELLLINK_VTABLE;
+
+struct IShellLink {
+ LPSHELLLINK_VTABLE lpvtbl;
+ DWORD ref;
+};
+
+#undef THIS
+
+#ifdef __WINE__
+extern LPSHELLFOLDER IShellFolder_Constructor();
+extern LPSHELLLINK IShellLink_Constructor();
+extern LPENUMIDLIST IEnumIDList_Constructor();
+#endif
+
+DWORD WINAPI SHELL32_DllGetClassObject(LPCLSID,REFIID,LPVOID*);
+
+#undef PURE
+#undef FAR
+#undef THIS
+#undef THIS_
+#undef STDMETHOD
+#undef STDMETHOD_
#endif /*_WINE_SHLOBJ_H*/
diff --git a/include/stddebug.h b/include/stddebug.h
index 8f73efc..0f51994 100644
--- a/include/stddebug.h
+++ b/include/stddebug.h
@@ -148,6 +148,7 @@
#undef DEBUG_STRING
#undef DEBUG_TASK
#undef DEBUG_TEXT
+#undef DEBUG_THUNK
#undef DEBUG_TIMER
#undef DEBUG_TOOLHELP
#undef DEBUG_TWEAK
@@ -234,6 +235,7 @@
#define DEBUG_STRING
#define DEBUG_TASK
#define DEBUG_TEXT
+#define DEBUG_THUNK
#define DEBUG_TIMER
#define DEBUG_TOOLHELP
#define DEBUG_TWEAK
diff --git a/include/task.h b/include/task.h
index ef54135..460f5de 100644
--- a/include/task.h
+++ b/include/task.h
@@ -131,5 +131,6 @@
UINT16 cmdShow );
extern void TASK_KillCurrentTask( INT16 exitCode );
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
+extern void TASK_Reschedule(void);
#endif /* __WINE_TASK_H */
diff --git a/include/toolhelp.h b/include/toolhelp.h
index 8d1cd81..1d2ddb7 100644
--- a/include/toolhelp.h
+++ b/include/toolhelp.h
@@ -348,6 +348,18 @@
void **lpBadParam;
} NFYLOGPARAMERROR;
+typedef struct {
+ DWORD dwSize;
+ HTASK16 hTask;
+ WORD wSS;
+ WORD wBP;
+ WORD wCS;
+ WORD wIP;
+ HMODULE16 hModule;
+ WORD wSegment;
+ WORD wFlags;
+} STACKTRACEENTRY;
+
#pragma pack(4)
#endif /* __WINE_TOOLHELP_H */
diff --git a/include/user.h b/include/user.h
index 68e023f..b235b76 100644
--- a/include/user.h
+++ b/include/user.h
@@ -24,5 +24,8 @@
((handle) ? PTR_SEG_OFF_TO_SEGPTR(USER_HeapSel, (handle)) : (SEGPTR)0)
void USER_SignalProc(HANDLE16, UINT16, UINT16, HINSTANCE16, HQUEUE16);
+void USER_ExitWindows(void);
+HGLOBAL16 USER_CallDefaultRsrcHandler( HGLOBAL16 hMemObj, HMODULE16 hModule,
+ HRSRC16 hRsrc );
#endif /* __WINE_USER_H */
diff --git a/include/version.h b/include/version.h
index b0cfc85..d3413e2 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define WINE_RELEASE_INFO "Wine release 971130"
+#define WINE_RELEASE_INFO "Wine release 971221"
diff --git a/include/windows.h b/include/windows.h
index 997208a..86cb5b8 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1591,13 +1591,30 @@
DECL_WINELIB_TYPE(LOGPEN);
DECL_WINELIB_TYPE(LPLOGPEN);
-#define PS_SOLID 0
-#define PS_DASH 1
-#define PS_DOT 2
-#define PS_DASHDOT 3
-#define PS_DASHDOTDOT 4
-#define PS_NULL 5
-#define PS_INSIDEFRAME 6
+#define PS_SOLID 0x00000000
+#define PS_DASH 0x00000001
+#define PS_DOT 0x00000002
+#define PS_DASHDOT 0x00000003
+#define PS_DASHDOTDOT 0x00000004
+#define PS_NULL 0x00000005
+#define PS_INSIDEFRAME 0x00000006
+#define PS_USERSTYLE 0x00000007
+#define PS_ALTERNATE 0x00000008
+#define PS_STYLE_MASK 0x0000000f
+
+#define PS_ENDCAP_ROUND 0x00000000
+#define PS_ENDCAP_SQUARE 0x00000100
+#define PS_ENDCAP_FLAT 0x00000200
+#define PS_ENDCAP_MASK 0x00000f00
+
+#define PS_JOIN_ROUND 0x00000000
+#define PS_JOIN_BEVEL 0x00001000
+#define PS_JOIN_MITER 0x00002000
+#define PS_JOIN_MASK 0x0000f000
+
+#define PS_COSMETIC 0x00000000
+#define PS_GEOMETRIC 0x00010000
+#define PS_TYPE_MASK 0x000f0000
/* Regions */
@@ -1947,6 +1964,10 @@
HBITMAP32 hbmColor;
} ICONINFO,*LPICONINFO;
+#ifdef FSHIFT
+/* Gcc on Solaris has a version of this that we don't care about. */
+#undef FSHIFT
+#endif
#define FVIRTKEY TRUE /* Assumed to be == TRUE */
#define FNOINVERT 0x02
@@ -2557,6 +2578,7 @@
#define DEVICE_DEFAULT_FONT 14
#define DEFAULT_PALETTE 15
#define SYSTEM_FIXED_FONT 16
+#define DEFAULT_GUI_FONT 17
/* DragObject stuff */
@@ -3038,33 +3060,47 @@
#define GCW_HBRBACKGROUND (-10)
#endif
-#define MB_OK 0x0000
-#define MB_OKCANCEL 0x0001
-#define MB_ABORTRETRYIGNORE 0x0002
-#define MB_YESNOCANCEL 0x0003
-#define MB_YESNO 0x0004
-#define MB_RETRYCANCEL 0x0005
-#define MB_TYPEMASK 0x000F
+#define MB_OK 0x00000000
+#define MB_OKCANCEL 0x00000001
+#define MB_ABORTRETRYIGNORE 0x00000002
+#define MB_YESNOCANCEL 0x00000003
+#define MB_YESNO 0x00000004
+#define MB_RETRYCANCEL 0x00000005
+#define MB_TYPEMASK 0x0000000F
-#define MB_ICONHAND 0x0010
-#define MB_ICONQUESTION 0x0020
-#define MB_ICONEXCLAMATION 0x0030
-#define MB_ICONASTERISK 0x0040
-#define MB_ICONMASK 0x00F0
+#define MB_ICONHAND 0x00000010
+#define MB_ICONQUESTION 0x00000020
+#define MB_ICONEXCLAMATION 0x00000030
+#define MB_ICONASTERISK 0x00000040
+#define MB_USERICON 0x00000080
+#define MB_ICONMASK 0x000000F0
-#define MB_ICONINFORMATION MB_ICONASTERISK
-#define MB_ICONSTOP MB_ICONHAND
+#define MB_ICONINFORMATION MB_ICONASTERISK
+#define MB_ICONSTOP MB_ICONHAND
+#define MB_ICONWARNING MB_ICONEXCLAMATION
+#define MB_ICONERROR MB_ICONHAND
-#define MB_DEFBUTTON1 0x0000
-#define MB_DEFBUTTON2 0x0100
-#define MB_DEFBUTTON3 0x0200
-#define MB_DEFMASK 0x0F00
+#define MB_DEFBUTTON1 0x00000000
+#define MB_DEFBUTTON2 0x00000100
+#define MB_DEFBUTTON3 0x00000200
+#define MB_DEFBUTTON4 0x00000300
+#define MB_DEFMASK 0x00000F00
-#define MB_APPLMODAL 0x0000
-#define MB_SYSTEMMODAL 0x1000
-#define MB_TASKMODAL 0x2000
+#define MB_APPLMODAL 0x00000000
+#define MB_SYSTEMMODAL 0x00001000
+#define MB_TASKMODAL 0x00002000
+#define MB_MODEMASK 0x00003000
-#define MB_NOFOCUS 0x8000
+#define MB_HELP 0x00004000
+#define MB_NOFOCUS 0x00008000
+#define MB_MISCMASK 0x0000C000
+
+#define MB_SETFOREGROUND 0x00010000
+#define MB_DEFAULT_DESKTOP_ONLY 0x00020000
+#define MB_SERVICE_NOTIFICATION 0x00040000
+#define MB_TOPMOST 0x00040000
+#define MB_RIGHT 0x00080000
+#define MB_RTLREADING 0x00100000
#define DT_TOP 0
@@ -3165,7 +3201,9 @@
#define DFCS_MONO 0x8000
/* DrawState defines ... */
-typedef BOOL32 (CALLBACK *DRAWSTATEPROC)(HDC32,LPARAM,WPARAM32,INT32,INT32);
+typedef BOOL16 (CALLBACK *DRAWSTATEPROC16)(HDC16,LPARAM,WPARAM16,INT16,INT16);
+typedef BOOL32 (CALLBACK *DRAWSTATEPROC32)(HDC32,LPARAM,WPARAM32,INT32,INT32);
+DECL_WINELIB_TYPE(DRAWSTATEPROC);
/* Image type */
#define DST_COMPLEX 0x0000
@@ -3178,6 +3216,7 @@
#define DSS_NORMAL 0x0000
#define DSS_UNION 0x0010 /* Gray string appearance */
#define DSS_DISABLED 0x0020
+#define DSS_DEFAULT 0x0040 /* Make it bold */
#define DSS_MONO 0x0080
#define DSS_RIGHT 0x8000
@@ -4875,6 +4914,20 @@
DECL_WINELIB_TYPE_AW(DEVMODE);
DECL_WINELIB_TYPE_AW(LPDEVMODE);
+typedef struct _PRINTER_DEFAULTS32A {
+ LPSTR pDatatype;
+ LPDEVMODE32A pDevMode;
+ ACCESS_MASK DesiredAccess;
+} PRINTER_DEFAULTS32A, *LPPRINTER_DEFAULTS32A;
+
+typedef struct _PRINTER_DEFAULTS32W {
+ LPWSTR pDatatype;
+ LPDEVMODE32W pDevMode;
+ ACCESS_MASK DesiredAccess;
+} PRINTER_DEFAULTS32W, *LPPRINTER_DEFAULTS32W;
+
+DECL_WINELIB_TYPE_AW(PRINTER_DEFAULTS);
+
typedef struct _SYSTEM_POWER_STATUS
{
BOOL16 ACLineStatus;
@@ -4910,6 +4963,12 @@
#define LR_LOADREALSIZE 0x0020
#define LR_LOADMAP3DCOLORS 0x1000
+/* Flags for PolyDraw and GetPath */
+#define PT_CLOSEFIGURE 0x0001
+#define PT_LINETO 0x0002
+#define PT_BEZIERTO 0x0004
+#define PT_MOVETO 0x0006
+
typedef struct _LARGE_INTEGER
{
DWORD LowPart;
@@ -5333,6 +5392,79 @@
} HighWord;
} LDT_ENTRY, *LPLDT_ENTRY;
+#define RDH_RECTANGLES 1
+
+typedef struct _RGNDATAHEADER {
+ DWORD dwSize;
+ DWORD iType;
+ DWORD nCount;
+ DWORD nRgnSize;
+ RECT32 rcBound;
+} RGNDATAHEADER,*LPRGNDATAHEADER;
+
+typedef struct _RGNDATA {
+ RGNDATAHEADER rdh;
+ char Buffer[1];
+} RGNDATA,*PRGNDATA,*LPRGNDATA;
+
+#define HELPINFO_WINDOW 0x0001
+#define HELPINFO_MENUITEM 0x0002
+typedef struct /* Structure pointed to by lParam of WM_HELP */
+{
+ UINT32 cbSize; /* Size in bytes of this struct */
+ INT32 iContextType; /* Either HELPINFO_WINDOW or HELPINFO_MENUITEM */
+ INT32 iCtrlId; /* Control Id or a Menu item Id. */
+ HANDLE32 hItemHandle; /* hWnd of control or hMenu. */
+ DWORD dwContextId; /* Context Id associated with this item */
+ POINT32 MousePos; /* Mouse Position in screen co-ordinates */
+} HELPINFO,*LPHELPINFO;
+
+typedef void (CALLBACK *MSGBOXCALLBACK)(LPHELPINFO lpHelpInfo);
+
+typedef struct /* not sure if the 16bit version is correct */
+{
+ UINT16 cbSize;
+ HWND16 hwndOwner;
+ HINSTANCE16 hInstance;
+ LPCSTR lpszText;
+ LPCSTR lpszCaption;
+ DWORD dwStyle;
+ LPCSTR lpszIcon;
+ DWORD dwContextHelpId;
+ MSGBOXCALLBACK lpfnMsgBoxCallback;
+ DWORD dwLanguageId;
+} MSGBOXPARAMS16,*LPMSGBOXPARAMS16;
+
+typedef struct
+{
+ UINT32 cbSize;
+ HWND32 hwndOwner;
+ HINSTANCE32 hInstance;
+ LPCSTR lpszText;
+ LPCSTR lpszCaption;
+ DWORD dwStyle;
+ LPCSTR lpszIcon;
+ DWORD dwContextHelpId;
+ MSGBOXCALLBACK lpfnMsgBoxCallback;
+ DWORD dwLanguageId;
+} MSGBOXPARAMS32A,*LPMSGBOXPARAMS32A;
+
+typedef struct
+{
+ UINT32 cbSize;
+ HWND32 hwndOwner;
+ HINSTANCE32 hInstance;
+ LPCWSTR lpszText;
+ LPCWSTR lpszCaption;
+ DWORD dwStyle;
+ LPCWSTR lpszIcon;
+ DWORD dwContextHelpId;
+ MSGBOXCALLBACK lpfnMsgBoxCallback;
+ DWORD dwLanguageId;
+} MSGBOXPARAMS32W,*LPMSGBOXPARAMS32W;
+
+DECL_WINELIB_TYPE_AW(MSGBOXPARAMS)
+
#pragma pack(4)
/* Declarations for functions that exist only in Win16 */
@@ -5390,6 +5522,7 @@
DWORD WINAPI GetFileResourceSize(LPCSTR,SEGPTR,SEGPTR,LPDWORD);
DWORD WINAPI GetFileResource(LPCSTR,SEGPTR,SEGPTR,DWORD,DWORD,LPVOID);
DWORD WINAPI GetHeapSpaces(HMODULE16);
+WORD WINAPI GetIconID(HGLOBAL16,DWORD);
INT16 WINAPI GetInstanceData(HINSTANCE16,WORD,INT16);
HGLOBAL16 WINAPI GetMetaFileBits(HMETAFILE16);
BOOL16 WINAPI GetModuleName(HINSTANCE16,LPSTR,INT16);
@@ -5434,6 +5567,7 @@
WORD WINAPI LocalCountFree(void);
WORD WINAPI LocalHandleDelta(WORD);
WORD WINAPI LocalHeapSize(void);
+HICON16 WINAPI LoadIconHandler(HGLOBAL16,BOOL16);
BOOL16 WINAPI LocalInit(HANDLE16,WORD,WORD);
FARPROC16 WINAPI LocalNotify(FARPROC16);
HTASK16 WINAPI LockCurrentTask(BOOL16);
@@ -5509,6 +5643,7 @@
HFILE32 WINAPI CreateFile32W(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,
DWORD,DWORD,HANDLE32);
#define CreateFile WINELIB_NAME_AW(CreateFile)
+HPALETTE32 WINAPI CreateHalftonePalette(HDC32);
HANDLE32 WINAPI CreateFileMapping32A(HANDLE32,LPSECURITY_ATTRIBUTES,DWORD,
DWORD,DWORD,LPCSTR);
HANDLE32 WINAPI CreateFileMapping32W(HANDLE32,LPSECURITY_ATTRIBUTES,DWORD,
@@ -5558,7 +5693,11 @@
HRSRC32 WINAPI FindResourceEx32A(HINSTANCE32,LPCSTR,LPCSTR,WORD);
HRSRC32 WINAPI FindResourceEx32W(HINSTANCE32,LPCWSTR,LPCWSTR,WORD);
#define FindResourceEx WINELIB_NAME_AW(FindResourceEx)
+BOOL32 WINAPI FlushConsoleInputBuffer(HANDLE32);
BOOL32 WINAPI FlushFileBuffers(HFILE32);
+DWORD WINAPI FormatMessage32A(DWORD,LPCVOID,DWORD,DWORD,LPSTR,
+ DWORD,LPDWORD);
+#define FormatMessage WINELIB_NAME_AW(FormatMessage)
BOOL32 WINAPI FreeEnvironmentStrings32A(LPSTR);
BOOL32 WINAPI FreeEnvironmentStrings32W(LPWSTR);
#define FreeEnvironmentStrings WINELIB_NAME_AW(FreeEnvironmentStrings)
@@ -5570,7 +5709,14 @@
BOOL32 WINAPI GetComputerName32A(LPSTR,LPDWORD);
BOOL32 WINAPI GetComputerName32W(LPWSTR,LPDWORD);
#define GetComputerName WINELIB_NAME_AW(GetComputerName)
+UINT32 WINAPI GetConsoleCP();
+BOOL32 WINAPI GetConsoleMode(HANDLE32,LPDWORD);
+UINT32 WINAPI GetConsoleOutputCP();
+DWORD WINAPI GetConsoleTitle32A(LPSTR,DWORD);
+DWORD WINAPI GetConsoleTitle32W(LPWSTR,DWORD);
+#define GetConsoleTitle WINELIB_NAME_AW(GetConsoleTitle)
BOOL32 WINAPI GetCPInfo(UINT32,LPCPINFO);
+HANDLE32 WINAPI GetCurrentObject(HDC32,UINT32);
HANDLE32 WINAPI GetCurrentProcess(void);
DWORD WINAPI GetCurrentProcessId(void);
HANDLE32 WINAPI GetCurrentThread(void);
@@ -5589,11 +5735,14 @@
DWORD WINAPI GetFullPathName32A(LPCSTR,DWORD,LPSTR,LPSTR*);
DWORD WINAPI GetFullPathName32W(LPCWSTR,DWORD,LPWSTR,LPWSTR*);
#define GetFullPathName WINELIB_NAME_AW(GetFullPathName)
+DWORD WINAPI GetLargestConsoleWindowSize(HANDLE32);
VOID WINAPI GetLocalTime(LPSYSTEMTIME);
DWORD WINAPI GetLogicalDrives(void);
BOOL32 WINAPI GetMenuItemInfo32A(HMENU32,UINT32,BOOL32,MENUITEMINFO32A*);
BOOL32 WINAPI GetMenuItemInfo32W(HMENU32,UINT32,BOOL32,MENUITEMINFO32W*);
#define GetMenuItemInfo WINELIB_NAME_AW(GetMenuItemInfo)
+BOOL32 WINAPI GetNumberOfConsoleInputEvents(HANDLE32,LPDWORD);
+BOOL32 WINAPI GetNumberOfConsoleMouseButtons(LPDWORD);
DWORD WINAPI GetObjectType(HANDLE32);
UINT32 WINAPI GetOEMCP(void);
DWORD WINAPI GetPriorityClass(HANDLE32);
@@ -5635,6 +5784,7 @@
BOOL32 WINAPI HeapUnlock(HANDLE32);
BOOL32 WINAPI HeapValidate(HANDLE32,DWORD,LPCVOID);
BOOL32 WINAPI IsDBCSLeadByteEx(UINT32,BYTE);
+BOOL32 WINAPI IsProcessorFeaturePresent(DWORD);
BOOL32 WINAPI IsWindowUnicode(HWND32);
BOOL32 WINAPI IsValidLocale(DWORD,DWORD);
BOOL32 WINAPI LocalFileTimeToFileTime(const FILETIME*,LPFILETIME);
@@ -5702,6 +5852,7 @@
BOOL32 WINAPI SetBrushOrgEx(HDC32,INT32,INT32,LPPOINT32);
BOOL32 WINAPI SetCommMask(INT32,DWORD);
BOOL32 WINAPI SetCommTimeouts(INT32,LPCOMMTIMEOUTS);
+BOOL32 WINAPI SetConsoleMode(HANDLE32,DWORD);
BOOL32 WINAPI SetConsoleTitle32A(LPCSTR);
BOOL32 WINAPI SetConsoleTitle32W(LPCWSTR);
#define SetConsoleTitle WINELIB_NAME_AW(SetConsoleTitle)
@@ -5743,8 +5894,8 @@
BOOL32 WINAPI VirtualQuery(LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD);
BOOL32 WINAPI VirtualQueryEx(HANDLE32,LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD);
BOOL32 WINAPI VirtualUnlock(LPVOID,DWORD);
-BOOL32 WINAPI WriteConsole32A(HANDLE32,LPVOID,DWORD,LPDWORD,LPVOID);
-BOOL32 WINAPI WriteConsole32W(HANDLE32,LPVOID,DWORD,LPDWORD,LPVOID);
+BOOL32 WINAPI WriteConsole32A(HANDLE32,LPCVOID,DWORD,LPDWORD,LPVOID);
+BOOL32 WINAPI WriteConsole32W(HANDLE32,LPCVOID,DWORD,LPDWORD,LPVOID);
#define WriteConsole WINELIB_NAME_AW(WriteConsole)
BOOL32 WINAPI WriteFile(HFILE32,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
@@ -5778,6 +5929,9 @@
/* Declarations for functions that change between Win16 and Win32 */
+BOOL16 WINAPI AbortPath16(HDC16);
+BOOL32 WINAPI AbortPath32(HDC32);
+#define AbortPath WINELIB_NAME(AbortPath)
LRESULT WINAPI AboutDlgProc16(HWND16,UINT16,WPARAM16,LPARAM);
LRESULT WINAPI AboutDlgProc32(HWND32,UINT32,WPARAM32,LPARAM);
#define AboutDlgProc WINELIB_NAME(AboutDlgProc)
@@ -5855,6 +6009,9 @@
HDC16 WINAPI BeginPaint16(HWND16,LPPAINTSTRUCT16);
HDC32 WINAPI BeginPaint32(HWND32,LPPAINTSTRUCT32);
#define BeginPaint WINELIB_NAME(BeginPaint)
+BOOL16 WINAPI BeginPath16(HDC16);
+BOOL32 WINAPI BeginPath32(HDC32);
+#define BeginPath WINELIB_NAME(BeginPath)
BOOL16 WINAPI BitBlt16(HDC16,INT16,INT16,INT16,INT16,HDC16,INT16,INT16,DWORD);
BOOL32 WINAPI BitBlt32(HDC32,INT32,INT32,INT32,INT32,HDC32,INT32,INT32,DWORD);
#define BitBlt WINELIB_NAME(BitBlt)
@@ -5946,6 +6103,9 @@
BOOL16 WINAPI CloseClipboard16(void);
BOOL32 WINAPI CloseClipboard32(void);
#define CloseClipboard WINELIB_NAME(CloseClipboard)
+BOOL16 WINAPI CloseFigure16(HDC16);
+BOOL32 WINAPI CloseFigure32(HDC32);
+#define CloseFigure WINELIB_NAME(CloseFigure)
HMETAFILE16 WINAPI CloseMetaFile16(HDC16);
HMETAFILE32 WINAPI CloseMetaFile32(HDC32);
#define CloseMetaFile WINELIB_NAME(CloseMetaFile)
@@ -6304,6 +6464,9 @@
BOOL16 WINAPI EndPaint16(HWND16,const PAINTSTRUCT16*);
BOOL32 WINAPI EndPaint32(HWND32,const PAINTSTRUCT32*);
#define EndPaint WINELIB_NAME(EndPaint)
+BOOL16 WINAPI EndPath16(HDC16);
+BOOL32 WINAPI EndPath32(HDC32);
+#define EndPath WINELIB_NAME(EndPath)
BOOL16 WINAPI EnumChildWindows16(HWND16,WNDENUMPROC16,LPARAM);
BOOL32 WINAPI EnumChildWindows32(HWND32,WNDENUMPROC32,LPARAM);
#define EnumChildWindows WINELIB_NAME(EnumChildWindows)
@@ -6360,6 +6523,9 @@
BOOL16 WINAPI ExitWindows16(DWORD,UINT16);
#define ExitWindows32(a,b) ExitWindowsEx(EWX_LOGOFF,0xffffffff)
#define ExitWindows WINELIB_NAME(ExitWindows)
+HPEN16 WINAPI ExtCreatePen16(DWORD,DWORD,const LOGBRUSH16*,DWORD,const DWORD*);
+HPEN32 WINAPI ExtCreatePen32(DWORD,DWORD,const LOGBRUSH32*,DWORD,const DWORD*);
+#define ExtCreatePen WINELIB_NAME(ExtCreatePen)
BOOL16 WINAPI ExtFloodFill16(HDC16,INT16,INT16,COLORREF,UINT16);
BOOL32 WINAPI ExtFloodFill32(HDC32,INT32,INT32,COLORREF,UINT32);
#define ExtFloodFill WINELIB_NAME(ExtFloodFill)
@@ -6382,6 +6548,9 @@
void WINAPI FatalAppExit32A(UINT32,LPCSTR);
void WINAPI FatalAppExit32W(UINT32,LPCWSTR);
#define FatalAppExit WINELIB_NAME_AW(FatalAppExit)
+BOOL16 WINAPI FillPath16(HDC16);
+BOOL32 WINAPI FillPath32(HDC32);
+#define FillPath WINELIB_NAME(FillPath)
INT16 WINAPI FillRect16(HDC16,const RECT16*,HBRUSH16);
INT32 WINAPI FillRect32(HDC32,const RECT32*,HBRUSH32);
#define FillRect WINELIB_NAME(FillRect)
@@ -6402,11 +6571,11 @@
HANDLE16 WINAPI FindFirstFile16(LPCSTR,LPWIN32_FIND_DATA32A);
HANDLE32 WINAPI FindFirstFile32A(LPCSTR,LPWIN32_FIND_DATA32A);
HANDLE32 WINAPI FindFirstFile32W(LPCWSTR,LPWIN32_FIND_DATA32W);
-#define FindFirst WINELIB_NAME_AW(FindFirst)
+#define FindFirstFile WINELIB_NAME_AW(FindFirstFile)
BOOL16 WINAPI FindNextFile16(HANDLE16,LPWIN32_FIND_DATA32A);
BOOL32 WINAPI FindNextFile32A(HANDLE32,LPWIN32_FIND_DATA32A);
BOOL32 WINAPI FindNextFile32W(HANDLE32,LPWIN32_FIND_DATA32W);
-#define FindNext WINELIB_NAME_AW(FindNext)
+#define FindNextFile WINELIB_NAME_AW(FindNextFile)
HRSRC16 WINAPI FindResource16(HINSTANCE16,SEGPTR,SEGPTR);
HRSRC32 WINAPI FindResource32A(HINSTANCE32,LPCSTR,LPCSTR);
HRSRC32 WINAPI FindResource32W(HINSTANCE32,LPCWSTR,LPCWSTR);
@@ -6563,6 +6732,9 @@
INT16 WINAPI GetDeviceCaps16(HDC16,INT16);
INT32 WINAPI GetDeviceCaps32(HDC32,INT32);
#define GetDeviceCaps WINELIB_NAME(GetDeviceCaps)
+UINT16 WINAPI GetDIBColorTable16(HDC16,UINT16,UINT16,RGBQUAD*);
+UINT32 WINAPI GetDIBColorTable32(HDC32,UINT32,UINT32,RGBQUAD*);
+#define GetDIBColorTable WINELIB_NAME(GetDIBColorTable)
INT16 WINAPI GetDIBits16(HDC16,HBITMAP16,UINT16,UINT16,LPSTR,LPBITMAPINFO,UINT16);
INT32 WINAPI GetDIBits32(HDC32,HBITMAP32,UINT32,UINT32,LPSTR,LPBITMAPINFO,UINT32);
#define GetDIBits WINELIB_NAME(GetDIBits)
@@ -6718,6 +6890,9 @@
HWND16 WINAPI GetParent16(HWND16);
HWND32 WINAPI GetParent32(HWND32);
#define GetParent WINELIB_NAME(GetParent)
+INT16 WINAPI GetPath16(HDC16,LPPOINT16,LPBYTE,INT16);
+INT32 WINAPI GetPath32(HDC32,LPPOINT32,LPBYTE,INT32);
+#define GetPath WINELIB_NAME(GetPath)
COLORREF WINAPI GetPixel16(HDC16,INT16,INT16);
COLORREF WINAPI GetPixel32(HDC32,INT32,INT32);
#define GetPixel WINELIB_NAME(GetPixel)
@@ -7228,6 +7403,10 @@
INT32 WINAPI MessageBox32A(HWND32,LPCSTR,LPCSTR,UINT32);
INT32 WINAPI MessageBox32W(HWND32,LPCWSTR,LPCWSTR,UINT32);
#define MessageBox WINELIB_NAME_AW(MessageBox)
+INT16 WINAPI MessageBoxIndirect16(LPMSGBOXPARAMS16);
+INT32 WINAPI MessageBoxIndirect32A(LPMSGBOXPARAMS32A);
+INT32 WINAPI MessageBoxIndirect32W(LPMSGBOXPARAMS32W);
+#define MessageBoxIndirect WINELIB_NAME_AW(MessageBoxIndirect)
BOOL16 WINAPI ModifyMenu16(HMENU16,UINT16,UINT16,UINT16,SEGPTR);
BOOL32 WINAPI ModifyMenu32A(HMENU32,UINT32,UINT32,UINT32,LPCSTR);
BOOL32 WINAPI ModifyMenu32W(HMENU32,UINT32,UINT32,UINT32,LPCWSTR);
@@ -7292,6 +7471,9 @@
BOOL16 WINAPI PatBlt16(HDC16,INT16,INT16,INT16,INT16,DWORD);
BOOL32 WINAPI PatBlt32(HDC32,INT32,INT32,INT32,INT32,DWORD);
#define PatBlt WINELIB_NAME(PatBlt)
+HRGN16 WINAPI PathToRegion16(HDC16);
+HRGN32 WINAPI PathToRegion32(HDC32);
+#define PathToRegion WINELIB_NAME(PathToRegion)
BOOL16 WINAPI PeekMessage16(LPMSG16,HWND16,UINT16,UINT16,UINT16);
BOOL32 WINAPI PeekMessage32A(LPMSG32,HWND32,UINT32,UINT32,UINT32);
BOOL32 WINAPI PeekMessage32W(LPMSG32,HWND32,UINT32,UINT32,UINT32);
@@ -7469,6 +7651,9 @@
INT32 WINAPI ScrollWindowEx32(HWND32,INT32,INT32,const RECT32*,
const RECT32*,HRGN32,LPRECT32,UINT32);
#define ScrollWindowEx WINELIB_NAME(ScrollWindowEx)
+BOOL16 WINAPI SelectClipPath16(HDC16,INT16);
+BOOL32 WINAPI SelectClipPath32(HDC32,INT32);
+#define SelectClipPath WINELIB_NAME(SelectClipPath)
INT16 WINAPI SelectClipRgn16(HDC16,HRGN16);
INT32 WINAPI SelectClipRgn32(HDC32,HRGN32);
#define SelectClipRgn WINELIB_NAME(SelectClipRgn)
@@ -7486,6 +7671,13 @@
LRESULT WINAPI SendMessage32A(HWND32,UINT32,WPARAM32,LPARAM);
LRESULT WINAPI SendMessage32W(HWND32,UINT32,WPARAM32,LPARAM);
#define SendMessage WINELIB_NAME_AW(SendMessage)
+LRESULT WINAPI SendMessageTimeout16(HWND16,UINT16,WPARAM16,LPARAM,UINT16,
+ UINT16,LPWORD);
+LRESULT WINAPI SendMessageTimeout32A(HWND32,UINT32,WPARAM32,LPARAM,UINT32,
+ UINT32,LPDWORD);
+LRESULT WINAPI SendMessageTimeout32W(HWND32,UINT32,WPARAM32,LPARAM,UINT32,
+ UINT32,LPDWORD);
+#define SendMessageTimeout WINELIB_NAME_AW(SendMessageTimeout)
HWND16 WINAPI SetActiveWindow16(HWND16);
HWND32 WINAPI SetActiveWindow32(HWND32);
#define SetActiveWindow WINELIB_NAME(SetActiveWindow)
@@ -7542,6 +7734,9 @@
BOOL16 WINAPI SetDeskWallPaper16(LPCSTR);
BOOL32 WINAPI SetDeskWallPaper32(LPCSTR);
#define SetDeskWallPaper WINELIB_NAME(SetDeskWallPaper)
+UINT16 WINAPI SetDIBColorTable16(HDC16,UINT16,UINT16,RGBQUAD*);
+UINT32 WINAPI SetDIBColorTable32(HDC32,UINT32,UINT32,RGBQUAD*);
+#define SetDIBColorTable WINELIB_NAME(SetDIBColorTable)
INT16 WINAPI SetDIBits16(HDC16,HBITMAP16,UINT16,UINT16,LPCVOID,const BITMAPINFO*,UINT16);
INT32 WINAPI SetDIBits32(HDC32,HBITMAP32,UINT32,UINT32,LPCVOID,const BITMAPINFO*,UINT32);
#define SetDIBits WINELIB_NAME(SetDIBits)
diff --git a/include/winerror.h b/include/winerror.h
index ce1a3fe..dd2f3f3 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -17,6 +17,7 @@
#define ERROR_TOO_MANY_OPEN_FILES 4
#define ERROR_ACCESS_DENIED 5
#define ERROR_INVALID_HANDLE 6
+#define ERROR_NOT_ENOUGH_MEMORY 8
#define ERROR_BAD_FORMAT 11
#define ERROR_OUTOFMEMORY 14
#define ERROR_NO_MORE_FILES 18
@@ -28,6 +29,7 @@
#define ERROR_BROKEN_PIPE 109
#define ERROR_DISK_FULL 112
#define ERROR_CALL_NOT_IMPLEMENTED 120
+#define ERROR_INSUFFICIENT_BUFFER 122
#define ERROR_SEEK_ON_DEVICE 132
#define ERROR_DIR_NOT_EMPTY 145
#define ERROR_BUSY 170
@@ -35,9 +37,22 @@
#define ERROR_FILENAME_EXCED_RANGE 206
#define ERROR_MORE_DATA 234
#define ERROR_NO_MORE_ITEMS 259
+#define ERROR_INVALID_ADDRESS 487
+#define ERROR_CAN_NOT_COMPLETE 1003
#define ERROR_IO_DEVICE 1117
#define ERROR_POSSIBLE_DEADLOCK 1131
#define ERROR_BAD_DEVICE 1200
#define ERROR_NO_NETWORK 1222
+#define ERROR_COMMITMENT_LIMIT 1455
+
+/* HRESULT values for OLE, SHELL and other Interface stuff */
+#define NOERROR 0
+#define S_OK 0
+#define E_UNEXPECTED 0x8000FFFF
+#define E_OUTOFMEMORY 0x8007000E
+#define E_INVALIDARG 0x80070057
+
+#define OLE_E_ENUM_NOMORE 0x80040002
+#define CLASS_E_CLASSNOTAVAILABLE 0x80040111
#endif /* __WINE_WINERROR_H */
diff --git a/include/winnt.h b/include/winnt.h
index a23df14..0d53299 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -24,6 +24,12 @@
#define HEAP_WINE_SEGPTR 0x01000000 /* Not a Win32 flag */
#define HEAP_WINE_CODESEG 0x02000000 /* Not a Win32 flag */
+/* Processor feature flags. */
+#define PF_FLOATING_POINT_PRECISION_ERRATA 0
+#define PF_FLOATING_POINT_EMULATED 1
+#define PF_COMPARE_EXCHANGE_DOUBLE 2
+#define PF_MMX_INSTRUCTIONS_AVAILABLE 3
+
/* The Win32 register context */
#define CONTEXT_i386 0x00010000
diff --git a/include/winpos.h b/include/winpos.h
index f07431e..a572d93 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -41,5 +41,8 @@
extern LONG WINPOS_HandleWindowPosChanging16(WND *wndPtr, WINDOWPOS16 *winpos);
extern LONG WINPOS_HandleWindowPosChanging32(WND *wndPtr, WINDOWPOS32 *winpos);
extern INT16 WINPOS_WindowFromPoint( WND* scopeWnd, POINT16 pt, WND **ppWnd );
+extern void WINPOS_CheckInternalPos( HWND32 hwnd );
+extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
+extern BOOL32 WINPOS_CreateInternalPosAtom(void);
#endif /* __WINE_WINPOS_H */
diff --git a/include/winsock.h b/include/winsock.h
index d202655..edee250 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -61,46 +61,62 @@
{
UINT16 fd_count; /* how many are SET? */
SOCKET16 fd_array[FD_SETSIZE]; /* an array of SOCKETs */
-} ws_fd_set;
+} ws_fd_set16;
+
+typedef struct
+{
+ UINT32 fd_count; /* how many are SET? */
+ SOCKET32 fd_array[FD_SETSIZE]; /* an array of SOCKETs */
+} ws_fd_set32;
/* ws_fd_set operations */
-INT16 WINAPI __WSAFDIsSet16( SOCKET16, ws_fd_set * );
-INT32 WINAPI __WSAFDIsSet32( SOCKET32, ws_fd_set * );
+INT16 WINAPI __WSAFDIsSet16( SOCKET16, ws_fd_set16 * );
+INT32 WINAPI __WSAFDIsSet32( SOCKET32, ws_fd_set32 * );
#define __WSAFDIsSet WINELIB_NAME(__WSAFDIsSet);
-#define WS_FD_CLR(fd, set) do { \
+#define __WS_FD_CLR(fd, set, cast) do { \
UINT16 __i; \
- for (__i = 0; __i < ((ws_fd_set*)(set))->fd_count ; __i++) \
+ for (__i = 0; __i < ((cast*)(set))->fd_count ; __i++) \
{ \
- if (((ws_fd_set*)(set))->fd_array[__i] == fd) \
+ if (((cast*)(set))->fd_array[__i] == fd) \
{ \
- while (__i < ((ws_fd_set*)(set))->fd_count-1) \
+ while (__i < ((cast*)(set))->fd_count-1) \
{ \
- ((ws_fd_set*)(set))->fd_array[__i] = \
- ((ws_fd_set*)(set))->fd_array[__i+1]; \
+ ((cast*)(set))->fd_array[__i] = \
+ ((cast*)(set))->fd_array[__i+1]; \
__i++; \
} \
- ((ws_fd_set*)(set))->fd_count--; \
+ ((cast*)(set))->fd_count--; \
break; \
} \
} \
} while(0)
+#define WS_FD_CLR16(fd, set) __WS_FD_CLR((fd),(set), ws_fd_set16)
+#define WS_FD_CLR32(fd, set) __WS_FD_CLR((fd),(set), ws_fd_set32)
+#define WS_FD_CLR WINELIB_NAME(WS_FD_CLR);
-#define WS_FD_SET(fd, set) do { \
- if (((ws_fd_set*)(set))->fd_count < FD_SETSIZE) \
- ((ws_fd_set*)(set))->fd_array[((ws_fd_set*)(set))->fd_count++]=(fd);\
+#define __WS_FD_SET(fd, set, cast) do { \
+ if (((cast*)(set))->fd_count < FD_SETSIZE) \
+ ((cast*)(set))->fd_array[((cast*)(set))->fd_count++]=(fd);\
} while(0)
+#define WS_FD_SET16(fd, set) __WS_FD_SET((fd),(set), ws_fd_set16)
+#define WS_FD_SET32(fd, set) __WS_FD_SET((fd),(set), ws_fd_set32)
+#define WS_FD_SET WINELIB_NAME(WS_FD_SET);
-#define WS_FD_ZERO(set) (((ws_fd_set*)(set))->fd_count=0)
+#define WS_FD_ZERO16(set) (((ws_fd_set16*)(set))->fd_count=0)
+#define WS_FD_ZERO32(set) (((ws_fd_set32*)(set))->fd_count=0)
+#define WS_FD_ZERO WINELIB_NAME(WS_FD_ZERO);
-#define WS_FD_ISSET(fd, set) __WSAFDIsSet((SOCKET16)(fd), (ws_fd_set*)(set))
+#define WS_FD_ISSET16(fd, set) __WSAFDIsSet16((SOCKET16)(fd), (ws_fd_set16*)(set))
+#define WS_FD_ISSET32(fd, set) __WSAFDIsSet32((SOCKET32)(fd), (ws_fd_set32*)(set))
+#define WS_FD_ISSET WINELIB_NAME(WS_FD_ISSET);
/*
* Internet address (old style... should be updated)
*/
-typedef struct ws_addr_in
+struct ws_in_addr
{
union {
struct { BYTE s_b1,s_b2,s_b3,s_b4; } S_un_b;
@@ -113,15 +129,15 @@
#define ws_imp S_un.S_un_w.s_w2 /* imp */
#define ws_impno S_un.S_un_b.s_b4 /* imp # */
#define ws_lh S_un.S_un_b.s_b3 /* logical host */
-} _ws_in_addr;
+};
-typedef struct ws_sockaddr_in
+struct ws_sockaddr_in
{
INT16 sin_family;
UINT16 sin_port;
- _ws_in_addr sin_addr;
- char sin_zero[8];
-} _ws_sockaddr_in;
+ struct ws_in_addr sin_addr;
+ BYTE sin_zero[8];
+};
#define WSADESCRIPTION_LEN 256
#define WSASYS_STATUS_LEN 128
@@ -356,27 +372,51 @@
FARPROC16 WINAPI WSASetBlockingHook16(FARPROC16 lpBlockFunc);
FARPROC32 WINAPI WSASetBlockingHook32(FARPROC32 lpBlockFunc);
#define WSASetBlockingHook WINELIB_NAME(WSASetBlockingHook)
-HANDLE16 WINAPI WSAAsyncGetServByName(HWND16 hWnd, UINT16 wMsg,
- LPCSTR name, LPCSTR proto,
- SEGPTR buf, INT16 buflen);
-HANDLE16 WINAPI WSAAsyncGetServByPort(HWND16 hWnd, UINT16 wMsg, INT16 port,
- LPCSTR proto, SEGPTR buf, INT16 buflen);
+HANDLE16 WINAPI WSAAsyncGetServByName16(HWND16 hWnd, UINT16 wMsg, LPCSTR name, LPCSTR proto,
+ SEGPTR buf, INT16 buflen);
+HANDLE32 WINAPI WSAAsyncGetServByName32(HWND32 hWnd, UINT32 uMsg, LPCSTR name, LPCSTR proto,
+ LPSTR sbuf, INT32 buflen);
+#define WSAAsyncGetServByName WINELIB_NAME(WSAAsyncGetServByName)
-HANDLE16 WINAPI WSAAsyncGetProtoByName(HWND16 hWnd, UINT16 wMsg,
- LPCSTR name, SEGPTR buf, INT16 buflen);
+HANDLE16 WINAPI WSAAsyncGetServByPort16(HWND16 hWnd, UINT16 wMsg, INT16 port,
+ LPCSTR proto, SEGPTR buf, INT16 buflen);
+HANDLE32 WINAPI WSAAsyncGetServByPort32(HWND32 hWnd, UINT32 uMsg, INT32 port,
+ LPCSTR proto, LPSTR sbuf, INT32 buflen);
+#define WSAAsyncGetServByPort WINELIB_NAME(WSAAsyncGetServByPort)
-HANDLE16 WINAPI WSAAsyncGetProtoByNumber(HWND16 hWnd, UINT16 wMsg,
- INT16 number, SEGPTR buf, INT16 buflen);
+HANDLE16 WINAPI WSAAsyncGetProtoByName16(HWND16 hWnd, UINT16 wMsg,
+ LPCSTR name, SEGPTR buf, INT16 buflen);
+HANDLE32 WINAPI WSAAsyncGetProtoByName32(HWND32 hWnd, UINT32 uMsg,
+ LPCSTR name, LPSTR sbuf, INT32 buflen);
+#define WSAAsyncGetProtoByByName WINELIB_NAME(WSAAsyncGetProtoByByName)
-HANDLE16 WINAPI WSAAsyncGetHostByName(HWND16 hWnd, UINT16 wMsg,
- LPCSTR name, SEGPTR buf, INT16 buflen);
+HANDLE16 WINAPI WSAAsyncGetProtoByNumber16(HWND16 hWnd, UINT16 wMsg,
+ INT16 number, SEGPTR buf, INT16 buflen);
+HANDLE32 WINAPI WSAAsyncGetProtoByNumber32(HWND32 hWnd, UINT32 uMsg,
+ INT32 number, LPSTR sbuf, INT32 buflen);
+#define WSAAsyncGetProtoByNumber WINELIB_NAME(WSAAsyncGetProtoByNumber)
-HANDLE16 WINAPI WSAAsyncGetHostByAddr(HWND16 hWnd, UINT16 wMsg, LPCSTR addr,
+HANDLE16 WINAPI WSAAsyncGetHostByName16(HWND16 hWnd, UINT16 wMsg,
+ LPCSTR name, SEGPTR buf, INT16 buflen);
+HANDLE32 WINAPI WSAAsyncGetHostByName32(HWND32 hWnd, UINT32 uMsg,
+ LPCSTR name, LPSTR sbuf, INT32 buflen);
+#define WSAAsyncGetHostByName WINELIB_NAME(WSAAsyncGetHostByName)
+
+HANDLE16 WINAPI WSAAsyncGetHostByAddr16(HWND16 hWnd, UINT16 wMsg, LPCSTR addr,
INT16 len, INT16 type, SEGPTR buf, INT16 buflen);
-INT16 WINAPI WSACancelAsyncRequest(HANDLE16 hAsyncTaskHandle);
-INT16 WINAPI WSAAsyncSelect(SOCKET16 s, HWND16 hWnd, UINT16 wMsg,
- UINT32 lEvent);
+HANDLE32 WINAPI WSAAsyncGetHostByAddr32(HWND32 hWnd, UINT32 uMsg, LPCSTR addr,
+ INT32 len, INT32 type, LPSTR sbuf, INT32 buflen);
+#define WSAAsyncGetHostByAddr WINELIB_NAME(WSAAsyncGetHostByAddr)
+
+INT16 WINAPI WSACancelAsyncRequest16(HANDLE16 hAsyncTaskHandle);
+INT32 WINAPI WSACancelAsyncRequest32(HANDLE32 hAsyncTaskHandle);
+#define WSACancelAsyncRequest WINELIB_NAME(WSACancelAsyncRequest)
+
+INT16 WINAPI WSAAsyncSelect16(SOCKET16 s, HWND16 hWnd, UINT16 wMsg, UINT32 lEvent);
+INT32 WINAPI WSAAsyncSelect32(SOCKET32 s, HWND32 hWnd, UINT32 uMsg, UINT32 lEvent);
+#define WSAAsyncSelect WINELIB_NAME(WSAAsyncSelect)
+
#ifdef __cplusplus
}
@@ -458,12 +498,18 @@
/* custom data */
- HWND16 hWnd; /* hWnd to post */
- UINT16 uMsg; /* uMsg message to. */
+ HWND32 hWnd; /* hWnd to post */
+ UINT32 uMsg; /* uMsg message to. */
- SEGPTR buffer_base; /* buffer to copy result to */
- UINT16 buflen;
- UINT16 flags; /* WSMSG_ASYNC_... */
+ union
+ {
+ SEGPTR seg_base;
+ LPSTR lin_base;
+ void* ptr_base;
+ } b; /* buffer to copy result to */
+
+ UINT32 buflen;
+ UINT32 flags; /* WSMSG_ASYNC_... */
} ws_async_op;
#define WSMSG_ASYNC_HOSTBYNAME 0x0001
@@ -472,6 +518,7 @@
#define WSMSG_ASYNC_PROTOBYNUM 0x0020
#define WSMSG_ASYNC_SERVBYNAME 0x0100
#define WSMSG_ASYNC_SERVBYPORT 0x0200
+#define WSMSG_ASYNC_WIN32 0x1000
#define WSMSG_DEAD_AOP 0x8000
typedef struct __sop /* WSAAsyncSelect() control struct */
@@ -479,8 +526,8 @@
struct __sop *next, *prev;
struct __ws* pws;
- HWND16 hWnd;
- UINT16 uMsg;
+ HWND32 hWnd;
+ UINT32 uMsg;
} ws_select_op;
typedef struct __ws /* socket */
diff --git a/include/wintypes.h b/include/wintypes.h
index 5092157..a5ab556 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -88,6 +88,7 @@
typedef unsigned int UINT32;
typedef unsigned short WORD;
typedef unsigned long DWORD;
+typedef unsigned long ULONG;
typedef unsigned char BYTE;
typedef long LONG;
typedef char CHAR;
diff --git a/include/x11drv.h b/include/x11drv.h
index da3588f..0db6b86 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -14,6 +14,8 @@
typedef struct
{
int style;
+ int endcap;
+ int linejoin;
int pixel;
int width;
char * dashes;
diff --git a/loader/module.c b/loader/module.c
index f35bae4..cebaea0 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -526,7 +526,7 @@
if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
fprintf(stderr, "Sorry, this is an OS/2 linear executable (LX) file !\n");
- return (HMODULE32)11;
+ return (HMODULE32)12;
}
/* We now have a valid NE header */
@@ -1508,9 +1508,9 @@
*
* FIXME: rough guesswork, don't know what "Private" means
*/
-HMODULE32 WINAPI PrivateLoadLibrary(LPCSTR libname)
+HINSTANCE32 WINAPI PrivateLoadLibrary(LPCSTR libname)
{
- return LoadLibrary16(libname);
+ return (HINSTANCE32)LoadLibrary16(libname);
}
@@ -1529,9 +1529,9 @@
*
* FIXME: rough guesswork, don't know what "Private" means
*/
-void WINAPI PrivateFreeLibrary(HMODULE32 handle)
+void WINAPI PrivateFreeLibrary(HINSTANCE32 handle)
{
- FreeLibrary16(handle);
+ FreeLibrary16((HINSTANCE16)handle);
}
diff --git a/loader/ne_image.c b/loader/ne_image.c
index d42e5bc..98a8a9c 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -55,8 +55,8 @@
if (!pSeg->filepos) return TRUE; /* No file image, just return */
fd = MODULE_OpenFile( pModule->self );
- dprintf_module( stddeb, "Loading segment %d, selector=%04x\n",
- segnum, pSeg->selector );
+ dprintf_module( stddeb, "Loading segment %d, selector=%04x, flags=%04x\n",
+ segnum, pSeg->selector, pSeg->flags );
lseek( fd, pSeg->filepos << pModule->alignment, SEEK_SET );
if (pSeg->size) size = pSeg->size;
else if (pSeg->minsize) size = pSeg->minsize;
@@ -631,7 +631,7 @@
dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04lx:%04x ds=%04lx di=%04x cx=%04x\n",
CS_reg(&context), IP_reg(&context), DS_reg(&context),
DI_reg(&context), CX_reg(&context) );
- Callbacks->CallRegisterProc( &context, 0 );
+ Callbacks->CallRegisterShortProc( &context, 0 );
return TRUE;
}
@@ -674,4 +674,5 @@
/* It does nothing */
void WINAPI PatchCodeHandle(HANDLE16 hSel)
{
+ fprintf(stderr,"PatchCodeHandle(%04x),stub!\n",hSel);
}
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 1485cb6..6693fe2 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -167,7 +167,7 @@
}
void
-fixup_imports (PDB32 *process,PE_MODREF *pem)
+fixup_imports (PDB32 *process,PE_MODREF *pem,HMODULE32 hModule)
{
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
int fixup_failed = 0;
@@ -207,10 +207,10 @@
/* don't use MODULE_Load, Win32 creates new task differently */
res = PE_LoadLibraryEx32A( name, 0, 0 );
if (res <= (HMODULE32) 32) {
- char *p, buffer[256];
+ char *p, buffer[1024];
/* Try with prepending the path of the current module */
- GetModuleFileName32A( pem->module, buffer, sizeof (buffer));
+ GetModuleFileName32A( hModule, buffer, sizeof (buffer));
if (!(p = strrchr (buffer, '\\')))
p = buffer;
strcpy (p + 1, name);
@@ -522,6 +522,11 @@
load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
+ if (load_addr == 0) {
+ load_addr = (DWORD)VirtualAlloc( NULL, vma_size,
+ MEM_RESERVE | MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE );
+ }
pem->module = (HMODULE32)load_addr;
dprintf_win32(stddeb, "Load addr is really %lx, range %x\n",
@@ -647,7 +652,7 @@
if(pem->pe_reloc) do_relocations(pem);
if(pem->pe_export) dump_exports(pem->module);
- if(pem->pe_import) fixup_imports(process,pem);
+ if(pem->pe_import) fixup_imports(process,pem,hModule);
if (pem->pe_export)
modname = (char*)RVA(pem->pe_export->Name);
@@ -671,6 +676,7 @@
/******************************************************************************
* The PE Library Loader frontend.
* FIXME: handle the flags.
+ * internal module handling should be made better here (and in builtin.c)
*/
HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, HFILE32 hFile, DWORD flags) {
OFSTRUCT ofs;
@@ -690,6 +696,27 @@
pem = pem->next;
}
pModule = MODULE_GetPtr(hModule);
+ if (pModule->flags & NE_FFLAGS_BUILTIN) {
+ PDB32 *process = (PDB32*)GetCurrentProcessId();
+ IMAGE_DOS_HEADER *dh;
+ IMAGE_NT_HEADERS *nh;
+ IMAGE_SECTION_HEADER *sh;
+
+ /* we only come here if we already have 'loaded' the
+ * internal dll but in another process. Just create
+ * a PE_MODREF and return.
+ */
+ pem = (PE_MODREF*)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,sizeof(*pem));
+ pem->module = hModule;
+ dh = (IMAGE_DOS_HEADER*)pem->module;
+ nh = (IMAGE_NT_HEADERS*)(dh+1);
+ sh = (IMAGE_SECTION_HEADER*)(nh+1);
+ pem->pe_export = (IMAGE_EXPORT_DIRECTORY*)(sh+2);
+ pem->next = process->modref_list;
+ process->modref_list = pem;
+ return hModule;
+ }
} else {
/* try to load builtin, enabled modules first */
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 4ba09dd..0139633 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -53,7 +53,8 @@
*
*/
LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY resdirptr,
- LPCWSTR name,DWORD root)
+ LPCWSTR name,DWORD root,
+ BOOL32 allowdefault)
{
int entrynum;
LPIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
@@ -64,7 +65,7 @@
char buf[10];
lstrcpynWtoA(buf,name+1,10);
- return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root);
+ return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
}
entryTable = (LPIMAGE_RESOURCE_DIRECTORY_ENTRY) (
(BYTE *) resdirptr +
@@ -94,7 +95,7 @@
root +
entryTable[entrynum].u2.s.OffsetToDirectory);
/* just use first entry if no default can be found */
- if (!name && resdirptr->NumberOfIdEntries)
+ if (allowdefault && !name && resdirptr->NumberOfIdEntries)
return (LPIMAGE_RESOURCE_DIRECTORY) (
root +
entryTable[0].u2.s.OffsetToDirectory);
@@ -118,14 +119,14 @@
resdirptr = pem->pe_resource;
root = (DWORD) resdirptr;
- if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL)
+ if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
return 0;
- if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL)
+ if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
return 0;
- result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT32)lang, root);
+ result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT32)lang, root, FALSE);
/* Try LANG_NEUTRAL, too */
if(!result)
- return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root);
+ return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
return result;
}
@@ -243,7 +244,7 @@
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
- resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource);
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
@@ -282,7 +283,7 @@
return FALSE;
resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
- resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource);
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
@@ -324,7 +325,7 @@
nameW = HEAP_strdupAtoW(heap,0,name);
else
nameW = (LPWSTR)name;
- resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource);
+ resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(nameW))
HeapFree(heap,0,nameW);
if (!resdir)
@@ -333,7 +334,7 @@
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
- resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource);
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
@@ -367,10 +368,10 @@
return FALSE;
resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
- resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource);
+ resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
- resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource);
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
if (!resdir)
return FALSE;
et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
diff --git a/loader/task.c b/loader/task.c
index cf981d4..08881d6 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -386,7 +386,7 @@
SELECTOROF(IF1632_Saved16_ss_sp),
OFFSETOF(IF1632_Saved16_ss_sp) );
- Callbacks->CallRegisterProc( &context, 0 );
+ Callbacks->CallRegisterShortProc( &context, 0 );
/* This should never return */
fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
TASK_KillCurrentTask( 1 );
@@ -629,8 +629,6 @@
*/
void TASK_KillCurrentTask( INT16 exitCode )
{
- extern void USER_ExitWindows(void);
-
TDB* pTask = (TDB*) GlobalLock16( hCurrentTask );
if (!pTask) USER_ExitWindows(); /* No current task yet */
diff --git a/memory/heap.c b/memory/heap.c
index 0cf20f5..1d4aee2 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -885,7 +885,7 @@
dprintf_heap( stddeb, "HeapAlloc(%08x,%08lx,%08lx): returning NULL\n",
heap, flags, size );
if (!(flags & HEAP_NO_SERIALIZE)) HeapUnlock( heap );
- SetLastError( ERROR_OUTOFMEMORY );
+ SetLastError( ERROR_COMMITMENT_LIMIT );
return NULL;
}
@@ -911,7 +911,6 @@
else if (debugging_heap) memset( pInUse + 1, ARENA_INUSE_FILLER, size );
if (!(flags & HEAP_NO_SERIALIZE)) HeapUnlock( heap );
- SetLastError( 0 );
dprintf_heap( stddeb, "HeapAlloc(%08x,%08lx,%08lx): returning %08lx\n",
heap, flags, size, (DWORD)(pInUse + 1) );
diff --git a/memory/selector.c b/memory/selector.c
index 5c47775..410c0d5 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -22,7 +22,8 @@
*/
WORD WINAPI AllocSelectorArray( WORD count )
{
- WORD i, size = 0;
+ WORD i, sel, size = 0;
+ ldt_entry entry;
if (!count) return 0;
for (i = FIRST_LDT_ENTRY_TO_ALLOC; i < LDT_SIZE; i++)
@@ -31,9 +32,22 @@
else if (++size >= count) break;
}
if (i == LDT_SIZE) return 0;
- /* Mark selector as allocated */
- while (size--) ldt_flags_copy[i--] |= LDT_FLAGS_ALLOCATED;
- return ENTRY_TO_SELECTOR( i + 1 );
+ sel = i - size + 1;
+
+ entry.base = 0;
+ entry.type = SEGMENT_DATA;
+ entry.seg_32bit = FALSE;
+ entry.read_only = FALSE;
+ entry.limit_in_pages = FALSE;
+ entry.limit = 1; /* avoid 0 base and limit */
+
+ for (i = 0; i < count; i++)
+ {
+ /* Mark selector as allocated */
+ ldt_flags_copy[sel + i] |= LDT_FLAGS_ALLOCATED;
+ LDT_SetEntry( sel + i, &entry );
+ }
+ return ENTRY_TO_SELECTOR( sel );
}
@@ -652,3 +666,24 @@
fprintf(stdnimp,"WOWGetVDMPointerUnfix(%08lx), STUB\n",vp);
/* FIXME: unfix heapsegment */
}
+
+/***********************************************************************
+ * UTSelectorOffsetToLinear (WIN32S16.48)
+ *
+ * rough guesswork, but seems to work (I had no "reasonable" docu)
+ */
+LPVOID WINAPI UTSelectorOffsetToLinear(SEGPTR sptr)
+{
+ return PTR_SEG_TO_LIN(sptr);
+}
+
+/***********************************************************************
+ * UTLinearToSelectorOffset (WIN32S16.49)
+ *
+ * FIXME: I don't know if that's the right way to do linear -> segmented
+ */
+SEGPTR WINAPI UTLinearToSelectorOffset(LPVOID lptr)
+{
+ fprintf( stderr, "UTLinearToSelectorOffset(%p): stub\n", lptr );
+ return (SEGPTR)lptr;
+}
diff --git a/memory/virtual.c b/memory/virtual.c
index 7ae69be..82d4845 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -21,6 +21,10 @@
#include "stddebug.h"
#include "debug.h"
+#ifndef MS_SYNC
+#define MS_SYNC 0
+#endif
+
/* File mapping */
typedef struct
{
@@ -190,6 +194,8 @@
/* Create the view structure */
+ assert( !(base & page_mask) );
+ assert( !(size & page_mask) );
size >>= page_shift;
if (!(view = (FILE_VIEW *)malloc( sizeof(*view) + size - 1 ))) return NULL;
view->base = base;
@@ -490,6 +496,13 @@
if (view_size > size)
FILE_munmap( (void *)(ptr + size), 0, view_size - size );
}
+ else if (ptr != base)
+ {
+ /* We couldn't get the address we wanted */
+ FILE_munmap( (void *)ptr, 0, view_size );
+ SetLastError( ERROR_INVALID_ADDRESS );
+ return NULL;
+ }
if (!(view = VIRTUAL_CreateView( ptr, size, 0, 0, vprot, NULL )))
{
FILE_munmap( (void *)ptr, 0, size );
@@ -1097,7 +1110,7 @@
return FALSE;
}
if (!cbFlush) cbFlush = view->size;
- if (!msync( addr, cbFlush, MS_SYNC )) return TRUE;
+ if (!msync( (void *)addr, cbFlush, MS_SYNC )) return TRUE;
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 4bbbe90..f9722db 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -37,6 +37,8 @@
w32scomb.c \
w32skrnl.c \
w32sys.c \
+ win32s16.c \
+ windebug.c \
winsock.c \
winsock_dns.c \
wsprintf.c \
diff --git a/misc/callback.c b/misc/callback.c
index c379a90..34e5f02 100644
--- a/misc/callback.c
+++ b/misc/callback.c
@@ -7,8 +7,8 @@
#include <assert.h>
#include <stdio.h>
#include "callback.h"
+#include "task.h"
-extern void TASK_Reschedule(void); /* loader/task.c */
/**********************************************************************
* CALLBACK_CallWndProc
@@ -24,10 +24,11 @@
/**********************************************************************
* CALLBACK_CallRegisterProc
*/
-static VOID WINAPI CALLBACK_CallRegisterProc( CONTEXT *context, INT32 offset)
+static LONG WINAPI CALLBACK_CallRegisterProc( CONTEXT *context, INT32 offset)
{
fprintf( stderr, "Cannot call a register proc in Winelib\n" );
assert( FALSE );
+ return 0;
}
@@ -123,6 +124,15 @@
return proc( ptr );
}
+
+/**********************************************************************
+ * CALLBACK_CallWOWCallbackProc
+ */
+static DWORD WINAPI CALLBACK_CallWOWCallbackProc( FARPROC16 proc, DWORD dw )
+{
+ return proc( dw );
+}
+
/**********************************************************************
* CALLBACK_WinelibTable
*
@@ -130,7 +140,8 @@
*/
static const CALLBACKS_TABLE CALLBACK_WinelibTable =
{
- CALLBACK_CallRegisterProc, /* CallRegisterProc */
+ CALLBACK_CallRegisterProc, /* CallRegisterShortProc */
+ CALLBACK_CallRegisterProc, /* CallRegisterLongProc */
TASK_Reschedule, /* CallTaskRescheduleProc */
NULL, /* CallFrom16WndProc */
CALLBACK_CallWndProc, /* CallWndProc */
@@ -142,6 +153,7 @@
CALLBACK_CallBootAppProc, /* CallBootAppProc */
CALLBACK_CallLoadAppSegProc, /* CallLoadAppSegProc */
CALLBACK_CallSystemTimerProc, /* CallSystemTimerProc */
+ CALLBACK_CallWOWCallbackProc, /* CallWOWCallbackProc */
CALLBACK_CallASPIPostProc, /* CallASPIPostProc */
/* The graphics driver callbacks are never used in Winelib */
NULL, /* CallDrvControlProc */
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 83fa922..d422c87 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -538,10 +538,14 @@
}
else
*tmpstr = 0;
- if (!FILEDLG_ScanDir(hWnd, tmpstr))
- fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n", tmpstr);
- /* select current drive in combo 2 */
- n = DRIVE_GetCurrentDrive();
+ if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
+ *tmpstr = 0;
+ if (!FILEDLG_ScanDir(hWnd, tmpstr))
+ fprintf(stderr, "FileDlg: couldn't read initial directory %s!\n",tmpstr);
+ }
+ /* select current drive in combo 2, omit missing drives */
+ for(i=0, n=-1; i<=DRIVE_GetCurrentDrive(); i++)
+ if (DRIVE_IsValid(i)) n++;
SendDlgItemMessage16(hWnd, cmb2, CB_SETCURSEL16, n, 0);
if (!(lpofn->Flags & OFN_SHOWHELP))
ShowWindow32(GetDlgItem32(hWnd, pshHelp), SW_HIDE);
diff --git a/misc/cpu.c b/misc/cpu.c
index 014c546..ffbbbbf 100644
--- a/misc/cpu.c
+++ b/misc/cpu.c
@@ -1,7 +1,7 @@
/*
* What processor?
*
- * Copyright 1995 Morten Welinder
+ * Copyright 1995,1997 Morten Welinder
* Copyright 1997 Marcus Meissner
*/
@@ -9,6 +9,7 @@
#include <ctype.h>
#include <string.h>
#include "windows.h"
+#include "winnt.h"
VOID WINAPI GetSystemInfo(LPSYSTEM_INFO si)
{
@@ -99,3 +100,25 @@
return;
#endif /* linux */
}
+
+
+/* IsProcessorFeaturePresent [KERNEL32.880] */
+BOOL32 WINAPI IsProcessorFeaturePresent (DWORD feature)
+{
+ SYSTEM_INFO si;
+ GetSystemInfo (&si);
+ /* FIXME: these are relatively stupid approximations. */
+ switch (feature)
+ {
+ case PF_FLOATING_POINT_PRECISION_ERRATA:
+ return si.wProcessorLevel == 5;
+ case PF_FLOATING_POINT_EMULATED:
+ return FALSE;
+ case PF_COMPARE_EXCHANGE_DOUBLE:
+ return si.wProcessorLevel >= 5;
+ case PF_MMX_INSTRUCTIONS_AVAILABLE:
+ return FALSE;
+ default:
+ return FALSE;
+ }
+}
diff --git a/misc/crtdll.c b/misc/crtdll.c
index 7ffa01a..3a12c9b 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -30,6 +30,7 @@
#include <ctype.h>
#include <math.h>
#include <fcntl.h>
+#include <setjmp.h>
#include "win.h"
#include "windows.h"
#include "stddebug.h"
@@ -438,7 +439,7 @@
if (fd == -1)
len = -1;
else if (fd<=2)
- len = (UINT32)write(fd,buf,(LONG)len);
+ len = (UINT32)write(fd,buf,(LONG)count);
else
len = _lwrite32(fd,buf,count);
dprintf_crtdll(stddeb,"CRTDLL_write %d/%d byte to dfh %d from %p,\n",
@@ -456,6 +457,8 @@
* FIXME _exit (CRTDLL.87)
* FIXME exit (CRTDLL.359)
*
+ * atexit-processing comes to mind -- MW.
+ *
*/
void __cdecl CRTDLL__cexit(INT32 ret)
{
@@ -502,10 +505,13 @@
*/
LPSTR __cdecl CRTDLL_gets(LPSTR buf)
{
+ char * ret;
/* BAD, for the whole WINE process blocks... just done this way to test
* windows95's ftp.exe.
*/
- return gets(buf);
+ ret = gets(buf);
+ dprintf_crtdll(stddeb,"CRTDLL_gets got %s\n",ret);
+ return ret;
}
@@ -762,12 +768,12 @@
bp = buffer + strlen(buffer);
i = strlen(buffer) + strlen(x) +2;
- /* Calculate needed buffer size tp prevent overflow*/
+ /* Calculate needed buffer size to prevent overflow. */
while (*y) {
if (*y =='\\') i++;
y++;
}
- /* if buffer to short, exit */
+ /* If buffer too short, exit. */
if (i > SYSBUF_LENGTH) {
dprintf_crtdll(stddeb,"_system buffer to small\n");
return 127;
@@ -780,7 +786,7 @@
bp++; y++;
if (*(y-1) =='\\') *bp++ = '\\';
}
- /* remove spaces from end of string */
+ /* Remove spaces from end of string. */
while (*(y-1) == ' ') {
bp--;y--;
}
@@ -836,6 +842,16 @@
/*********************************************************************
+ * longjmp (CRTDLL.426)
+ */
+VOID __cdecl CRTDLL_longjmp(jmp_buf env, int val)
+{
+ dprintf_crtdll(stdnimp,"CRTDLL_longjmp semistup, expect crash\n");
+ dprintf_crtdll(stddeb, "CRTDLL_longjmp semistup, expect crash\n");
+ return longjmp(env, val);
+}
+
+/*********************************************************************
* malloc (CRTDLL.427)
*/
VOID* __cdecl CRTDLL_malloc(DWORD size)
@@ -1088,14 +1104,14 @@
/*********************************************************************
* wcschr (CRTDLL.504)
*/
-LPWSTR __cdecl CRTDLL_wcschr(LPWSTR str,WCHAR xchar)
+LPWSTR __cdecl CRTDLL_wcschr(LPCWSTR str,WCHAR xchar)
{
- LPWSTR s;
+ LPCWSTR s;
s=str;
do {
if (*s==xchar)
- return s;
+ return (LPWSTR)s;
} while (*s++);
return NULL;
}
@@ -1345,7 +1361,7 @@
{
/* Slightly modified lstrcpynAtoW functions from memory/strings.c
- * We need the numberr of characters transfered
+ * We need the number of characters transfered
* FIXME: No multibyte support yet
*/
@@ -1522,9 +1538,8 @@
len = size;
if (!buf) {
- len = size;
if (size < 0) /* allocate as big as nescessary */
- len =GetCurrentDirectory32A(1,test);
+ len =GetCurrentDirectory32A(1,test) + 1;
if(!(buf = CRTDLL_malloc(len)))
{
/* set error to OutOfRange */
diff --git a/misc/lstr.c b/misc/lstr.c
index 2d7db18..ce80476 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -10,40 +10,50 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <wctype.h>
#include "windows.h"
#include "winnt.h" /* HEAP_ macros */
+#include "task.h"
#include "heap.h"
#include "ldt.h"
+#include "stackframe.h"
#include "module.h"
#include "stddebug.h"
#include "debug.h"
-#define ToUpper(c) toupper(c)
-#define ToLower(c) tolower(c)
-
/* Funny to divide them between user and kernel. */
-/* IsCharAlpha USER 433 */
+/* be careful: always use functions from wctype.h if character > 255 */
+
+/***********************************************************************
+ * IsCharAlpha (USER.433)
+ */
BOOL16 WINAPI IsCharAlpha16(CHAR ch)
{
return isalpha(ch); /* This is probably not right for NLS */
}
-/* IsCharAlphanumeric USER 434 */
+/***********************************************************************
+ * IsCharAlphanumeric (USER.434)
+ */
BOOL16 WINAPI IsCharAlphaNumeric16(CHAR ch)
{
return isalnum(ch);
}
-/* IsCharUpper USER 435 */
+/***********************************************************************
+ * IsCharUpper (USER.435)
+ */
BOOL16 WINAPI IsCharUpper16(CHAR ch)
{
return isupper(ch);
}
-/* IsCharLower USER 436 */
+/***********************************************************************
+ * IsCharLower (USER.436)
+ */
BOOL16 WINAPI IsCharLower16(CHAR ch)
{
return islower(ch);
@@ -64,7 +74,7 @@
for (s = PTR_SEG_TO_LIN(strOrChar); *s; s++) *s = toupper(*s);
return strOrChar;
}
- else return (SEGPTR)ToUpper( (int)strOrChar );
+ else return toupper((char)strOrChar);
}
@@ -93,7 +103,7 @@
for (s = PTR_SEG_TO_LIN( strOrChar ); *s; s++) *s = tolower( *s );
return strOrChar;
}
- else return (SEGPTR)tolower( (int)strOrChar );
+ else return tolower((char)strOrChar);
}
@@ -274,7 +284,7 @@
}
return x;
}
- else return (LPSTR)tolower(LOWORD(x));
+ else return (LPSTR)tolower((char)(int)x);
}
/***********************************************************************
@@ -285,6 +295,7 @@
{
DWORD done=0;
+ if (!x) return 0; /* YES */
while (*x && (buflen--))
{
*x=tolower(*x);
@@ -302,9 +313,10 @@
{
DWORD done=0;
+ if (!x) return 0; /* YES */
while (*x && (buflen--))
{
- *x=tolower(*x);
+ *x=towlower(*x);
x++;
done++;
}
@@ -322,12 +334,12 @@
LPWSTR s = x;
while (*s)
{
- *s=tolower(*s);
+ *s=towlower(*s);
s++;
}
return x;
}
- else return (LPWSTR)tolower(LOWORD(x));
+ else return (LPWSTR)towlower(LOWORD(x));
}
/***********************************************************************
@@ -346,7 +358,7 @@
}
return x;
}
- else return (LPSTR)toupper(LOWORD(x));
+ return (LPSTR)toupper((char)(int)x);
}
/***********************************************************************
@@ -357,6 +369,7 @@
{
DWORD done=0;
+ if (!x) return 0; /* YES */
while (*x && (buflen--))
{
*x=toupper(*x);
@@ -374,9 +387,10 @@
{
DWORD done=0;
+ if (!x) return 0; /* YES */
while (*x && (buflen--))
{
- *x=toupper(*x);
+ *x=towupper(*x);
x++;
done++;
}
@@ -394,12 +408,12 @@
LPWSTR s = x;
while (*s)
{
- *s=toupper(*s);
+ *s=towupper(*s);
s++;
}
return x;
}
- else return (LPWSTR)toupper(LOWORD(x));
+ else return (LPWSTR)towupper(LOWORD(x));
}
/***********************************************************************
@@ -426,7 +440,7 @@
*/
BOOL32 WINAPI IsCharAlphaNumeric32W(WCHAR x)
{
- return isalnum(x);
+ return iswalnum(x);
}
/***********************************************************************
@@ -435,7 +449,7 @@
*/
BOOL32 WINAPI IsCharAlpha32W(WCHAR x)
{
- return isalpha(x);
+ return iswalpha(x);
}
/***********************************************************************
@@ -453,7 +467,7 @@
*/
BOOL32 WINAPI IsCharLower32W(WCHAR x)
{
- return islower(x);
+ return iswlower(x);
}
/***********************************************************************
@@ -471,7 +485,7 @@
*/
BOOL32 WINAPI IsCharUpper32W(WCHAR x)
{
- return isupper(x);
+ return iswupper(x);
}
/***********************************************************************
diff --git a/misc/main.c b/misc/main.c
index 02984ae..bda1779 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -18,12 +18,12 @@
#include <X11/Xutil.h>
#include <X11/Xlocale.h>
#include <X11/cursorfont.h>
+#include "winsock.h"
#include "heap.h"
#include "message.h"
#include "msdos.h"
#include "windows.h"
#include "color.h"
-#include "winsock.h"
#include "options.h"
#include "desktop.h"
#include "process.h"
diff --git a/misc/network.c b/misc/network.c
index 12ed9fa..58b8cbd 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -156,7 +156,7 @@
/**************************************************************************
* WNetGetConnection [USER.512]
*/
-int WINAPI WNetGetConnection16(LPSTR lpLocalName,
+int WINAPI WNetGetConnection16(LPCSTR lpLocalName,
LPSTR lpRemoteName, UINT16 *cbRemoteName)
{
const char *path;
diff --git a/misc/port.c b/misc/port.c
index b16ff0f..f98a951 100644
--- a/misc/port.c
+++ b/misc/port.c
@@ -49,3 +49,11 @@
return dest;
}
#endif /* HAVE_MEMMOVE */
+
+#ifndef HAVE_STRERROR
+const char *strerror( int err )
+{
+ /* Let's hope we have sys_errlist then */
+ return sys_errlist[err];
+}
+#endif /* HAVE_STRERROR */
diff --git a/misc/printdrv.c b/misc/printdrv.c
index 94ca696..3c73581 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -89,6 +89,14 @@
return 1;
}
+BOOL32 WINAPI OpenPrinter32A(LPSTR lpPrinterName,HANDLE32 *phPrinter,
+ LPPRINTER_DEFAULTS32A pDefault)
+{
+ fprintf(stderr,"OpenPrinter32A(%s,%p,%p), stub\n",
+ lpPrinterName, phPrinter, pDefault);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
BOOL32 WINAPI EnumPrinters32A(DWORD dwType, LPSTR lpszName,
DWORD dwLevel, LPBYTE lpbPrinters,
DWORD cbBuf, LPDWORD lpdwNeeded,
diff --git a/misc/shell.c b/misc/shell.c
index 66a94ce..d0bd6ba 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -8,6 +8,7 @@
#include <unistd.h>
#include <ctype.h>
#include "windows.h"
+#include "winerror.h"
#include "file.h"
#include "shell.h"
#include "heap.h"
@@ -125,6 +126,7 @@
"William Smith",
"Dominik Strasser",
"Vadim Strizhevsky",
+ "Bertho Stultiens",
"Erik Svendsen",
"Tristan Tarrant",
"Andrew Taylor",
@@ -181,9 +183,6 @@
#pragma pack(4)
-extern HICON16 WINAPI LoadIconHandler( HGLOBAL16 hResource, BOOL16 bNew );
-extern WORD WINAPI GetIconID( HGLOBAL16 hResource, DWORD resType );
-
static const char* lpstrMsgWndCreated = "OTHERWINDOWCREATED";
static const char* lpstrMsgWndDestroyed = "OTHERWINDOWDESTROYED";
static const char* lpstrMsgShellActivate = "ACTIVATESHELLWINDOW";
@@ -754,6 +753,29 @@
return ret;
}
+/*************************************************************************
+ * Shell_NotifyIcon [SHELL32.249]
+ * FIXME
+ * This function is supposed to deal with the systray.
+ * Any ideas on how this is to be implimented?
+ */
+BOOL32 WINAPI Shell_NotifyIcon( DWORD dwMessage,
+ PNOTIFYICONDATA pnid )
+{
+ return FALSE;
+}
+
+/*************************************************************************
+ * Shell_NotifyIcon [SHELL32.240]
+ * FIXME
+ * This function is supposed to deal with the systray.
+ * Any ideas on how this is to be implimented?
+ */
+BOOL32 WINAPI Shell_NotifyIconA(DWORD dwMessage,
+ PNOTIFYICONDATA pnid )
+{
+ return FALSE;
+}
/*************************************************************************
* SHELL_GetResourceTable
@@ -1048,7 +1070,7 @@
_lclose32( hFile);
return 0;
}
- icongroupresdir = GetResDirEntryW(rootresdir,(LPWSTR)RT_GROUP_ICON,(DWORD)rootresdir);
+ icongroupresdir = GetResDirEntryW(rootresdir,(LPWSTR)RT_GROUP_ICON,(DWORD)rootresdir,FALSE);
if (!icongroupresdir) {
fprintf(stderr,"InternalExtractIcon: No Icongroupresourcedirectory!\n");
UnmapViewOfFile(peimage);
@@ -1094,7 +1116,7 @@
/* go down this resource entry, name */
resdir = (LPIMAGE_RESOURCE_DIRECTORY)((DWORD)rootresdir+(xresent->u2.s.OffsetToDirectory));
/* default language (0) */
- resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir);
+ resdir = GetResDirEntryW(resdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
igdataent = (LPIMAGE_RESOURCE_DATA_ENTRY)resdir;
/* lookup address in mapped image for virtual address */
@@ -1116,13 +1138,9 @@
/* found */
cid = (CURSORICONDIR*)igdata;
cids[i] = cid;
- fprintf(stderr,"cursoricondir %d: idType %d, idCount %d\n",
- i,cid->idType,cid->idCount
- );
RetPtr[i] = LookupIconIdFromDirectoryEx32(igdata,TRUE,SYSMETRICS_CXICON,SYSMETRICS_CYICON,0);
- fprintf(stderr,"-> best match is %08x\n",RetPtr[i]);
}
- iconresdir=GetResDirEntryW(rootresdir,(LPWSTR)RT_ICON,(DWORD)rootresdir);
+ iconresdir=GetResDirEntryW(rootresdir,(LPWSTR)RT_ICON,(DWORD)rootresdir,FALSE);
if (!iconresdir) {
fprintf(stderr,"InternalExtractIcon: No Iconresourcedirectory!\n");
UnmapViewOfFile(peimage);
@@ -1133,8 +1151,8 @@
for (i=0;i<n;i++) {
LPIMAGE_RESOURCE_DIRECTORY xresdir;
- xresdir = GetResDirEntryW(iconresdir,(LPWSTR)RetPtr[i],(DWORD)rootresdir);
- xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir);
+ xresdir = GetResDirEntryW(iconresdir,(LPWSTR)RetPtr[i],(DWORD)rootresdir,FALSE);
+ xresdir = GetResDirEntryW(xresdir,(LPWSTR)0,(DWORD)rootresdir,TRUE);
idataent = (LPIMAGE_RESOURCE_DATA_ENTRY)xresdir;
@@ -1214,6 +1232,12 @@
* Return icon for given file (either from file itself or from associated
* executable) and patch parameters if needed.
*/
+HICON32 WINAPI ExtractAssociatedIcon32A(HINSTANCE32 hInst,LPSTR lpIconPath,
+ LPWORD lpiIcon)
+{
+ return ExtractAssociatedIcon16(hInst,lpIconPath,lpiIcon);
+}
+
HICON16 WINAPI ExtractAssociatedIcon16(HINSTANCE16 hInst,LPSTR lpIconPath,
LPWORD lpiIcon)
{
@@ -1541,26 +1565,101 @@
*
* http://premium.microsoft.com/msdn/library/sdkdoc/api2_48fo.htm
*/
-
-/* This is the wrong place, but where is the right one? */
-#if 0
-#define E_OUTOFMEMORY 0x8007000EL
-
-HRESULT32 WINAPI SHELL32_DllGetClassObject (REFCLSID32 clsid,
- REFIID32 riid,
- LPVOID *ppv)
+DWORD WINAPI SHELL32_DllGetClassObject(REFCLSID rclsid,REFIID iid,LPVOID *ppv)
{
- HRESULT32 hres = E_OUTOFMEMORY;
- *ppv = NULL;
+ char xclsid[50],xiid[50];
+ HRESULT hres = E_OUTOFMEMORY;
- fprintf (stdnimp, "SHELL32_DllGetClassObject (0x%x,0x%x,%p) -- STUB\n",
- clsid, riid, ppv);
- return hres;
-}
-#endif
+ StringFromCLSID((LPCLSID)rclsid,xclsid);
+ StringFromCLSID((LPCLSID)iid,xiid);
+ fprintf(stderr,"SHELL32_DllGetClassObject(%s,%s,%p)\n",xclsid,xiid,ppv);
-DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) {
- *shellfolder = NULL;
+ *ppv = NULL;
+/* SDK example code looks like this:
+ *
+ HRESULT hres = E_OUTOFMEMORY;
+
+ *ppv = NULL;
+ CClassFactory *pClassFactory = new CClassFactory(rclsid);
+
+ if (pClassFactory) {
+ hRes = pClassFactory->QueryInterface(riid,ppv);
+ pClassFactory->Release();
+ }
+ return hRes;
+ *
+ * The magic of the whole stuff is still unclear to me, so just hack together
+ * something.
+ */
+
+ if (!memcmp(rclsid,&CLSID_ShellDesktop,sizeof(CLSID_ShellDesktop))) {
+ fprintf(stderr," requested CLSID_ShellDesktop, creating it.\n");
+ *ppv = IShellFolder_Constructor();
+ /* FIXME: Initialize this folder to be the shell desktop folder */
return 0;
+ }
+
+ fprintf (stdnimp, " -> clsid not found. returning E_OUTOFMEMORY.\n");
+ return hres;
}
+
+/*************************************************************************
+ * SHGetDesktopFolder [SHELL32.216]
+ * returns the interface to the shell desktop folder.
+ *
+ * [SDK header win95/shlobj.h: This is equivalent to call CoCreateInstance with
+ * CLSID_ShellDesktop.
+ *
+ * CoCreateInstance(CLSID_Desktop, NULL,
+ * CLSCTX_INPROC, IID_IShellFolder, &pshf);
+ * ]
+ * So what we are doing is currently wrong....
+ */
+DWORD WINAPI SHGetDesktopFolder(LPSHELLFOLDER *shellfolder) {
+ *shellfolder = IShellFolder_Constructor();
+ return NOERROR;
+}
+
+/*************************************************************************
+ * SHGetMalloc [SHELL32.220]
+ * returns the interface to shell malloc.
+ *
+ * [SDK header win95/shlobj.h:
+ * equivalent to: #define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem)
+ * ]
+ * What we are currently doing is not very wrong, since we always use the same
+ * heap (ProcessHeap).
+ */
+DWORD WINAPI SHGetMalloc(LPMALLOC *lpmal) {
+ fprintf(stderr,"SHGetMalloc()\n");
+ *lpmal = IMalloc_Constructor();
+ return NOERROR;
+}
+
+/*************************************************************************
+ * SHGetSpecialFolderLocation [SHELL32.223]
+ * returns the PIDL of a special folder
+ *
+ * nFolder is a CSIDL_xxxxx.
+ */
+HRESULT WINAPI SHGetSpecialFolderLocation(HWND32 hwndOwner, INT32 nFolder, LPITEMIDLIST * ppidl) {
+ fprintf(stderr,"SHGetSpecialFolderLocation(%04x,%d,%p),stub!\n",
+ hwndOwner,nFolder,ppidl
+ );
+ *ppidl = (LPITEMIDLIST)HeapAlloc(GetProcessHeap(),0,2*sizeof(ITEMIDLIST));
+ /* FIXME: we return only the empty ITEMIDLIST currently. */
+ (*ppidl)->mkid.cb = 0;
+ return NOERROR;
+}
+
+/*************************************************************************
+ * SHGetPathFromIDList [SHELL32.221]
+ * returns the path from a passed PIDL.
+ */
+BOOL32 WINAPI SHGetPathFromIDList(LPCITEMIDLIST pidl,LPSTR pszPath) {
+ fprintf(stderr,"SHGetPathFromIDList(%p,%p),stub!\n",pidl,pszPath);
+ lstrcpy32A(pszPath,"E:\\"); /* FIXME */
+ return NOERROR;
+}
+
diff --git a/misc/shellord.c b/misc/shellord.c
index f3a1191..3a1a6dc 100644
--- a/misc/shellord.c
+++ b/misc/shellord.c
@@ -32,6 +32,81 @@
#include "winreg.h"
/*************************************************************************
+ * SHELL32_2 [SHELL32.2]
+ */
+DWORD WINAPI SHELL32_2(HWND32 hwnd,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6) {
+ fprintf(stderr,"SHELL32_2(0x%04x,0x%08lx,0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",
+ hwnd,x2,x3,x4,x5,x6
+ );
+ return 0;
+}
+/*************************************************************************
+ * SHELL32_16 [SHELL32.16]
+ * find_lastitem_in_itemidlist()
+ */
+LPSHITEMID WINAPI SHELL32_16(LPITEMIDLIST iil) {
+ LPSHITEMID lastsii,sii;
+
+ if (!iil)
+ return NULL;
+ sii = &(iil->mkid);
+ lastsii = sii;
+ while (sii->cb) {
+ lastsii = sii;
+ sii = (LPSHITEMID)(((char*)sii)+sii->cb);
+ }
+ return lastsii;
+}
+/*************************************************************************
+ * SHELL32_29 [SHELL32.29]
+ * is_rootdir(const char*path)
+ */
+BOOL32 WINAPI SHELL32_29(LPCSTR x) {
+ if (!lstrcmp32A(x+1,":\\")) /* "X:\" */
+ return 1;
+ if (!lstrcmp32A(x,"\\")) /* "\" */
+ return 1;
+ if (x[0]=='\\' && x[1]=='\\') { /* UNC "\\<xx>\" */
+ int foundbackslash = 0;
+ x=x+2;
+ while (*x) {
+ if (*x++=='\\')
+ foundbackslash++;
+ }
+ if (foundbackslash<=1) /* max 1 \ more ... */
+ return 1;
+ }
+ return 0;
+}
+
+/*************************************************************************
+ * SHELL32_30 [SHELL32.30]
+ * get_rootdir(char*path,int drive)
+ */
+DWORD WINAPI SHELL32_30(LPSTR root,BYTE drive) {
+ strcpy(root,"A:\\");
+ root[0]+=drive;
+ return root;
+}
+
+/*************************************************************************
+ * SHELL32_31 [SHELL32.31]
+ * returns pointer to last . in last pathcomponent or at \0.
+ */
+LPSTR WINAPI SHELL32_31(LPSTR path) {
+ LPSTR lastpoint = NULL;
+
+ while (*path) {
+ if (*path=='\\'||*path==' ')
+ lastpoint=NULL;
+ if (*path=='.')
+ lastpoint=path;
+ path++;
+ }
+ return lastpoint?lastpoint:path;
+}
+
+/*************************************************************************
* SHELL32_32 [SHELL32.32]
* append \ if there is none
*/
@@ -48,6 +123,27 @@
}
/*************************************************************************
+ * SHELL32_33 [SHELL32.33]
+ * remove spaces from beginning and end of passed string
+ */
+LPSTR WINAPI SHELL32_33(LPSTR str) {
+ LPSTR x = str;
+
+ while (*x==' ') x++;
+ if (x!=str)
+ lstrcpy32A(str,x);
+ if (!*str)
+ return str;
+ x=str+strlen(str)-1;
+ while (*x==' ')
+ x--;
+ if (*x==' ')
+ *x='\0';
+ return x;
+}
+
+
+/*************************************************************************
* SHELL32_34 [SHELL32.34]
* basename(char *fn);
*/
@@ -135,6 +231,27 @@
}
/*************************************************************************
+ * SHELL32_39 [SHELL32.39]
+ * isUNC(const char*path);
+ */
+BOOL32 WINAPI SHELL32_39(LPCSTR path) {
+ if ((path[0]=='\\') && (path[1]=='\\'))
+ return TRUE;
+ return FALSE;
+}
+
+/*************************************************************************
+ * SHELL32_45 [SHELL32.45]
+ * file_exists(char *fn);
+ */
+BOOL32 WINAPI SHELL32_45(LPSTR fn) {
+ if (GetFileAttributes32A(fn)==-1)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+/*************************************************************************
* SHELL32_52 [SHELL32.52]
* look for next arg in string. handle "quoted" strings
* returns pointer to argument *AFTER* the space. Or to the \0.
@@ -153,14 +270,95 @@
}
/*************************************************************************
- * SHELL32_45 [SHELL32.45]
- * file_exists(char *fn);
+ * SHELL32_56 [SHELL32.56]
+ * unquote string (remove ")
*/
-BOOL32 WINAPI SHELL32_45(LPSTR fn) {
- if (GetFileAttributes32A(fn)==-1)
- return FALSE;
- else
- return TRUE;
+VOID WINAPI SHELL32_56(LPSTR str) {
+ DWORD len = lstrlen32A(str);
+
+ if (*str!='"') return;
+ if (str[len-1]!='"') return;
+ str[len-1]='\0';
+ lstrcpy32A(str,str+1);
+ return;
+}
+
+/*************************************************************************
+ * SHELL32_58 [SHELL32.58]
+ */
+DWORD WINAPI SHELL32_58(LPCSTR src,DWORD x2,LPSTR target,DWORD pathlen) {
+ fprintf(stderr,"SHELL32_58(%s,0x%08lx,%p,%ld),STUB!\n",
+ src,x2,target,pathlen
+ );
+ if (!src)
+ return 0;
+ return 0;
+}
+
+/*************************************************************************
+ * SHELL32_62 [SHELL32.62]
+ */
+DWORD WINAPI SHELL32_62(DWORD x,DWORD y,DWORD z,DWORD a) {
+ fprintf(stderr,"SHELL32_62(%08lx,%08lx,%08lx,%08lx),stub!\n",x,y,z,a);
+ return 0xffffffff;
+}
+
+/*************************************************************************
+ * SHELL32_63 [SHELL32.63]
+ */
+DWORD WINAPI SHELL32_63(HWND32 howner, LPSTR targetbuf, DWORD len, DWORD x, LPCSTR suffix, LPCSTR y, LPCSTR cmd) {
+ fprintf(stderr,"SHELL32_63(%04x,%p,%ld,%08lx,%s,%s,%s),stub!\n",
+ howner,targetbuf,len,x,suffix,y,cmd
+ );
+ /* puts up a Open Dialog and requests input into targetbuf */
+ /* OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_FILEMUSTEXIST|OFN_unknown */
+ lstrcpy32A(targetbuf,"x:\\s3.exe");
+ return 1;
+}
+
+/*************************************************************************
+ * SHELL32_68 [SHELL32.68]
+ */
+DWORD WINAPI SHELL32_68(DWORD x,DWORD y,DWORD z) {
+ fprintf(stderr,"SHELL32_68(0x%08lx,0x%08lx,0x%08lx),stub!\n",
+ x,y,z
+ );
+ return 0;
+}
+/*************************************************************************
+ * SHELL32_71 [SHELL32.71]
+ * returns internal shell values in the passed pointers
+ */
+BOOL32 WINAPI SHELL32_71(LPDWORD x,LPDWORD y) {
+
+ fprintf(stderr,"SHELL32_71(%p,%p),stub!\n",x,y);
+ return TRUE;
+}
+
+/*************************************************************************
+ * SHELL32_72 [SHELL32.72]
+ * dunno. something with icons
+ */
+void WINAPI SHELL32_72(LPSTR x,DWORD y,DWORD z) {
+ fprintf(stderr,"SHELL32_72(%s,%08lx,%08lx),stub!\n",x,y,z);
+}
+
+/*************************************************************************
+ * SHELL32_89 [SHELL32.89]
+ */
+DWORD WINAPI SHELL32_89(DWORD x1,DWORD x2,DWORD x3) {
+ fprintf(stderr,"SHELL32_89(0x%08lx,0x%08lx,0x%08lx),stub!\n",
+ x1,x2,x3
+ );
+ return 0;
+}
+
+/*************************************************************************
+ * SHELL32_119 [SHELL32.119]
+ * unknown
+ */
+void WINAPI SHELL32_119(LPVOID x) {
+ fprintf(stderr,"SHELL32_119(%p(%s)),stub\n",x,(char *)x);
}
/*************************************************************************
@@ -182,14 +380,6 @@
}
/*************************************************************************
- * SHELL32_119 [SHELL32.119]
- * unknown
- */
-void WINAPI SHELL32_119(LPVOID x) {
- fprintf(stderr,"SHELL32_119(%p),stub\n",x);
-}
-
-/*************************************************************************
* SHELL32_75 [SHELL32.75]
* unknown
*/
@@ -198,16 +388,26 @@
return TRUE;
}
-DWORD WINAPI
-SHELL32_DllGetClassObject(REFCLSID *clsid,REFIID *iid,LPVOID *x) {
- char xclsid[50],xiid[50];
-
- StringFromCLSID((LPCLSID)clsid,xclsid);
- StringFromCLSID((LPCLSID)iid,xiid);
- fprintf(stderr,"SHELL32_DllGetClassObject(%s,%s,%p), STUB\n",xclsid,xiid,x);
+/*************************************************************************
+ * SHELL32_77 [SHELL32.77]
+ */
+DWORD WINAPI SHELL32_77(DWORD x,DWORD y,DWORD z) {
+ fprintf(stderr,"SHELL32_77(%08lx,%08lx,%08lx),stub!\n",x,y,z);
return 0;
}
+/*************************************************************************
+ * SHELL32_79 [SHELL32.79]
+ * create_directory_and_notify(...)
+ */
+DWORD WINAPI SHELL32_79(LPCSTR dir,LPVOID xvoid) {
+ fprintf(stderr,"mkdir %s,%p\n",dir,xvoid);
+ if (!CreateDirectory32A(dir,xvoid))
+ return FALSE;
+ /* SHChangeNotify(8,1,dir,0); */
+ return TRUE;
+}
+
static FARPROC32 _find_moduleproc(LPSTR dllname,HMODULE32 *xhmod,LPSTR name) {
HMODULE32 hmod;
FARPROC32 dllunload,nameproc;
@@ -236,18 +436,26 @@
) {
DWORD WINAPI (*dllgetclassob)(REFCLSID,REFIID,LPVOID);
DWORD hres;
+/*
LPCLASSFACTORY classfac;
+ */
dllgetclassob = (DWORD(*)(REFCLSID,REFIID,LPVOID))_find_moduleproc(dllname,NULL,"DllGetClassObject");
if (!dllgetclassob)
return 0x80070000|GetLastError();
- hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac);
+/* FIXME */
+ hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,inst);
if (hres<0)
return hres;
+/*
+ hres = (*dllgetclassob)(clsid,(REFIID)&IID_IClassFactory,&classfac);
+ if (hres<0)
+ return hres;
classfac->lpvtbl->fnCreateInstance(classfac,unknownouter,refiid,inst);
classfac->lpvtbl->fnRelease(classfac);
+ */
return 0;
}
/*************************************************************************
@@ -321,24 +529,6 @@
/*************************************************************************
- * SHELL32_71 [SHELL32.71]
- * returns internal shell values in the passed pointers
- */
-BOOL32 WINAPI SHELL32_71(LPDWORD x,LPDWORD y) {
-
- fprintf(stderr,"SHELL32_71(%p,%p),stub!\n",x,y);
- return TRUE;
-}
-
-/*************************************************************************
- * SHELL32_72 [SHELL32.72]
- * dunno. something with icons
- */
-void WINAPI SHELL32_72(LPSTR x,DWORD y,DWORD z) {
- fprintf(stderr,"SHELL32_72(%s,%08lx,%08lx),stub!\n",x,y,z);
-}
-
-/*************************************************************************
* SHELL32_100 [SHELL32.100]
* walks through policy table, queries <app> key, <type> value, returns
* queried (DWORD) value.
@@ -375,56 +565,6 @@
}
-DWORD WINAPI SHELL32_77(DWORD x,DWORD y,DWORD z) {
- fprintf(stderr,"SHELL32_77(%08lx,%08lx,%08lx),stub!\n",x,y,z);
- return 0;
-}
-
-/*************************************************************************
- * SHELL32_79 [SHELL32.79]
- * create_directory_and_notify(...)
- */
-DWORD WINAPI SHELL32_79(LPCSTR dir,LPVOID xvoid) {
- fprintf(stderr,"mkdir %s,%p\n",dir,xvoid);
- if (!CreateDirectory32A(dir,xvoid))
- return FALSE;
- /* SHChangeNotify(8,1,dir,0); */
- return TRUE;
-}
-
-/*************************************************************************
- * SHELL32_165 [SHELL32.165]
- * create_path_and_notify(...)
- */
-DWORD WINAPI SHELL32_165(DWORD x,LPCSTR path) {
- if (SHELL32_79(path,(LPVOID)x))
- return 0;
- fprintf(stderr,"SHELL32_165(%08lx,%s),stub!\n",x,path);
- return 0;
-}
-
-/*************************************************************************
- * SHELL32_29 [SHELL32.29]
- * is_rootdir(const char*path)
- */
-BOOL32 WINAPI SHELL32_29(LPCSTR x) {
- if (!lstrcmp32A(x+1,":\\")) /* "X:\" */
- return 1;
- if (!lstrcmp32A(x,"\\")) /* "\" */
- return 1;
- if (x[0]=='\\' && x[1]=='\\') { /* UNC "\\<xx>\" */
- int foundbackslash = 0;
- x=x+2;
- while (*x) {
- if (*x++=='\\')
- foundbackslash++;
- }
- if (foundbackslash<=1) /* max 1 \ more ... */
- return 1;
- }
- return 0;
-}
-
/*************************************************************************
* SHELL32_152 [SHELL32.152]
* itemlist_length
@@ -443,6 +583,34 @@
}
/*************************************************************************
+ * SHELL32_158 [SHELL32.158]
+ */
+LPSTR WINAPI SHELL32_158(LPSTR path,DWORD y,DWORD z) {
+ fprintf(stderr,"SHELL32_158(%s,%08lx,%08lx)\n",path,y,z);
+ path = SHELL32_31(path);
+ return *path?(path+1):path;
+}
+
+/*************************************************************************
+ * SHELL32_165 [SHELL32.165]
+ * create_path_and_notify(...)
+ */
+DWORD WINAPI SHELL32_165(DWORD x,LPCSTR path) {
+ if (SHELL32_79(path,(LPVOID)x))
+ return 0;
+ fprintf(stderr,"SHELL32_165(%08lx,%s),stub!\n",x,path);
+ return 0;
+}
+
+/*************************************************************************
+ * SHELL32_195 [SHELL32.195]
+ * free_ptr() - frees memory using IMalloc
+ */
+DWORD WINAPI SHELL32_195(LPVOID x) {
+ return LocalFree32((HANDLE32)x);
+}
+
+/*************************************************************************
* SHELL32_196 [SHELL32.196]
* void *task_alloc(DWORD len), uses SHMalloc allocator
*/
@@ -481,32 +649,6 @@
}
/*************************************************************************
- * SHELL32_16 [SHELL32.16]
- * find_lastitem_in_itemidlist()
- */
-LPSHITEMID WINAPI SHELL32_16(LPITEMIDLIST iil) {
- LPSHITEMID lastsii,sii;
-
- if (!iil)
- return NULL;
- sii = &(iil->mkid);
- lastsii = sii;
- while (sii->cb) {
- lastsii = sii;
- sii = (LPSHITEMID)(((char*)sii)+sii->cb);
- }
- return lastsii;
-}
-
-/*************************************************************************
- * SHELL32_195 [SHELL32.195]
- * free_ptr() - frees memory using IMalloc
- */
-DWORD WINAPI SHELL32_195(LPVOID x) {
- return LocalFree32((HANDLE32)x);
-}
-
-/*************************************************************************
* SHELL32_155 [SHELL32.155]
* free_check_ptr - frees memory (if not NULL) allocated by SHMalloc allocator
*/
@@ -515,11 +657,3 @@
return 0;
return SHELL32_195(x);
}
-
-/*************************************************************************
- * SHELL32_62 [SHELL32.62]
- */
-DWORD WINAPI SHELL32_62(DWORD x,DWORD y,DWORD z,DWORD a) {
- fprintf(stderr,"SHELL32_62(%08lx,%08lx,%08lx,%08lx),stub!\n",x,y,z,a);
- return 0xffffffff;
-}
diff --git a/misc/toolhelp.c b/misc/toolhelp.c
index c9ceabb..afbdc46 100644
--- a/misc/toolhelp.c
+++ b/misc/toolhelp.c
@@ -70,3 +70,18 @@
nrofnotifys--;
return TRUE;
}
+
+BOOL16 WINAPI StackTraceCSIPFirst(STACKTRACEENTRY *ste, WORD wSS, WORD wCS, WORD wIP, WORD wBP)
+{
+ return TRUE;
+}
+
+BOOL16 WINAPI StackTraceFirst(STACKTRACEENTRY *ste, HTASK16 Task)
+{
+ return TRUE;
+}
+
+BOOL16 WINAPI StackTraceNext(STACKTRACEENTRY *ste)
+{
+ return TRUE;
+}
diff --git a/misc/ver.c b/misc/ver.c
index 422e6c3..883af0d 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -310,10 +310,6 @@
}
}
-extern LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(
- LPIMAGE_RESOURCE_DIRECTORY resdirptr,LPCWSTR name,DWORD root
-);
-
/* Loads the specified PE resource.
* FIXME: shouldn't load the whole image
*/
@@ -368,20 +364,20 @@
continue;
}
resourcedir = (LPIMAGE_RESOURCE_DIRECTORY)(image+resdir.VirtualAddress);
- xresdir = GetResDirEntryW(resourcedir,typeid,(DWORD)resourcedir);
+ xresdir = GetResDirEntryW(resourcedir,typeid,(DWORD)resourcedir,FALSE);
if (!xresdir) {
dprintf_ver(stddeb,"...no typeid entry found for %p\n",typeid);
HeapFree(GetProcessHeap(),0,image);
return 0;
}
- xresdir = GetResDirEntryW(xresdir,resid,(DWORD)resourcedir);
+ xresdir = GetResDirEntryW(xresdir,resid,(DWORD)resourcedir,FALSE);
if (!xresdir) {
dprintf_ver(stddeb,"...no resid entry found for %p\n",resid);
HeapFree(GetProcessHeap(),0,image);
return 0;
}
- xresdir = GetResDirEntryW(xresdir,0,(DWORD)resourcedir);
+ xresdir = GetResDirEntryW(xresdir,0,(DWORD)resourcedir,TRUE);
if (!xresdir) {
dprintf_ver(stddeb,"...no 0 (default language) entry found for %p\n",resid);
HeapFree(GetProcessHeap(),0,image);
@@ -1181,7 +1177,8 @@
nextslash++;
if (!*nextslash)
nextslash=NULL;
- }
+ } else if (*str == 0)
+ return NULL;
while (1) {
@@ -1208,7 +1205,7 @@
}
/* this one used for Win32 resources, which are always in UNICODE format */
-extern LPWSTR CRTDLL_wcschr(LPCWSTR str,WCHAR xchar);
+extern LPWSTR __cdecl CRTDLL_wcschr(LPCWSTR str,WCHAR xchar);
static BYTE*
_find_dataW(BYTE *block,LPCWSTR str, int buff_remain) {
LPWSTR nextslash;
@@ -1227,7 +1224,8 @@
nextslash++;
if (!*nextslash)
nextslash=NULL;
- }
+ } else if (*str == 0)
+ return NULL;
while (1) {
@@ -1298,6 +1296,7 @@
if (!b) {
fprintf(stderr,"key %s not found in versionresource.\n",s);
*buflen=0;
+ free (s);
return 0;
}
db=(struct dbW*)b;
@@ -1315,6 +1314,7 @@
if (!b) {
fprintf(stderr,"key %s not found in versionresource.\n",s);
*buflen=0;
+ free (s);
return 0;
}
db=(struct dbA*)b;
@@ -1358,6 +1358,7 @@
if (!b) {
fprintf(stderr,"key %s not found in versionresource.\n",s);
*buflen=0;
+ free (s);
return 0;
}
db = (struct dbW*)b;
@@ -1369,12 +1370,15 @@
HeapFree(GetProcessHeap(),0,xs);
} else
dprintf_ver(stderr,"->%p\n",b);
+ /* This is a leak. */
+ b = HEAP_strdupWtoA(GetProcessHeap(),0,(WCHAR*)b);
} else {
struct dbA *db;
b=_find_dataA(block,s,*(WORD*)block);
if (!b) {
fprintf(stderr,"key %s not found in versionresource.\n",subblock);
*buflen=0;
+ free (s);
return 0;
}
db=(struct dbA*)b;
diff --git a/misc/w32scomb.c b/misc/w32scomb.c
index 54d1d5c..9d2ac9e 100644
--- a/misc/w32scomb.c
+++ b/misc/w32scomb.c
@@ -10,13 +10,14 @@
#include <stdlib.h>
#include "windows.h"
#include "module.h"
+#include "ldt.h"
/***********************************************************************
* Get16DLLAddress (KERNEL32)
*
* rough guesswork, but seems to work
*/
-FARPROC16 Get16DLLAddress(HMODULE32 handle, LPSTR name) {
+FARPROC16 WINAPI Get16DLLAddress(HMODULE16 handle, LPSTR name) {
if (!handle) handle=GetModuleHandle16("WIN32S16");
return (FARPROC16)WIN32_GetProcAddress16(handle, name);
}
diff --git a/misc/w32skrnl.c b/misc/w32skrnl.c
index af8dae5..f05cc99 100644
--- a/misc/w32skrnl.c
+++ b/misc/w32skrnl.c
@@ -10,7 +10,7 @@
#include <stdlib.h>
#include <stdio.h>
-LPSTR WINAPI GetWin32sDirectory()
+LPSTR WINAPI GetWin32sDirectory(void)
{
static char *sysdir;
LPSTR text;
@@ -24,7 +24,7 @@
}
/* FIXME */
-SEGPTR WINAPI _GetThunkBuff()
+SEGPTR WINAPI _GetThunkBuff(void)
{
return (SEGPTR)NULL;
}
diff --git a/misc/win32s16.c b/misc/win32s16.c
new file mode 100644
index 0000000..382e146
--- /dev/null
+++ b/misc/win32s16.c
@@ -0,0 +1,16 @@
+/*
+ * WIN32S16
+ * DLL for Win32s
+ *
+ * Copyright (c) 1997 Andreas Mohr
+ */
+
+#include "windows.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+void BootTask()
+{
+ fprintf(stderr, "BootTask(): should only be used by WIN32S.EXE.\n");
+}
diff --git a/misc/windebug.c b/misc/windebug.c
new file mode 100644
index 0000000..30f4d2c
--- /dev/null
+++ b/misc/windebug.c
@@ -0,0 +1,20 @@
+/*
+ * WINDEBUG.DLL
+ *
+ * Copyright (c) 1997 Andreas Mohr
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "windows.h"
+#include "module.h"
+
+/***********************************************************************
+ * WinNotify (WINDEBUG.1)
+ * written without _any_ docu
+ */
+DWORD WinNotify() {
+ fprintf(stderr, "WinNotify(): stub !\n");
+ return NULL;
+}
diff --git a/misc/winsock.c b/misc/winsock.c
index a5d4dc9..b94bb3c 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -4,7 +4,6 @@
*
* (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
*
- * TODO: 32-bit asynchronous services.
*/
#include <stdio.h>
@@ -32,13 +31,13 @@
#include <netdb.h>
#include <unistd.h>
+#include "winsock.h"
#include "windows.h"
#include "winnt.h"
#include "heap.h"
#include "ldt.h"
#include "task.h"
#include "message.h"
-#include "winsock.h"
#include "miscemu.h"
#include "stddebug.h"
#include "debug.h"
@@ -148,25 +147,31 @@
return NULL;
}
-static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, ws_fd_set* ws, int* highfd )
+static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, void* wsfds, int* highfd, BOOL32 b32 )
{
/* translate Winsock fd set into local fd set */
- if( ws )
+ if( wsfds )
{
- int i;
- ws_socket* pws;
+#define wsfds16 ((ws_fd_set16*)wsfds)
+#define wsfds32 ((ws_fd_set32*)wsfds)
+ ws_socket* pws;
+ int i, count;
FD_ZERO(fds);
- for( i = 0; i < (ws->fd_count) ; i++ )
+ count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
+ for( i = 0; i < count; i++ )
{
- pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
- if( _check_ws(pwsi, pws) )
- {
- if( pws->fd > *highfd ) *highfd = pws->fd;
- FD_SET(pws->fd, fds);
- }
+ pws = (b32) ? (ws_socket*)WS_HANDLE2PTR(wsfds32->fd_array[i])
+ : (ws_socket*)WS_HANDLE2PTR(wsfds16->fd_array[i]);
+ if( _check_ws(pwsi, pws) )
+ {
+ if( pws->fd > *highfd ) *highfd = pws->fd;
+ FD_SET(pws->fd, fds);
+ }
}
+#undef wsfds32
+#undef wsfds16
return fds;
}
return NULL;
@@ -182,20 +187,23 @@
return optval != 0;
}
-static int fd_set_export( LPWSINFO pwsi, fd_set* fds, fd_set* exceptfds, ws_fd_set* ws )
+static int fd_set_export( LPWSINFO pwsi, fd_set* fds, fd_set* exceptfds, void* wsfds, BOOL32 b32 )
{
int num_err = 0;
/* translate local fd set into Winsock fd set, adding
* errors to exceptfds (only if app requested it) */
- if( ws )
+ if( wsfds )
{
- int i, j, count = ws->fd_count;
+#define wsfds16 ((ws_fd_set16*)wsfds)
+#define wsfds32 ((ws_fd_set32*)wsfds)
+ int i, j, count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
for( i = 0, j = 0; i < count; i++ )
{
- ws_socket *pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
+ ws_socket *pws = (b32) ? (ws_socket*)WS_HANDLE2PTR(wsfds32->fd_array[i])
+ : (ws_socket*)WS_HANDLE2PTR(wsfds16->fd_array[i]);
int fd = pws->fd;
if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
@@ -206,11 +214,19 @@
num_err++;
}
else
- ws->fd_array[j++] = ws->fd_array[i];
+ if( b32 )
+ wsfds32->fd_array[j++] = wsfds32->fd_array[i];
+ else
+ wsfds16->fd_array[j++] = wsfds16->fd_array[i];
}
}
- ws->fd_count = j;
+
+ if( b32 ) wsfds32->fd_count = j;
+ else wsfds16->fd_count = j;
+
dprintf_winsock(stddeb, "\n");
+#undef wsfds32
+#undef wsfds16
}
return num_err;
}
@@ -386,7 +402,7 @@
if( pwsi->sock[i].psop )
{
n++;
- WSAAsyncSelect( (SOCKET16)WS_PTR2HANDLE(pwsi->sock + i), 0, 0, 0 );
+ WSAAsyncSelect32( (SOCKET16)WS_PTR2HANDLE(pwsi->sock + i), 0, 0, 0 );
}
close(pwsi->sock[i].fd); j++;
}
@@ -504,8 +520,8 @@
EVENT_AddIO( pws->fd, EVENT_IO_READ ); /* reenabler */
/* async select the accept()'ed socket */
- WSAAsyncSelect( s, pws->psop->hWnd, pws->psop->uMsg,
- pws->flags & ~WS_FD_ACCEPT );
+ WSAAsyncSelect32( s, pws->psop->hWnd, pws->psop->uMsg,
+ pws->flags & ~WS_FD_ACCEPT );
}
return s;
}
@@ -538,13 +554,13 @@
dprintf_winsock(stddeb, "WS_BIND(%08x): socket %04x, ptr %8x, length %d\n",
(unsigned)pwsi, s, (int) name, namelen);
-#if DEBUG_SOCKADDR
+/* #if DEBUG_SOCKADDR */
dump_sockaddr(name);
-#endif
+/* #endif */
if ( _check_ws(pwsi, pws) )
if ( namelen >= sizeof(*name) )
- if ( ((struct sockaddr_in *)name)->sin_family == AF_INET )
+ if ( ((struct ws_sockaddr_in *)name)->sin_family == AF_INET )
if ( bind(pws->fd, name, namelen) < 0 )
{
int loc_errno = errno;
@@ -585,7 +601,7 @@
{
int fd = pws->fd;
- if( pws->psop ) WSAAsyncSelect( s, 0, 0, 0 );
+ if( pws->psop ) WSAAsyncSelect32( s, 0, 0, 0 );
pws->fd = -1;
pws->flags = (unsigned)pwsi->last_free;
@@ -789,7 +805,7 @@
*/
u_short WINAPI WINSOCK_htons(u_short hostshort) { return( htons(hostshort) ); }
/***********************************************************************
- * inet_addr() (WINSOCK.10)
+ * inet_addr() (WINSOCK.10)(WSOCK32.10)
*/
u_long WINAPI WINSOCK_inet_addr(char *cp) { return( inet_addr(cp) ); }
/***********************************************************************
@@ -802,34 +818,40 @@
u_short WINAPI WINSOCK_ntohs(u_short netshort) { return( ntohs(netshort) ); }
/***********************************************************************
- * inet_ntoa() (WINSOCK.11)
+ * inet_ntoa() (WINSOCK.11)(WSOCK32.11)
*/
-SEGPTR WINAPI WINSOCK_inet_ntoa(struct in_addr in)
+char* WINAPI WINSOCK_inet_ntoa32(struct in_addr in)
{
/* use "buffer for dummies" here because some applications have
* propensity to decode addresses in ws_hostent structure without
* saving them first...
*/
- LPWSINFO pwsi = wsi_find(GetCurrentTask());
+ LPWSINFO pwsi = wsi_find(GetCurrentTask());
- if( pwsi )
- {
- char* s = inet_ntoa(in);
- if( s )
+ if( pwsi )
{
- if( pwsi->dbuffer == NULL )
- if((pwsi->dbuffer = (char*) SEGPTR_ALLOC(32)) == NULL )
- {
- pwsi->err = WSAENOBUFS;
- return (SEGPTR)NULL;
- }
- strncpy(pwsi->dbuffer, s, 32 );
- return SEGPTR_GET(pwsi->dbuffer);
+ char* s = inet_ntoa(in);
+ if( s )
+ {
+ if( pwsi->dbuffer == NULL )
+ if((pwsi->dbuffer = (char*) SEGPTR_ALLOC(32)) == NULL )
+ {
+ pwsi->err = WSAENOBUFS;
+ return NULL;
+ }
+ strncpy(pwsi->dbuffer, s, 32 );
+ return pwsi->dbuffer;
+ }
+ pwsi->err = wsaErrno();
}
- pwsi->err = wsaErrno();
- }
- return (SEGPTR)NULL;
+ return NULL;
+}
+
+SEGPTR WINAPI WINSOCK_inet_ntoa16(struct in_addr in)
+{
+ char* retVal = WINSOCK_inet_ntoa32(in);
+ return retVal ? SEGPTR_GET(retVal) : (SEGPTR)NULL;
}
/***********************************************************************
@@ -1019,16 +1041,15 @@
}
/***********************************************************************
- * select() (WINSOCK.18)
+ * select() (WINSOCK.18)(WSOCK32.18)
*/
-INT16 WINAPI WINSOCK_select16(INT16 nfds, ws_fd_set *ws_readfds,
- ws_fd_set *ws_writefds, ws_fd_set *ws_exceptfds,
- struct timeval *timeout)
+static INT32 __ws_select( BOOL32 b32, void *ws_readfds, void *ws_writefds, void *ws_exceptfds,
+ struct timeval *timeout )
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_SELECT(%08x): nfds %d (ignored), read %8x, write %8x, excp %8x\n",
- (unsigned) pwsi, nfds, (unsigned) ws_readfds, (unsigned) ws_writefds, (unsigned) ws_exceptfds);
+ dprintf_winsock(stddeb, "WS_SELECT(%08x): read %8x, write %8x, excp %8x\n",
+ (unsigned) pwsi, (unsigned) ws_readfds, (unsigned) ws_writefds, (unsigned) ws_exceptfds);
if( pwsi )
{
@@ -1036,28 +1057,41 @@
fd_set readfds, writefds, exceptfds;
fd_set *p_read, *p_write, *p_except;
- p_read = fd_set_import(&readfds, pwsi, ws_readfds, &highfd);
- p_write = fd_set_import(&writefds, pwsi, ws_writefds, &highfd);
- p_except = fd_set_import(&exceptfds, pwsi, ws_exceptfds, &highfd);
+ p_read = fd_set_import(&readfds, pwsi, ws_readfds, &highfd, b32);
+ p_write = fd_set_import(&writefds, pwsi, ws_writefds, &highfd, b32);
+ p_except = fd_set_import(&exceptfds, pwsi, ws_exceptfds, &highfd, b32);
if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) >= 0 )
{
if( highfd )
{
- fd_set_export(pwsi, &readfds, p_except, ws_readfds);
- fd_set_export(pwsi, &writefds, p_except, ws_writefds);
+ fd_set_export(pwsi, &readfds, p_except, ws_readfds, b32);
+ fd_set_export(pwsi, &writefds, p_except, ws_writefds, b32);
if (p_except && ws_exceptfds)
{
- int i, j, count = ws_exceptfds->fd_count;
+#define wsfds16 ((ws_fd_set16*)ws_exceptfds)
+#define wsfds32 ((ws_fd_set32*)ws_exceptfds)
+ int i, j, count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
for (i = j = 0; i < count; i++)
{
- ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws_exceptfds->fd_array[i]);
+ ws_socket *pws = (b32) ? (ws_socket *)WS_HANDLE2PTR(wsfds32->fd_array[i])
+ : (ws_socket *)WS_HANDLE2PTR(wsfds16->fd_array[i]);
if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
- ws_exceptfds->fd_array[j++] = ws_exceptfds->fd_array[i];
+ {
+ if( b32 )
+ wsfds32->fd_array[j++] = wsfds32->fd_array[i];
+ else
+ wsfds16->fd_array[j++] = wsfds16->fd_array[i];
+ }
}
- ws_exceptfds->fd_count = j;
+ if( b32 )
+ wsfds32->fd_count = j;
+ else
+ wsfds16->fd_count = j;
+#undef wsfds32
+#undef wsfds16
}
}
return highfd;
@@ -1067,15 +1101,19 @@
return SOCKET_ERROR;
}
-/***********************************************************************
- * select() (WSOCK32.18)
- */
-INT32 WINAPI WINSOCK_select32(INT32 nfds, ws_fd_set *ws_readfds,
- ws_fd_set *ws_writefds, ws_fd_set *ws_exceptfds,
+INT16 WINAPI WINSOCK_select16(INT16 nfds, ws_fd_set16 *ws_readfds,
+ ws_fd_set16 *ws_writefds, ws_fd_set16 *ws_exceptfds,
+ struct timeval *timeout)
+{
+ return (INT16)__ws_select( FALSE, ws_readfds, ws_writefds, ws_exceptfds, timeout );
+}
+
+INT32 WINAPI WINSOCK_select32(INT32 nfds, ws_fd_set32 *ws_readfds,
+ ws_fd_set32 *ws_writefds, ws_fd_set32 *ws_exceptfds,
struct timeval *timeout)
{
/* struct timeval is the same for both 32- and 16-bit code */
- return WINSOCK_select16( (INT16)nfds, ws_readfds, ws_writefds, ws_exceptfds, timeout );
+ return (INT32)__ws_select( TRUE, ws_readfds, ws_writefds, ws_exceptfds, timeout );
}
@@ -1088,7 +1126,7 @@
LPWSINFO pwsi = wsi_find(GetCurrentTask());
dprintf_winsock(stddeb, "WS_SEND(%08x): socket %04x, ptr %08x, length %d, flags %d\n",
- (unsigned)pwsi, s, (unsigned) buf, len, flags);
+ (unsigned)pwsi, s, (unsigned) buf, len, flags);
if( _check_ws(pwsi, pws) )
{
int length;
@@ -1221,7 +1259,7 @@
case 2: /* drop all */
default:
- WSAAsyncSelect( s, 0, 0, 0 );
+ WSAAsyncSelect32( s, 0, 0, 0 );
break;
}
@@ -1586,23 +1624,40 @@
*/
/* winsock_dns.c */
-extern HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND16 hWnd, UINT16 uMsg, INT16 type, LPCSTR init,
- INT16 len, LPCSTR proto, SEGPTR sbuf, INT16 buflen, UINT32 flag);
+extern HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND32 hWnd, UINT32 uMsg, INT32 type, LPCSTR init,
+ INT32 len, LPCSTR proto, void* sbuf, INT32 buflen, UINT32 flag);
/***********************************************************************
* WSAAsyncGetHostByAddr() (WINSOCK.102)
*/
-HANDLE16 WINAPI WSAAsyncGetHostByAddr(HWND16 hWnd, UINT16 uMsg, LPCSTR addr,
+HANDLE16 WINAPI WSAAsyncGetHostByAddr16(HWND16 hWnd, UINT16 uMsg, LPCSTR addr,
INT16 len, INT16 type, SEGPTR sbuf, INT16 buflen)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncGetHostByAddr(%08x): hwnd %04x, msg %04x, addr %08x[%i]\n",
+ dprintf_winsock(stddeb, "WS_AsyncGetHostByAddr16(%08x): hwnd %04x, msg %04x, addr %08x[%i]\n",
(unsigned)pwsi, hWnd, uMsg, (unsigned)addr , len );
if( pwsi )
return __WSAsyncDBQuery(pwsi, hWnd, uMsg, type, addr, len,
- NULL, sbuf, buflen, WSMSG_ASYNC_HOSTBYADDR );
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_HOSTBYADDR );
+ return 0;
+}
+
+/***********************************************************************
+ * WSAAsyncGetHostByAddr() (WSOCK32.102)
+ */
+HANDLE32 WINAPI WSAAsyncGetHostByAddr32(HWND32 hWnd, UINT32 uMsg, LPCSTR addr,
+ INT32 len, INT32 type, LPSTR sbuf, INT32 buflen)
+{
+ LPWSINFO pwsi = wsi_find(GetCurrentTask());
+
+ dprintf_winsock(stddeb, "WS_AsyncGetHostByAddr32(%08x): hwnd %04x, msg %08x, addr %08x[%i]\n",
+ (unsigned)pwsi, (HWND16)hWnd, uMsg, (unsigned)addr , len );
+
+ if( pwsi )
+ return __WSAsyncDBQuery(pwsi, hWnd, uMsg, type, addr, len,
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_HOSTBYADDR | WSMSG_ASYNC_WIN32);
return 0;
}
@@ -1610,17 +1665,17 @@
/***********************************************************************
* WSAAsyncGetHostByName() (WINSOCK.103)
*/
-HANDLE16 WINAPI WSAAsyncGetHostByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
+HANDLE16 WINAPI WSAAsyncGetHostByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
SEGPTR sbuf, INT16 buflen)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncGetHostByName(%08x): hwnd %04x, msg %04x, host %s, buffer %i\n",
- (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (int)buflen );
+ dprintf_winsock(stddeb, "WS_AsyncGetHostByName16(%08x): hwnd %04x, msg %04x, host %s,
+buffer %i\n", (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (int)buflen );
if( pwsi )
return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
- NULL, sbuf, buflen, WSMSG_ASYNC_HOSTBYNAME );
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_HOSTBYNAME );
return 0;
}
@@ -1628,12 +1683,14 @@
* WSAAsyncGetHostByName32() (WSOCK32.103)
*/
HANDLE32 WINAPI WSAAsyncGetHostByName32(HWND32 hWnd, UINT32 uMsg, LPCSTR name,
- LPSTR sbuf, INT32 buflen)
+ LPSTR sbuf, INT32 buflen)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncGetHostByName(%08x): hwnd %04x, msg %04x, host %s, buffer %i\n",
- (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (int)buflen );
-
+ dprintf_winsock(stddeb, "WS_AsyncGetHostByName32(%08x): hwnd %04x, msg %08x, host %s,
+buffer %i\n", (unsigned)pwsi, (HWND16)hWnd, uMsg, (name)?name:NULL_STRING, (int)buflen );
+ if( pwsi )
+ return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_HOSTBYNAME | WSMSG_ASYNC_WIN32);
return 0;
}
@@ -1641,17 +1698,34 @@
/***********************************************************************
* WSAAsyncGetProtoByName() (WINSOCK.105)
*/
-HANDLE16 WINAPI WSAAsyncGetProtoByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
- SEGPTR sbuf, INT16 buflen)
+HANDLE16 WINAPI WSAAsyncGetProtoByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
+ SEGPTR sbuf, INT16 buflen)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncGetProtoByName(%08x): hwnd %04x, msg %04x, protocol %s\n",
- (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING );
+ dprintf_winsock(stddeb, "WS_AsyncGetProtoByName16(%08x): hwnd %04x, msg %08x, protocol %s\n",
+ (unsigned)pwsi, (HWND16)hWnd, uMsg, (name)?name:NULL_STRING );
if( pwsi )
return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
- NULL, sbuf, buflen, WSMSG_ASYNC_PROTOBYNAME );
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_PROTOBYNAME );
+ return 0;
+}
+
+/***********************************************************************
+ * WSAAsyncGetProtoByName() (WSOCK32.105)
+ */
+HANDLE32 WINAPI WSAAsyncGetProtoByName32(HWND32 hWnd, UINT32 uMsg, LPCSTR name,
+ LPSTR sbuf, INT32 buflen)
+{
+ LPWSINFO pwsi = wsi_find(GetCurrentTask());
+
+ dprintf_winsock(stddeb, "WS_AsyncGetProtoByName32(%08x): hwnd %04x, msg %08x, protocol %s\n",
+ (unsigned)pwsi, (HWND16)hWnd, uMsg, (name)?name:NULL_STRING );
+
+ if( pwsi )
+ return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_PROTOBYNAME | WSMSG_ASYNC_WIN32);
return 0;
}
@@ -1659,17 +1733,34 @@
/***********************************************************************
* WSAAsyncGetProtoByNumber() (WINSOCK.104)
*/
-HANDLE16 WINAPI WSAAsyncGetProtoByNumber(HWND16 hWnd, UINT16 uMsg, INT16 number,
- SEGPTR sbuf, INT16 buflen)
+HANDLE16 WINAPI WSAAsyncGetProtoByNumber16(HWND16 hWnd, UINT16 uMsg, INT16 number,
+ SEGPTR sbuf, INT16 buflen)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncGetProtoByNumber(%08x): hwnd %04x, msg %04x, num %i\n",
+ dprintf_winsock(stddeb, "WS_AsyncGetProtoByNumber16(%08x): hwnd %04x, msg %04x, num %i\n",
(unsigned)pwsi, hWnd, uMsg, number );
if( pwsi )
return __WSAsyncDBQuery(pwsi, hWnd, uMsg, number, NULL, 0,
- NULL, sbuf, buflen, WSMSG_ASYNC_PROTOBYNUM );
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_PROTOBYNUM );
+ return 0;
+}
+
+/***********************************************************************
+ * WSAAsyncGetProtoByNumber() (WSOCK32.104)
+ */
+HANDLE32 WINAPI WSAAsyncGetProtoByNumber32(HWND32 hWnd, UINT32 uMsg, INT32 number,
+ LPSTR sbuf, INT32 buflen)
+{
+ LPWSINFO pwsi = wsi_find(GetCurrentTask());
+
+ dprintf_winsock(stddeb, "WS_AsyncGetProtoByNumber32(%08x): hwnd %04x, msg %08x, num %i\n",
+ (unsigned)pwsi, (HWND16)hWnd, uMsg, number );
+
+ if( pwsi )
+ return __WSAsyncDBQuery(pwsi, hWnd, uMsg, number, NULL, 0,
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_PROTOBYNUM | WSMSG_ASYNC_WIN32);
return 0;
}
@@ -1677,65 +1768,105 @@
/***********************************************************************
* WSAAsyncGetServByName() (WINSOCK.107)
*/
-HANDLE16 WINAPI WSAAsyncGetServByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
- LPCSTR proto, SEGPTR sbuf, INT16 buflen)
+HANDLE16 WINAPI WSAAsyncGetServByName16(HWND16 hWnd, UINT16 uMsg, LPCSTR name,
+ LPCSTR proto, SEGPTR sbuf, INT16 buflen)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncGetServByName(%08x): hwnd %04x, msg %04x, name %s, proto %s\n",
+ dprintf_winsock(stddeb, "WS_AsyncGetServByName16(%08x): hwnd %04x, msg %04x, name %s, proto %s\n",
(unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING );
if( pwsi )
return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
- proto, sbuf, buflen, WSMSG_ASYNC_SERVBYNAME );
+ proto, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME );
return 0;
}
/***********************************************************************
+ * WSAAsyncGetServByName() (WSOCK32.107)
+ */
+HANDLE32 WINAPI WSAAsyncGetServByName32(HWND32 hWnd, UINT32 uMsg, LPCSTR name,
+ LPCSTR proto, LPSTR sbuf, INT32 buflen)
+{
+ LPWSINFO pwsi = wsi_find(GetCurrentTask());
+
+ dprintf_winsock(stddeb, "WS_AsyncGetServByName32(%08x): hwnd %04x, msg %08x, name %s, proto %s\n",
+ (unsigned)pwsi, (HWND16)hWnd, uMsg, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING );
+ if( pwsi )
+ return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
+ proto, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME | WSMSG_ASYNC_WIN32);
+ return 0;
+}
+
+
+/***********************************************************************
* WSAAsyncGetServByPort() (WINSOCK.106)
*/
-HANDLE16 WINAPI WSAAsyncGetServByPort(HWND16 hWnd, UINT16 uMsg, INT16 port,
- LPCSTR proto, SEGPTR sbuf, INT16 buflen)
+HANDLE16 WINAPI WSAAsyncGetServByPort16(HWND16 hWnd, UINT16 uMsg, INT16 port,
+ LPCSTR proto, SEGPTR sbuf, INT16 buflen)
{
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncGetServByPort(%08x): hwnd %04x, msg %04x, port %i, proto %s\n",
+ dprintf_winsock(stddeb, "WS_AsyncGetServByPort16(%08x): hwnd %04x, msg %04x, port %i, proto %s\n",
(unsigned)pwsi, hWnd, uMsg, port, (proto)?proto:NULL_STRING );
if( pwsi )
return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, proto, 0,
- NULL, sbuf, buflen, WSMSG_ASYNC_SERVBYPORT );
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT );
return 0;
}
/***********************************************************************
- * WSACancelAsyncRequest() (WINSOCK.108)
+ * WSAAsyncGetServByPort() (WSOCK32.106)
*/
-INT16 WINAPI WSACancelAsyncRequest(HANDLE16 hAsyncTaskHandle)
+HANDLE32 WINAPI WSAAsyncGetServByPort32(HWND32 hWnd, UINT32 uMsg, INT32 port,
+ LPCSTR proto, LPSTR sbuf, INT32 buflen)
{
- INT16 retVal = SOCKET_ERROR;
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- ws_async_op* p_aop = (ws_async_op*)WS_HANDLE2PTR(hAsyncTaskHandle);
- dprintf_winsock(stddeb, "WS_CancelAsyncRequest(%08x): handle %04x\n",
- (unsigned)pwsi, hAsyncTaskHandle);
+ dprintf_winsock(stddeb, "WS_AsyncGetServByPort32(%08x): hwnd %04x, msg %08x, port %i, proto %s\n",
+ (unsigned)pwsi, (HWND16)hWnd, uMsg, port, (proto)?proto:NULL_STRING );
+
if( pwsi )
- {
- SIGNAL_MaskAsyncEvents( TRUE ); /* block SIGIO */
- if( WINSOCK_cancel_async_op(p_aop) )
- {
- WS_FREE(p_aop);
- pwsi->num_async_rq--;
- retVal = 0;
- }
- else pwsi->err = WSAEINVAL;
- SIGNAL_MaskAsyncEvents( FALSE );
- }
- return retVal;
+ return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, proto, 0,
+ NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT | WSMSG_ASYNC_WIN32);
+ return 0;
+}
+
+
+/***********************************************************************
+ * WSACancelAsyncRequest() (WINSOCK.108)(WSOCK32.109)
+ */
+INT32 WINAPI WSACancelAsyncRequest32(HANDLE32 hAsyncTaskHandle)
+{
+ INT32 retVal = SOCKET_ERROR;
+ LPWSINFO pwsi = wsi_find(GetCurrentTask());
+ ws_async_op* p_aop = (ws_async_op*)WS_HANDLE2PTR(hAsyncTaskHandle);
+
+ dprintf_winsock(stddeb, "WS_CancelAsyncRequest(%08x): handle %08x\n",
+ (unsigned)pwsi, hAsyncTaskHandle);
+ if( pwsi )
+ {
+ SIGNAL_MaskAsyncEvents( TRUE ); /* block SIGIO */
+ if( WINSOCK_cancel_async_op(p_aop) )
+ {
+ WS_FREE(p_aop);
+ pwsi->num_async_rq--;
+ retVal = 0;
+ }
+ else pwsi->err = WSAEINVAL;
+ SIGNAL_MaskAsyncEvents( FALSE );
+ }
+ return retVal;
+}
+
+INT16 WINAPI WSACancelAsyncRequest16(HANDLE16 hAsyncTaskHandle)
+{
+ return (HANDLE16)WSACancelAsyncRequest16((HANDLE32)hAsyncTaskHandle);
}
/***********************************************************************
- * WSAAsyncSelect() (WINSOCK.101)
+ * WSAAsyncSelect() (WINSOCK.101)(WSOCK32.101)
*/
static ws_select_op* __ws_select_list = NULL;
@@ -1838,7 +1969,7 @@
/* this will be reenabled when send() or sendto() fail with
* WSAEWOULDBLOCK */
- if( PostMessage16( psop->hWnd, psop->uMsg, (WPARAM16)WS_PTR2HANDLE(psop->pws),
+ if( PostMessage32A( psop->hWnd, psop->uMsg, (WPARAM32)WS_PTR2HANDLE(psop->pws),
(LPARAM)WSAMAKESELECTREPLY( WS_FD_WRITE, 0 ) ) )
{
dprintf_winsock(stddeb, "\t hwnd %04x - %04x, %08x\n",
@@ -1905,8 +2036,8 @@
{
dprintf_winsock(stddeb, "\t hwnd %04x - %04x, %08x\n",
psop->hWnd, psop->uMsg, (unsigned)dwEvent );
- PostMessage16( psop->hWnd, psop->uMsg,
- (WPARAM16)WS_PTR2HANDLE(psop->pws), (LPARAM)dwEvent );
+ PostMessage32A( psop->hWnd, psop->uMsg,
+ (WPARAM32)WS_PTR2HANDLE(psop->pws), (LPARAM)dwEvent );
bPost = FALSE;
num_posted++;
}
@@ -1918,14 +2049,13 @@
return ( num_posted ) ? TRUE : FALSE;
}
-
-INT16 WINAPI WSAAsyncSelect(SOCKET16 s, HWND16 hWnd, UINT16 uMsg, UINT32 lEvent)
+INT32 WINAPI WSAAsyncSelect32(SOCKET32 s, HWND32 hWnd, UINT32 uMsg, UINT32 lEvent)
{
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
LPWSINFO pwsi = wsi_find(GetCurrentTask());
- dprintf_winsock(stddeb, "WS_AsyncSelect(%08x): %04x, hWnd %04x, uMsg %04x, event %08x\n",
- (unsigned)pwsi, s, hWnd, uMsg, (unsigned)lEvent );
+ dprintf_winsock(stddeb, "WS_AsyncSelect(%08x): %04x, hWnd %04x, uMsg %08x, event %08x\n",
+ (unsigned)pwsi, (SOCKET16)s, (HWND16)hWnd, uMsg, (unsigned)lEvent );
if( _check_ws(pwsi, pws) )
{
ws_select_op* psop;
@@ -1996,15 +2126,20 @@
return SOCKET_ERROR;
}
+INT16 WINAPI WSAAsyncSelect16(SOCKET16 s, HWND16 hWnd, UINT16 wMsg, UINT32 lEvent)
+{
+ return (INT16)WSAAsyncSelect32( s, hWnd, wMsg, lEvent );
+}
+
/***********************************************************************
* __WSAFDIsSet() (WINSOCK.151)
*/
-INT16 WINAPI __WSAFDIsSet16(SOCKET16 s, ws_fd_set *set)
+INT16 WINAPI __WSAFDIsSet16(SOCKET16 s, ws_fd_set16 *set)
{
int i = set->fd_count;
- dprintf_winsock(stddeb, "__WSAFDIsSet(%d,%8lx)\n", s,(unsigned long)set);
+ dprintf_winsock(stddeb, "__WSAFDIsSet16(%d,%8lx)\n", s,(unsigned long)set);
while (i--)
if (set->fd_array[i] == s) return 1;
@@ -2014,9 +2149,15 @@
/***********************************************************************
* __WSAFDIsSet() (WSOCK32.151)
*/
-INT32 WINAPI __WSAFDIsSet32(SOCKET32 s, ws_fd_set *set)
+INT32 WINAPI __WSAFDIsSet32(SOCKET32 s, ws_fd_set32 *set)
{
- return __WSAFDIsSet16( (SOCKET16)s, set );
+ int i = set->fd_count;
+
+ dprintf_winsock(stddeb, "__WSAFDIsSet32(%d,%8lx)\n", s,(unsigned long)set);
+
+ while (i--)
+ if (set->fd_array[i] == s) return 1;
+ return 0;
}
/***********************************************************************
@@ -2121,25 +2262,74 @@
return SOCKET_ERROR;
}
+/*
+ * TCP/IP action codes.
+ */
+
+
+#define WSCNTL_TCPIP_QUERY_INFO 0x00000000
+#define WSCNTL_TCPIP_SET_INFO 0x00000001
+#define WSCNTL_TCPIP_ICMP_ECHO 0x00000002
+#define WSCNTL_TCPIP_TEST 0x00000003
+
+
/***********************************************************************
* WsControl()
+ *
+ * WsControl seems to be an undocumented Win95 function. A lot of
+ * discussion about WsControl can be found on the net, e.g.
+ * Subject: Re: WSOCK32.DLL WsControl Exported Function
+ * From: "Peter Rindfuss" <rindfuss-s@medea.wz-berlin.de>
+ * Date: 1997/08/17
*/
-VOID WINAPI WsControl(DWORD x1,DWORD x2,LPDWORD x3,LPDWORD x4,
- LPDWORD x5,LPDWORD x6)
+
+DWORD WINAPI WsControl(DWORD protocoll,DWORD action,
+ LPVOID inbuf,LPDWORD inbuflen,
+ LPVOID outbuf,LPDWORD outbuflen)
{
- fprintf(stdnimp,"WsControl(%lx,%lx,%p,%p,%p,%p)\n",
- x1,x2,x3,x4,x5,x6
- );
- fprintf(stdnimp,"WsControl(x,x,%lx,%lx,%lx,%lx)\n",
- x3?*x3:0,x4?*x4:0,x5?*x5:0,x6?*x6:0
- );
+
+ switch (action) {
+ case WSCNTL_TCPIP_ICMP_ECHO:
+ {
+ unsigned int addr = *(unsigned int*)inbuf;
+#if 0
+ int timeout= *(unsigned int*)(inbuf+4);
+ short x1 = *(unsigned short*)(inbuf+8);
+ short sendbufsize = *(unsigned short*)(inbuf+10);
+ char x2 = *(unsigned char*)(inbuf+12);
+ char ttl = *(unsigned char*)(inbuf+13);
+ char service = *(unsigned char*)(inbuf+14);
+ char type= *(unsigned char*)(inbuf+15); /* 0x2: don't fragment*/
+#endif
+
+ fprintf(stdnimp,"WsControl(ICMP_ECHO) to 0x%08x stub \n",
+ addr);
+ break;
+ }
+ default:
+ fprintf(stdnimp,"WsControl(%lx,%lx,%p,%p,%p,%p) stub\n",
+ protocoll,action,inbuf,inbuflen,outbuf,outbuflen);
+ }
+ return FALSE;
+}
+/*********************************************************
+ * WS_s_perror WSOCK32.1108
+ */
+void WINAPI WS_s_perror(LPCSTR message)
+{
+ fprintf(stdnimp,"s_perror %s stub\n",message);
return;
}
+
+
/* ----------------------------------- end of API stuff */
-
-
-/* ----------------------------------- helper functions */
+/* ----------------------------------- helper functions -
+ *
+ * TODO: Merge WS_dup_..() stuff into one function that
+ * would operate with a generic structure containing internal
+ * pointers (via some sort of a template).
+ */
static int list_size(char** l, int item_size)
{
@@ -2193,34 +2383,29 @@
int size = hostent_size(p_he);
if( size )
{
- char* p_name,*p_aliases,*p_addr,*p_base,*p;
+ struct ws_hostent* p_to;
+ char* p_name,*p_aliases,*p_addr,*p_base,*p;
_check_buffer(pwsi, size);
+ p_to = (struct ws_hostent*)pwsi->buffer;
p = pwsi->buffer;
p_base = (flag & WS_DUP_OFFSET) ? NULL
: ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
- p += (flag & WS_DUP_NATIVE) ? sizeof(struct hostent) : sizeof(struct ws_hostent);
+ p += sizeof(struct ws_hostent);
p_name = p;
strcpy(p, p_he->h_name); p += strlen(p) + 1;
p_aliases = p;
p += list_dup(p_he->h_aliases, p, p_base + (p - pwsi->buffer), 0);
p_addr = p;
list_dup(p_he->h_addr_list, p, p_base + (p - pwsi->buffer), p_he->h_length);
- if( flag & WS_DUP_NATIVE )
- { struct hostent* p_to = (struct hostent*)pwsi->buffer;
- p_to->h_addrtype = p_he->h_addrtype; p_to->h_length = p_he->h_length;
- p_to->h_name = p_base + (p_name - pwsi->buffer);
- p_to->h_aliases = (char**)(p_base + (p_aliases - pwsi->buffer));
- p_to->h_addr_list = (char**)(p_base + (p_addr - pwsi->buffer)); }
- else
- { struct ws_hostent* p_to = (struct ws_hostent*)pwsi->buffer;
- p_to->h_addrtype = (INT16)p_he->h_addrtype;
- p_to->h_length = (INT16)p_he->h_length;
- p_to->h_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
- p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
- p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - pwsi->buffer));
- return (size + sizeof(struct ws_hostent) - sizeof(struct hostent)); }
+ p_to->h_addrtype = (INT16)p_he->h_addrtype;
+ p_to->h_length = (INT16)p_he->h_length;
+ p_to->h_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
+ p_to->h_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
+ p_to->h_addr_list = (SEGPTR)(p_base + (p_addr - pwsi->buffer));
+
+ size += (sizeof(struct ws_hostent) - sizeof(struct hostent));
}
return size;
}
@@ -2242,28 +2427,25 @@
int size = protoent_size(p_pe);
if( size )
{
- char* p_name,*p_aliases,*p_base,*p;
+ struct ws_protoent* p_to;
+ char* p_name,*p_aliases,*p_base,*p;
_check_buffer(pwsi, size);
+ p_to = (struct ws_protoent*)pwsi->buffer;
p = pwsi->buffer;
p_base = (flag & WS_DUP_OFFSET) ? NULL
: ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
- p += (flag & WS_DUP_NATIVE)? sizeof(struct protoent) : sizeof(struct ws_protoent);
+ p += sizeof(struct ws_protoent);
p_name = p;
strcpy(p, p_pe->p_name); p += strlen(p) + 1;
p_aliases = p;
list_dup(p_pe->p_aliases, p, p_base + (p - pwsi->buffer), 0);
- if( flag & WS_DUP_NATIVE )
- { struct protoent* p_to = (struct protoent*)pwsi->buffer;
- p_to->p_proto = p_pe->p_proto;
- p_to->p_name = p_base + (p_name - pwsi->buffer);
- p_to->p_aliases = (char**)(p_base + (p_aliases - pwsi->buffer)); }
- else
- { struct ws_protoent* p_to = (struct ws_protoent*)pwsi->buffer;
- p_to->p_proto = (INT16)p_pe->p_proto;
- p_to->p_name = (SEGPTR)(p_base) + (p_name - pwsi->buffer);
- p_to->p_aliases = (SEGPTR)((p_base) + (p_aliases - pwsi->buffer));
- return (size + sizeof(struct ws_protoent) - sizeof(struct protoent)); }
+
+ p_to->p_proto = (INT16)p_pe->p_proto;
+ p_to->p_name = (SEGPTR)(p_base) + (p_name - pwsi->buffer);
+ p_to->p_aliases = (SEGPTR)((p_base) + (p_aliases - pwsi->buffer));
+
+ size += (sizeof(struct ws_protoent) - sizeof(struct protoent));
}
return size;
}
@@ -2285,9 +2467,11 @@
int size = servent_size(p_se);
if( size )
{
- char* p_name,*p_aliases,*p_proto,*p_base,*p;
+ struct ws_servent* p_to;
+ char* p_name,*p_aliases,*p_proto,*p_base,*p;
_check_buffer(pwsi, size);
+ p_to = (struct ws_servent*)pwsi->buffer;
p = pwsi->buffer;
p_base = (flag & WS_DUP_OFFSET) ? NULL
: ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
@@ -2299,19 +2483,12 @@
p_aliases = p;
list_dup(p_se->s_aliases, p, p_base + (p - pwsi->buffer), 0);
- if( flag & WS_DUP_NATIVE )
- { struct servent* p_to = (struct servent*)pwsi->buffer;
- p_to->s_port = p_se->s_port;
- p_to->s_name = p_base + (p_name - pwsi->buffer);
- p_to->s_proto = p_base + (p_proto - pwsi->buffer);
- p_to->s_aliases = (char**)(p_base + (p_aliases - pwsi->buffer)); }
- else
- { struct ws_servent* p_to = (struct ws_servent*)pwsi->buffer;
- p_to->s_port = (INT16)p_se->s_port;
- p_to->s_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
- p_to->s_proto = (SEGPTR)(p_base + (p_proto - pwsi->buffer));
- p_to->s_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
- return (size + sizeof(struct ws_servent) - sizeof(struct servent)); }
+ p_to->s_port = (INT16)p_se->s_port;
+ p_to->s_name = (SEGPTR)(p_base + (p_name - pwsi->buffer));
+ p_to->s_proto = (SEGPTR)(p_base + (p_proto - pwsi->buffer));
+ p_to->s_aliases = (SEGPTR)(p_base + (p_aliases - pwsi->buffer));
+
+ size += (sizeof(struct ws_servent) - sizeof(struct servent));
}
return size;
}
@@ -2323,7 +2500,7 @@
int loc_errno = errno;
#if defined(__FreeBSD__)
dprintf_winsock(stderr, "winsock: errno %d, (%s).\n",
- errno, sys_errlist[errno]);
+ errno, strerror(errno));
#else
dprintf_winsock(stderr, "winsock: errno %d\n", errno);
#endif
@@ -2398,7 +2575,7 @@
#if defined(__FreeBSD__)
dprintf_winsock(stderr, "winsock: h_errno %d, (%s).\n",
- h_errno, sys_errlist[h_errno]);
+ h_errno, strerror(h_errno));
#else
dprintf_winsock(stderr, "winsock: h_errno %d.\n", h_errno);
#ifndef sun
diff --git a/misc/winsock_dns.c b/misc/winsock_dns.c
index 173f6bb..94224de 100644
--- a/misc/winsock_dns.c
+++ b/misc/winsock_dns.c
@@ -29,12 +29,12 @@
extern int h_errno;
+#include "winsock.h"
#include "windows.h"
#include "heap.h"
#include "ldt.h"
#include "message.h"
#include "miscemu.h"
-#include "winsock.h"
#include "debug.h"
#ifndef FASYNC
@@ -67,9 +67,9 @@
static fd_set __async_io_fdset;
static ws_async_op* __async_op_list = NULL;
-static void fixup_wshe(struct ws_hostent* p_wshe, SEGPTR base);
-static void fixup_wspe(struct ws_protoent* p_wspe, SEGPTR base);
-static void fixup_wsse(struct ws_servent* p_wsse, SEGPTR base);
+static void fixup_wshe(struct ws_hostent* p_wshe, void* base);
+static void fixup_wspe(struct ws_protoent* p_wspe, void* base);
+static void fixup_wsse(struct ws_servent* p_wsse, void* base);
extern void EVENT_AddIO( int fd, unsigned flag );
extern void EVENT_DeleteIO( int fd, unsigned flag );
@@ -274,19 +274,21 @@
{
if( (int)LOWORD(lLength) <= p_aop->buflen )
{
- char* buffer = (char*)PTR_SEG_TO_LIN(p_aop->buffer_base);
+ char* buffer = (p_aop->flags & WSMSG_ASYNC_WIN32)
+ ? p_aop->b.lin_base : (char*)PTR_SEG_TO_LIN(p_aop->b.seg_base);
+
read(p_aop->fd[0], buffer, LOWORD(lLength));
switch( p_aop->flags )
{
case WSMSG_ASYNC_HOSTBYNAME:
case WSMSG_ASYNC_HOSTBYADDR:
- fixup_wshe((struct ws_hostent*)buffer, p_aop->buffer_base); break;
+ fixup_wshe((struct ws_hostent*)buffer, p_aop->b.ptr_base); break;
case WSMSG_ASYNC_PROTOBYNAME:
case WSMSG_ASYNC_PROTOBYNUM:
- fixup_wspe((struct ws_protoent*)buffer, p_aop->buffer_base); break;
+ fixup_wspe((struct ws_protoent*)buffer, p_aop->b.ptr_base); break;
case WSMSG_ASYNC_SERVBYNAME:
case WSMSG_ASYNC_SERVBYPORT:
- fixup_wsse((struct ws_servent*)buffer, p_aop->buffer_base); break;
+ fixup_wsse((struct ws_servent*)buffer, p_aop->b.ptr_base); break;
default:
if( p_aop->flags ) fprintf(stderr,"Received unknown async request!\n");
return AOP_CONTROL_REMOVE;
@@ -302,14 +304,14 @@
/* FIXME: update num_async_rq */
EVENT_DeleteIO( p_aop->fd[0], EVENT_IO_READ );
- PostMessage16( p_aop->hWnd, p_aop->uMsg, __ws_gethandle(p_aop), (LPARAM)lLength );
+ PostMessage32A( p_aop->hWnd, p_aop->uMsg, __ws_gethandle(p_aop), (LPARAM)lLength );
return AOP_CONTROL_REMOVE; /* one-shot request */
}
-HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND16 hWnd, UINT16 uMsg, INT16 type, LPSTR init,
- INT16 len, LPSTR proto, SEGPTR sbuf, INT16 buflen, UINT32 flag)
+HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND32 hWnd, UINT32 uMsg, INT32 type, LPSTR init,
+ INT32 len, LPSTR proto, void* sbuf, INT32 buflen, UINT32 flag)
{
/* queue 'flag' request and fork off its handler */
@@ -328,7 +330,8 @@
async_ctl.ws_aop->hWnd = hWnd;
async_ctl.ws_aop->uMsg = uMsg;
- async_ctl.ws_aop->buffer_base = sbuf; async_ctl.ws_aop->buflen = buflen;
+ async_ctl.ws_aop->b.ptr_base = sbuf;
+ async_ctl.ws_aop->buflen = buflen;
async_ctl.ws_aop->flags = flag;
async_ctl.ws_aop->aop_control = &aop_control;
@@ -441,19 +444,20 @@
close(async_ctl.ws_aop->fd[0]);
- dprintf_winsock(stddeb,"DNS: getting hostent for [%s]\n", async_ctl.rq.name );
-
p_he = (flag & WSMSG_ASYNC_HOSTBYNAME)
? gethostbyname(async_ctl.rq.name)
: gethostbyaddr(async_ctl.rq.name,
async_ctl.ilength, async_ctl.type);
- dprintf_winsock(stddeb,"DNS: done!\n");
- if( p_he ) size = WS_dup_he(pwsi, p_he, WS_DUP_SEGPTR | WS_DUP_OFFSET );
+ dprintf_winsock(stddeb,"DNS: got hostent for [%s]\n", async_ctl.rq.name );
+
+ if( p_he ) /* convert to the Winsock format with internal pointers as offsets */
+ size = WS_dup_he(pwsi, p_he, WS_DUP_OFFSET |
+ ((flag & WSMSG_ASYNC_WIN32) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
if( size )
{
- async_ctl.buffer = pwsi->buffer;
- async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
+ async_ctl.buffer = pwsi->buffer;
+ async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
_async_notify( flag );
}
else _async_fail();
@@ -468,11 +472,16 @@
p_pe = (flag & WSMSG_ASYNC_PROTOBYNAME)
? getprotobyname(async_ctl.rq.name)
: getprotobynumber(async_ctl.type);
- if( p_pe ) size = WS_dup_pe(pwsi, p_pe, WS_DUP_SEGPTR | WS_DUP_OFFSET );
+
+ dprintf_winsock(stddeb,"DNS: got protoent for [%s]\n", async_ctl.rq.name );
+
+ if( p_pe ) /* convert to the Winsock format with internal pointers as offsets */
+ size = WS_dup_pe(pwsi, p_pe, WS_DUP_OFFSET |
+ ((flag & WSMSG_ASYNC_WIN32) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
if( size )
{
- async_ctl.buffer = pwsi->buffer;
- async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
+ async_ctl.buffer = pwsi->buffer;
+ async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
_async_notify( flag );
}
else _async_fail();
@@ -487,19 +496,32 @@
p_se = (flag & WSMSG_ASYNC_SERVBYNAME)
? getservbyname(async_ctl.rq.name, async_ctl.buffer)
: getservbyport(async_ctl.type, async_ctl.buffer);
- if( p_se ) size = WS_dup_se(pwsi, p_se, WS_DUP_SEGPTR | WS_DUP_OFFSET );
+
+ if( p_se ) /* convert to the Winsock format with internal pointers as offsets */
+ size = WS_dup_se(pwsi, p_se, WS_DUP_OFFSET |
+ ((flag & WSMSG_ASYNC_WIN32) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
if( size )
{
- async_ctl.buffer = pwsi->buffer;
- async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
+ async_ctl.buffer = pwsi->buffer;
+ async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
_async_notify( flag );
}
else _async_fail();
}
-/* ----------------------------------- helper functions */
+/* ----------------------------------- helper functions -
+ *
+ * Raw results from pipe contain internal pointers stored as
+ * offsets relative to the beginning of the buffer and we need
+ * to apply a fixup before passing them to applications.
+ *
+ * NOTE: It is possible to exploit the fact that fork() doesn't
+ * change the buffer address by storing fixed up pointers right
+ * in the handler. However, this will get in the way if we ever
+ * get to implementing DNS helper daemon a-la Netscape.
+ */
-void fixup_wshe(struct ws_hostent* p_wshe, SEGPTR base)
+void fixup_wshe(struct ws_hostent* p_wshe, void* base)
{
/* add 'base' to ws_hostent pointers to convert them from offsets */
@@ -515,7 +537,7 @@
for(i=0;p_addr[i];i++) p_addr[i] += (unsigned)base;
}
-void fixup_wspe(struct ws_protoent* p_wspe, SEGPTR base)
+void fixup_wspe(struct ws_protoent* p_wspe, void* base)
{
int i;
unsigned* p_aliases = (unsigned*)((char*)p_wspe + (unsigned)p_wspe->p_aliases);
@@ -524,7 +546,7 @@
for(i=0;p_aliases[i];i++) p_aliases[i] += (unsigned)base;
}
-void fixup_wsse(struct ws_servent* p_wsse, SEGPTR base)
+void fixup_wsse(struct ws_servent* p_wsse, void* base)
{
int i;
unsigned* p_aliases = (unsigned*)((char*)p_wsse + (unsigned)p_wsse->s_aliases);
diff --git a/miscemu/instr.c b/miscemu/instr.c
index c101d21..46cd421 100644
--- a/miscemu/instr.c
+++ b/miscemu/instr.c
@@ -22,20 +22,23 @@
* INSTR_ReplaceSelector
*
* Try to replace an invalid selector by a valid one.
- * For now, only selector 0x40 is handled here.
+ * The only selector where it is allowed to do "mov ax,40;mov es,ax"
+ * is the so called 'bimodal' selector 0x40, which points to the BIOS
+ * data segment. Used by (at least) Borland products (and programs compiled
+ * using Borland products).
+ *
+ * See Undocumented Windows, Chapter 5, __0040.
*/
static WORD INSTR_ReplaceSelector( SIGCONTEXT *context, WORD sel)
{
if (sel == 0x40)
{
static WORD sys_timer = 0;
- fprintf( stderr, "Direct access to segment 0x40 (cs:ip=%04x:%04lx).\n",
- CS_sig(context), EIP_sig(context) );
if (!sys_timer)
sys_timer = CreateSystemTimer( 55, (FARPROC16)DOSMEM_Tick );
return DOSMEM_BiosSeg;
}
- return 0; /* Can't replace selector */
+ return 0; /* Can't replace selector, crashdump */
}
diff --git a/msdos/int13.c b/msdos/int13.c
index eb9560c..1e86258 100644
--- a/msdos/int13.c
+++ b/msdos/int13.c
@@ -25,15 +25,13 @@
break;
case 0x05: /* FORMAT TRACK */
+ case 0x06: /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
+ case 0x07: /* FORMAT DRIVE STARTING AT GIVEN TRACK */
+ /* despite of what Ralf Brown says, 0x06 and 0x07 seem to set CFLAG, too (at least my BIOS does that) */
AH_reg(context) = 0x0c;
SET_CFLAG(context);
break;
- case 0x06: /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
- case 0x07: /* FORMAT DRIVE STARTING AT GIVEN TRACK */
- AH_reg(context) = 0x0c;
- break;
-
case 0x08: /* GET DRIVE PARAMETERS */
AH_reg(context) = (DL_reg(context) & 0x80) ? 0x07 : 0x01;
SET_CFLAG(context);
diff --git a/multimedia/audio.c b/multimedia/audio.c
index 0d5e14c..58d8365 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -1738,7 +1738,7 @@
* AUDIO_DriverProc [sample driver]
*/
LONG WAVE_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
#if defined(linux) || defined(__FreeBSD__)
dprintf_mciwave(stddeb,"WAVE_DriverProc(%08lX, %04X, %04X, %08lX, %08lX)\n",
diff --git a/multimedia/joystick.c b/multimedia/joystick.c
index cdd65ab..97f4016 100644
--- a/multimedia/joystick.c
+++ b/multimedia/joystick.c
@@ -1,5 +1,5 @@
/*
- * Joystick functions
+ * joystick functions
*
* Copyright 1997 Andreas Mohr
*/
@@ -21,10 +21,10 @@
static int count_use[4] = {0, 0, 0, 0};
static int dev_stat;
static int joy_nr_open = 0;
-static BOOL16 JoyCaptured = FALSE;
+static BOOL16 joyCaptured = FALSE;
static HWND16 CaptureWnd[2] = {0, 0};
static int joy_dev[2] = {-1, -1};
-static JOYINFO JoyCapData[2];
+static JOYINFO16 joyCapData[2];
static unsigned int joy_threshold[2] = {0, 0};
struct js_status
@@ -36,9 +36,9 @@
/**************************************************************************
- * JoyOpenDriver [internal]
+ * joyOpenDriver [internal]
*/
-BOOL16 JoyOpenDriver(WORD wID)
+BOOL16 joyOpenDriver(WORD wID)
{
char dev_name[] = "/dev/jsx";
@@ -52,9 +52,9 @@
}
/**************************************************************************
- * JoyCloseDriver [internal]
+ * joyCloseDriver [internal]
*/
-void JoyCloseDriver(WORD wID)
+void joyCloseDriver(WORD wID)
{
if (joy_dev[wID] >= 0) {
close(joy_dev[wID]);
@@ -64,9 +64,9 @@
}
/**************************************************************************
- * JoySendMessages [internal]
+ * joySendMessages [internal]
*/
-void JoySendMessages(void)
+void joySendMessages(void)
{
int joy;
struct js_status js;
@@ -75,67 +75,146 @@
for (joy=0; joy < 4; joy++)
if (joy_dev[joy] >= 0) {
if (count_use[joy] > 250) {
- JoyCloseDriver(joy);
+ joyCloseDriver(joy);
count_use[joy] = 0;
}
count_use[joy]++;
}
else return;
- if (JoyCaptured == FALSE) return;
+ if (joyCaptured == FALSE) return;
dprintf_mmsys(stddeb, "JoySendMessages()\n");
for (joy=0; joy < 4; joy++) {
- if (JoyOpenDriver(joy) == FALSE) continue;
+ if (joyOpenDriver(joy) == FALSE) continue;
dev_stat = read(joy_dev[joy], &js, sizeof(js));
if (dev_stat == sizeof(js)) {
js.x = js.x*37;
js.y = js.y*37;
- if ((JoyCapData[joy].wXpos != js.x) || (JoyCapData[joy].wYpos != js.y)) {
+ if ((joyCapData[joy].wXpos != js.x) || (joyCapData[joy].wYpos != js.y)) {
SendMessage32A(CaptureWnd[joy], MM_JOY1MOVE + joy, js.buttons, MAKELONG(js.x, js.y));
- JoyCapData[joy].wXpos = js.x;
- JoyCapData[joy].wYpos = js.y;
+ joyCapData[joy].wXpos = js.x;
+ joyCapData[joy].wYpos = js.y;
}
- if (JoyCapData[joy].wButtons != js.buttons) {
- unsigned int ButtonChanged = (WORD)(JoyCapData[joy].wButtons ^ js.buttons)<<8;
- if (JoyCapData[joy].wButtons < js.buttons)
+ if (joyCapData[joy].wButtons != js.buttons) {
+ unsigned int ButtonChanged = (WORD)(joyCapData[joy].wButtons ^ js.buttons)<<8;
+ if (joyCapData[joy].wButtons < js.buttons)
SendMessage32A(CaptureWnd[joy], MM_JOY1BUTTONDOWN + joy, ButtonChanged, MAKELONG(js.x, js.y));
else
- if (JoyCapData[joy].wButtons > js.buttons)
+ if (joyCapData[joy].wButtons > js.buttons)
SendMessage32A(CaptureWnd[joy], MM_JOY1BUTTONUP
+ joy, ButtonChanged, MAKELONG(js.x, js.y));
- JoyCapData[joy].wButtons = js.buttons;
+ joyCapData[joy].wButtons = js.buttons;
}
}
}
}
+
/**************************************************************************
* JoyGetNumDevs [MMSYSTEM.101]
*/
-WORD WINAPI JoyGetNumDevs(void)
+UINT32 WINAPI joyGetNumDevs32(void)
{
-int joy;
-WORD joy_cnt = 0;
+ return joyGetNumDevs16();
+}
+
+/**************************************************************************
+ * JoyGetNumDevs [MMSYSTEM.101]
+ */
+UINT16 WINAPI joyGetNumDevs16(void)
+{
+ int joy;
+ UINT16 joy_cnt = 0;
dprintf_mmsys(stddeb, "JoyGetNumDevs: ");
for (joy=0; joy<4; joy++)
- if (JoyOpenDriver(joy) == TRUE) {
- JoyCloseDriver(joy);
+ if (joyOpenDriver(joy) == TRUE) {
+ joyCloseDriver(joy);
joy_cnt++;
- }
+ }
dprintf_mmsys(stddeb, "returning %d\n", joy_cnt);
if (!joy_cnt) fprintf(stderr, "No joystick found - perhaps get joystick-0.8.0.tar.gz and load it as module or use Linux >= 2.1.45 to be able to use joysticks.\n");
return joy_cnt;
}
/**************************************************************************
+ * JoyGetDevCaps [WINMM.27]
+ */
+MMRESULT32 WINAPI joyGetDevCaps32A(UINT32 wID, LPJOYCAPS32A lpCaps,UINT32 wSize)
+{
+ JOYCAPS16 jc16;
+ MMRESULT16 ret = joyGetDevCaps16(wID,&jc16,sizeof(jc16));
+
+ lpCaps->wMid = jc16.wMid;
+ lpCaps->wPid = jc16.wPid;
+ lstrcpy32A(lpCaps->szPname,jc16.szPname);
+ lpCaps->wXmin = jc16.wXmin;
+ lpCaps->wXmax = jc16.wXmax;
+ lpCaps->wYmin = jc16.wYmin;
+ lpCaps->wYmax = jc16.wYmax;
+ lpCaps->wZmin = jc16.wZmin;
+ lpCaps->wZmax = jc16.wZmax;
+ lpCaps->wNumButtons = jc16.wNumButtons;
+ lpCaps->wPeriodMin = jc16.wPeriodMin;
+ lpCaps->wPeriodMax = jc16.wPeriodMax;
+
+ lpCaps->wRmin = jc16.wRmin;
+ lpCaps->wRmax = jc16.wRmax;
+ lpCaps->wUmin = jc16.wUmin;
+ lpCaps->wUmax = jc16.wUmax;
+ lpCaps->wVmin = jc16.wVmin;
+ lpCaps->wVmax = jc16.wVmax;
+ lpCaps->wCaps = jc16.wCaps;
+ lpCaps->wMaxAxes = jc16.wMaxAxes;
+ lpCaps->wNumAxes = jc16.wNumAxes;
+ lpCaps->wMaxButtons = jc16.wMaxButtons;
+ lstrcpy32A(lpCaps->szRegKey,jc16.szRegKey);
+ lstrcpy32A(lpCaps->szOEMVxD,jc16.szOEMVxD);
+ return ret;
+}
+
+/**************************************************************************
+ * JoyGetDevCaps [WINMM.28]
+ */
+MMRESULT32 WINAPI joyGetDevCaps32W(UINT32 wID, LPJOYCAPS32W lpCaps,UINT32 wSize)
+{
+ JOYCAPS16 jc16;
+ MMRESULT16 ret = joyGetDevCaps16(wID,&jc16,sizeof(jc16));
+
+ lpCaps->wMid = jc16.wMid;
+ lpCaps->wPid = jc16.wPid;
+ lstrcpyAtoW(lpCaps->szPname,jc16.szPname);
+ lpCaps->wXmin = jc16.wXmin;
+ lpCaps->wXmax = jc16.wXmax;
+ lpCaps->wYmin = jc16.wYmin;
+ lpCaps->wYmax = jc16.wYmax;
+ lpCaps->wZmin = jc16.wZmin;
+ lpCaps->wZmax = jc16.wZmax;
+ lpCaps->wNumButtons = jc16.wNumButtons;
+ lpCaps->wPeriodMin = jc16.wPeriodMin;
+ lpCaps->wPeriodMax = jc16.wPeriodMax;
+
+ lpCaps->wRmin = jc16.wRmin;
+ lpCaps->wRmax = jc16.wRmax;
+ lpCaps->wUmin = jc16.wUmin;
+ lpCaps->wUmax = jc16.wUmax;
+ lpCaps->wVmin = jc16.wVmin;
+ lpCaps->wVmax = jc16.wVmax;
+ lpCaps->wCaps = jc16.wCaps;
+ lpCaps->wMaxAxes = jc16.wMaxAxes;
+ lpCaps->wNumAxes = jc16.wNumAxes;
+ lpCaps->wMaxButtons = jc16.wMaxButtons;
+ lstrcpyAtoW(lpCaps->szRegKey,jc16.szRegKey);
+ lstrcpyAtoW(lpCaps->szOEMVxD,jc16.szOEMVxD);
+ return ret;
+}
+/**************************************************************************
* JoyGetDevCaps [MMSYSTEM.102]
*/
-WORD WINAPI JoyGetDevCaps(WORD wID, LPJOYCAPS lpCaps, WORD wSize)
+MMRESULT16 WINAPI joyGetDevCaps16(UINT16 wID, LPJOYCAPS16 lpCaps, UINT16 wSize)
{
dprintf_mmsys(stderr, "JoyGetDevCaps(%04X, %p, %d);\n",
wID, lpCaps, wSize);
- if (wSize != sizeof(*lpCaps)) return JOYERR_PARMS; /* FIXME: should we really return this error value ? */
- if (JoyOpenDriver(wID) == TRUE) {
+ if (joyOpenDriver(wID) == TRUE) {
lpCaps->wMid = MM_MICROSOFT;
lpCaps->wPid = MM_PC_JOYSTICK;
strcpy(lpCaps->szPname, "WineJoy"); /* joystick product name */
@@ -148,8 +227,22 @@
lpCaps->wNumButtons = 2;
lpCaps->wPeriodMin = 0;
lpCaps->wPeriodMax = 50; /* FIXME end */
-
- JoyCloseDriver(wID);
+ if (wSize == sizeof(JOYCAPS16)) {
+ /* complete 95 structure */
+ lpCaps->wRmin = 0;
+ lpCaps->wRmax = 0xffff;
+ lpCaps->wUmin = 0;
+ lpCaps->wUmax = 0xffff;
+ lpCaps->wVmin = 0;
+ lpCaps->wVmax = 0xffff;
+ lpCaps->wCaps = 0;
+ lpCaps->wMaxAxes = 6;
+ lpCaps->wNumAxes = 2;
+ lpCaps->wMaxButtons = 3;
+ strcpy(lpCaps->szRegKey,"");
+ strcpy(lpCaps->szOEMVxD,"");
+ }
+ joyCloseDriver(wID);
return JOYERR_NOERROR;
}
else
@@ -157,17 +250,32 @@
}
/**************************************************************************
+ * JoyGetPos [WINMM.30]
+ */
+MMRESULT32 WINAPI joyGetPos32(UINT32 wID, LPJOYINFO32 lpInfo)
+{
+ JOYINFO16 ji;
+ MMRESULT16 ret = joyGetPos16(wID,&ji);
+
+ lpInfo->wXpos = ji.wXpos;
+ lpInfo->wYpos = ji.wYpos;
+ lpInfo->wZpos = ji.wZpos;
+ lpInfo->wButtons = ji.wButtons;
+ return ret;
+}
+
+/**************************************************************************
* JoyGetPos [MMSYSTEM.103]
*/
-WORD WINAPI JoyGetPos(WORD wID, LPJOYINFO lpInfo)
+MMRESULT16 WINAPI joyGetPos16(UINT16 wID, LPJOYINFO16 lpInfo)
{
struct js_status js;
dprintf_mmsys(stderr, "JoyGetPos(%04X, %p):", wID, lpInfo);
- if (JoyOpenDriver(wID) == FALSE) return MMSYSERR_NODRIVER;
+ if (joyOpenDriver(wID) == FALSE) return MMSYSERR_NODRIVER;
dev_stat = read(joy_dev[wID], &js, sizeof(js));
if (dev_stat != sizeof(js)) {
- JoyCloseDriver(wID);
+ joyCloseDriver(wID);
return JOYERR_UNPLUGGED; /* FIXME: perhaps wrong, but what should I return else ? */
}
count_use[wID] = 0;
@@ -182,9 +290,21 @@
}
/**************************************************************************
+ * JoyGetThreshold [WINMM.32]
+ */
+MMRESULT32 WINAPI joyGetThreshold32(UINT32 wID, LPUINT32 lpThreshold)
+{
+ UINT16 thresh;
+ MMRESULT16 ret = joyGetThreshold16(wID,&thresh);
+
+ *lpThreshold = thresh;
+ return ret;
+}
+
+/**************************************************************************
* JoyGetThreshold [MMSYSTEM.104]
*/
-WORD WINAPI JoyGetThreshold(WORD wID, LPWORD lpThreshold)
+MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
{
dprintf_mmsys(stderr, "JoyGetThreshold(%04X, %p);\n", wID, lpThreshold);
if (wID > 3) return JOYERR_PARMS;
@@ -193,13 +313,21 @@
}
/**************************************************************************
+ * JoyReleaseCapture [WINMM.33]
+ */
+MMRESULT32 WINAPI joyReleaseCapture32(UINT32 wID)
+{
+ return joyReleaseCapture16(wID);
+}
+
+/**************************************************************************
* JoyReleaseCapture [MMSYSTEM.105]
*/
-WORD WINAPI JoyReleaseCapture(WORD wID)
+MMRESULT16 WINAPI joyReleaseCapture16(UINT16 wID)
{
dprintf_mmsys(stderr, "JoyReleaseCapture(%04X);\n", wID);
- JoyCaptured = FALSE;
- JoyCloseDriver(wID);
+ joyCaptured = FALSE;
+ joyCloseDriver(wID);
joy_dev[wID] = -1;
CaptureWnd[wID] = 0;
return JOYERR_NOERROR;
@@ -208,15 +336,23 @@
/**************************************************************************
* JoySetCapture [MMSYSTEM.106]
*/
-WORD WINAPI JoySetCapture(HWND16 hWnd, WORD wID, WORD wPeriod, BOOL16 bChanged)
+MMRESULT32 WINAPI joySetCapture32(HWND32 hWnd,UINT32 wID,UINT32 wPeriod,BOOL32 bChanged)
+{
+ return joySetCapture16(hWnd,wID,wPeriod,bChanged);
+}
+
+/**************************************************************************
+ * JoySetCapture [MMSYSTEM.106]
+ */
+MMRESULT16 WINAPI joySetCapture16(HWND16 hWnd,UINT16 wID,UINT16 wPeriod,BOOL16 bChanged)
{
dprintf_mmsys(stderr, "JoySetCapture(%04X, %04X, %d, %d);\n",
hWnd, wID, wPeriod, bChanged);
if (!CaptureWnd[wID]) {
- if (JoyOpenDriver(wID) == FALSE) return MMSYSERR_NODRIVER;
- JoyCaptured = TRUE;
+ if (joyOpenDriver(wID) == FALSE) return MMSYSERR_NODRIVER;
+ joyCaptured = TRUE;
CaptureWnd[wID] = hWnd;
return JOYERR_NOERROR;
}
@@ -225,9 +361,16 @@
}
/**************************************************************************
+ * JoySetThreshold [WINMM.35]
+ */
+MMRESULT32 WINAPI joySetThreshold32(UINT32 wID, UINT32 wThreshold)
+{
+ return joySetThreshold16(wID,wThreshold);
+}
+/**************************************************************************
* JoySetThreshold [MMSYSTEM.107]
*/
-WORD WINAPI JoySetThreshold(WORD wID, WORD wThreshold)
+MMRESULT16 WINAPI joySetThreshold16(UINT16 wID, UINT16 wThreshold)
{
dprintf_mmsys(stderr, "JoySetThreshold(%04X, %d);\n", wID, wThreshold);
@@ -239,8 +382,8 @@
/**************************************************************************
* JoySetCalibration [MMSYSTEM.109]
*/
-WORD WINAPI JoySetCalibration(WORD wID)
+MMRESULT16 WINAPI joySetCalibration16(UINT16 wID)
{
- fprintf(stderr, "EMPTY STUB !!! JoySetCalibration(%04X);\n", wID);
+ fprintf(stderr, "EMPTY STUB !!! joySetCalibration(%04X);\n", wID);
return JOYERR_NOCANDO;
}
diff --git a/multimedia/mcianim.c b/multimedia/mcianim.c
index 7b44e39..39fcdf1 100644
--- a/multimedia/mcianim.c
+++ b/multimedia/mcianim.c
@@ -605,7 +605,7 @@
* ANIM_DriverProc [sample driver]
*/
LONG ANIM_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
#if defined(linux) || defined(__FreeBSD__)
switch(wMsg) {
diff --git a/multimedia/mcicda.c b/multimedia/mcicda.c
index d92d840..65a3375 100644
--- a/multimedia/mcicda.c
+++ b/multimedia/mcicda.c
@@ -1026,7 +1026,7 @@
* CDAUDIO_DriverProc [sample driver]
*/
LONG CDAUDIO_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
#if defined(linux) || defined(__FreeBSD__)
switch(wMsg) {
diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c
index 298bd5c..88cf60a 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -23,20 +23,17 @@
#include "user.h"
#include "driver.h"
#include "mmsystem.h"
+#include "callback.h"
#include "stddebug.h"
#include "debug.h"
#include "xmalloc.h"
-extern MCI_OPEN_DRIVER_PARMS mciDrv[MAXMCIDRIVERS];
-
-/* FIXME: I need to remember the aliasname of a spec. driver.
- * and this is the easiest way. *sigh*
- */
-extern MCI_OPEN_PARMS16 mciOpenDrv[MAXMCIDRIVERS];
+extern struct LINUX_MCIDRIVER mciDrv[MAXMCIDRIVERS];
#define GetDrv(wDevID) (&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
-#define GetOpenDrv(wDevID) (&mciOpenDrv[MMSYSTEM_DevIDToIndex(wDevID)])
+#define GetOpenDrv(wDevID) (&(GetDrv(wDevID)->mop))
+
extern int MMSYSTEM_DevIDToIndex(UINT16 wDevID);
extern UINT16 MMSYSTEM_FirstDevID(void);
extern UINT16 MMSYSTEM_NextDevID(UINT16 wDevID);
@@ -80,24 +77,25 @@
#define _MCI_CALL_DRIVER(cmd,params) \
switch(uDevTyp) {\
case MCI_DEVTYPE_CD_AUDIO:\
- res=CDAUDIO_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags, (DWORD)(params));\
+ res=CDAUDIO_DriverProc(GetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags, (DWORD)(params));\
break;\
case MCI_DEVTYPE_WAVEFORM_AUDIO:\
- res=WAVE_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
+ res=WAVE_DriverProc(GetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
break;\
case MCI_DEVTYPE_SEQUENCER:\
- res=MIDI_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
+ res=MIDI_DriverProc(GetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
break;\
case MCI_DEVTYPE_ANIMATION:\
- res=ANIM_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
+ res=ANIM_DriverProc(GetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
break;\
case MCI_DEVTYPE_DIGITAL_VIDEO:\
dprintf_mci(stddeb,"_MCI_CALL_DRIVER //No DIGITAL_VIDEO yet !\n");\
res=MCIERR_DEVICE_NOT_INSTALLED;\
break;\
default:\
- dprintf_mci(stddeb,"_MCI_CALL_DRIVER //Invalid Device Name '%s' !\n",dev);\
- res=MCIERR_INVALID_DEVICE_NAME;\
+ /*res = Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,GetDrv(wDevID)->modp.wDeviceID,GetDrv(wDevID)->hdrv,cmd,dwFlags,(DWORD)(params));\
+ break;*/\
+ res = MCIERR_DEVICE_NOT_INSTALLED;\
break;\
}
/* print a DWORD in the specified timeformat */
@@ -335,17 +333,17 @@
return MCIERR_INVALID_DEVICE_NAME;
}
wDevID=MMSYSTEM_FirstDevID();
- while(GetDrv(wDevID)->wType) {
+ while(GetDrv(wDevID)->modp.wType) {
wDevID = MMSYSTEM_NextDevID(wDevID);
if (!MMSYSTEM_DevIDValid(wDevID)) {
- dprintf_mci(stddeb, __FILE__":MCISTR_Open:MAXMCIDRIVERS reached!\n");
+ dprintf_mci(stddeb, __FILE__":MCISTR_Open:MAXMCIDRIVERS reached (%x) !\n", wDevID);
SEGPTR_FREE(PTR_SEG_TO_LIN(pU->openParams.lpstrElementName));
SEGPTR_FREE(pU);
return MCIERR_INTERNAL;
}
}
- GetDrv(wDevID)->wType = uDevTyp;
- GetDrv(wDevID)->wDeviceID = 0; /* FIXME? for multiple devices */
+ GetDrv(wDevID)->modp.wType = uDevTyp;
+ GetDrv(wDevID)->modp.wDeviceID = 0; /* FIXME? for multiple devices */
pU->openParams.dwCallback = hwndCallback ;
pU->openParams.wDeviceID = wDevID;
pU->ovlyopenParams.dwStyle = 0;
@@ -2190,7 +2188,7 @@
return MCIERR_INVALID_DEVICE_NAME;
}
}
- uDevTyp=GetDrv(wDevID)->wType;
+ uDevTyp=GetDrv(wDevID)->modp.wType;
}
for (i=0;MCISTR_cmdtable[i].cmd!=NULL;i++) {
diff --git a/multimedia/midi.c b/multimedia/midi.c
index 471a4d1..f38d5dd 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -1347,7 +1347,7 @@
* MIDI_DriverProc [sample driver]
*/
LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg,
- DWORD dwParam1, DWORD dwParam2)
+ DWORD dwParam1, DWORD dwParam2)
{
#if defined(linux) || defined(__FreeBSD__)
switch(wMsg) {
diff --git a/multimedia/mixer.c b/multimedia/mixer.c
index 14ec17a..89f9394 100644
--- a/multimedia/mixer.c
+++ b/multimedia/mixer.c
@@ -39,7 +39,6 @@
{
#ifdef linux
int mixer,mask;
- struct mixer_info mi;
dprintf_mmaux(stddeb,"MIX_GetDevCaps(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
@@ -47,16 +46,10 @@
dprintf_mmaux(stddeb,"MIX_GetDevCaps // mixer device not available !\n");
return MMSYSERR_NOTENABLED;
}
- if (ioctl(mixer, SOUND_MIXER_INFO, &mi) == -1) {
- close(mixer);
- perror("ioctl mixer SOUND_MIXER_INFO");
- return MMSYSERR_NOTENABLED;
- }
- fprintf(stderr,"SOUND_MIXER_INFO returns { \"%s\",\"%s\" }\n",mi.id,mi.name);
lpCaps->wMid = 0xAA;
lpCaps->wPid = 0x55;
lpCaps->vDriverVersion = 0x0100;
- strcpy(lpCaps->szPname,mi.name);
+ strcpy(lpCaps->szPname,"WINE Generic Mixer");
if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
close(mixer);
perror("ioctl mixer SOUND_MIXER_DEVMASK");
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 159e78f..ad9d211 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -23,6 +23,7 @@
#include "file.h"
#include "mmsystem.h"
#include "stddebug.h"
+/* #define DEBUG_MMSYS */
#include "debug.h"
#include "xmalloc.h"
#include "callback.h"
@@ -31,11 +32,7 @@
static int InstalledListLen;
static LPSTR lpInstallNames = NULL;
-MCI_OPEN_DRIVER_PARMS mciDrv[MAXMCIDRIVERS];
-/* struct below is to remember alias/devicenames for mcistring.c
- * FIXME: should use some internal struct ...
- */
-MCI_OPEN_PARMS16 mciOpenDrv[MAXMCIDRIVERS];
+struct LINUX_MCIDRIVER mciDrv[MAXMCIDRIVERS];
UINT16 midiGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
static UINT16 waveGetErrorText(UINT16 uError, LPSTR lpText, UINT16 uSize);
@@ -53,7 +50,7 @@
#define GetDrv(wDevID) (&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
-#define GetOpenDrv(wDevID) (&mciOpenDrv[MMSYSTEM_DevIDToIndex(wDevID)])
+#define GetOpenDrv(wDevID) (&(GetDrv(wDevID)->mop))
/* The wDevID's returned by wine were originally in the range
* 0 - (MAXMCIDRIVERS - 1) and used directly as array indices.
@@ -122,25 +119,22 @@
}
/**************************************************************************
-* PlaySoundA [WINMM.1]
-*/
+ * PlaySoundA [WINMM.1]
+ */
BOOL32 WINAPI PlaySound32A(LPCSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
{
- dprintf_mmsys(stddeb, "PlaySoundA: pszSound='%s' hmod=%04X fdwSound=%08lX\n",
+ dprintf_mmsys(stddeb, "PlaySoundA: pszSound='%p' hmod=%04X fdwSound=%08lX\n",
pszSound, hmod, fdwSound);
if(hmod != 0 || !(fdwSound & SND_FILENAME)) {
fprintf(stderr, "PlaySoundA: only disk sound files are supported\n");
return FALSE;
- } else {
- BOOL16 bSound;
- bSound = sndPlaySound(pszSound, (UINT16) fdwSound);
- return (BOOL32) bSound;
- }
+ } else
+ return sndPlaySound(pszSound, (UINT16) fdwSound);
}
/**************************************************************************
-* PlaySoundW [WINMM.18]
-*/
+ * PlaySoundW [WINMM.18]
+ */
BOOL32 WINAPI PlaySound32W(LPCWSTR pszSound, HMODULE32 hmod, DWORD fdwSound)
{
LPSTR pszSoundA = HEAP_strdupWtoA(GetProcessHeap(),0,pszSound);
@@ -537,7 +531,7 @@
/**************************************************************************
* mixerGetLineControlsA [WINMM.104]
*/
-UINT32 mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWORD fdwControls) {
+UINT32 WINAPI mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWORD fdwControls) {
fprintf(stderr,"mixerGetLineControlsA(%04x,%p,%08lx),stub!\n",
hmix,lpmlc,fdwControls
);
@@ -547,7 +541,7 @@
/**************************************************************************
* mixerGetLineControlsW [WINMM.105]
*/
-UINT32 mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWORD fdwControls) {
+UINT32 WINAPI mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWORD fdwControls) {
fprintf(stderr,"mixerGetLineControlsA(%04x,%p,%08lx),stub!\n",
hmix,lpmlc,fdwControls
);
@@ -557,7 +551,7 @@
/**************************************************************************
* mixerGetLineControls [MMSYSTEM.807]
*/
-UINT16 mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD fdwControls) {
+UINT16 WINAPI mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD fdwControls) {
fprintf(stderr,"mixerGetLineControls(%04x,%p,%08lx),stub!\n",
hmix,lpmlc,fdwControls
);
@@ -567,7 +561,7 @@
/**************************************************************************
* mixerGetLineInfoA [WINMM.106]
*/
-UINT32 mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo) {
+UINT32 WINAPI mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo) {
MIXERLINE16 ml16;
UINT32 ret;
@@ -599,7 +593,7 @@
/**************************************************************************
* mixerGetLineInfoW [WINMM.107]
*/
-UINT32 mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo) {
+UINT32 WINAPI mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo) {
MIXERLINE16 ml16;
UINT32 ret;
@@ -631,7 +625,7 @@
/**************************************************************************
* mixerGetLineInfo [MMSYSTEM.805]
*/
-UINT16 mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo) {
+UINT16 WINAPI mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo) {
UINT16 devid = _get_mixerID_from_handle(hmix,fdwInfo);
fprintf(stderr,"mixerGetLineInfo16(%04x,%p[line %08lx],%08lx)\n",
@@ -643,7 +637,7 @@
/**************************************************************************
* mixerSetControlDetails [WINMM.111]
*/
-UINT32 mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
+UINT32 WINAPI mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,DWORD fdwDetails) {
fprintf(stderr,"mixerSetControlDetails32(%04x,%p,%08lx),stub!\n",
hmix,lpmcd,fdwDetails
);
@@ -653,7 +647,7 @@
/**************************************************************************
* mixerSetControlDetails [MMSYSTEM.809]
*/
-UINT16 mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
+UINT16 WINAPI mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,DWORD fdwDetails) {
fprintf(stderr,"mixerSetControlDetails16(%04x,%p,%08lx),stub!\n",
hmix,lpmcd,fdwDetails
);
@@ -663,7 +657,7 @@
/**************************************************************************
* mixerMessage [WINMM.109]
*/
-UINT32 mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2) {
+UINT32 WINAPI mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2) {
LPMIXEROPENDESC lpmod;
UINT16 uDeviceID;
@@ -679,7 +673,7 @@
/**************************************************************************
* mixerMessage [MMSYSTEM.804]
*/
-UINT16 mixerMessage16(HMIXER16 hmix,UINT16 uMsg,DWORD dwParam1,DWORD dwParam2) {
+UINT16 WINAPI mixerMessage16(HMIXER16 hmix,UINT16 uMsg,DWORD dwParam1,DWORD dwParam2) {
LPMIXEROPENDESC lpmod;
UINT16 uDeviceID;
@@ -1164,7 +1158,7 @@
dprintf_mmsys(stddeb, "mciOpen(%08lX, %p (%p))\n", dwParam, lp16Parms, lpParms);
if (lp16Parms == NULL) return MCIERR_INTERNAL;
- while(GetDrv(wDevID)->wType != 0) {
+ while(GetDrv(wDevID)->modp.wType != 0) {
wDevID = MMSYSTEM_NextDevID(wDevID);
if (!MMSYSTEM_DevIDValid(wDevID)) {
dprintf_mmsys(stddeb, "MCI_OPEN // MAXMCIDRIVERS reached !\n");
@@ -1204,8 +1198,21 @@
if (strcmp(str,"*") == 0) {
dprintf_mmsys(stddeb,"No [mci extensions] entry for %s found.\n",t);
return MCIERR_EXTENSION_NOT_FOUND;
+#if testing16
} else {
- dprintf_mmsys(stddeb,"[mci extensions] entry %s for %s not supported.\n",str,t);
+ HDRVR16 hdrv = OpenDriver(str,"mci",NULL);
+ if (hdrv) {
+ HMODULE16 hmod;
+
+ hmod = GetDriverModuleHandle(hdrv);
+ GetDrv(wDevID)->hdrv = hdrv;
+ GetDrv(wDevID)->driverproc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
+ uDevTyp = MCI_DEVTYPE_OTHER;
+ } else {
+ dprintf_mmsys(stddeb,"[mci extensions] entry %s for %s not supported.\n",str,t);
+ return MCIERR_DEVICE_NOT_INSTALLED;
+ }
+#endif
}
} else
return MCIERR_EXTENSION_NOT_FOUND;
@@ -1245,11 +1252,26 @@
} else
if (strcmp(str, "AVIVIDEO") == 0) {
uDevTyp = MCI_DEVTYPE_DIGITAL_VIDEO;
+ } else {
+#if testing16
+ HDRVR16 hdrv;
+ fprintf(stderr,"trying to load driver...\n");
+ hdrv = OpenDriver(str,"mci",NULL);
+ if (hdrv) {
+ HMODULE16 hmod;
+
+ hmod = GetDriverModuleHandle(hdrv);
+ GetDrv(wDevID)->hdrv = hdrv;
+ GetDrv(wDevID)->driverproc = GetProcAddress16(hmod,SEGPTR_GET(SEGPTR_STRDUP("DRIVERPROC")));
+ uDevTyp = MCI_DEVTYPE_OTHER;
+ } else
+#endif
+ return MCIERR_DEVICE_NOT_INSTALLED;
}
}
}
- GetDrv(wDevID)->wType = uDevTyp;
- GetDrv(wDevID)->wDeviceID = 0; /* FIXME? for multiple devices */
+ GetDrv(wDevID)->modp.wType = uDevTyp;
+ GetDrv(wDevID)->modp.wDeviceID = 0; /* FIXME? for multiple devices */
lpParms->wDeviceID = wDevID;
dprintf_mmsys(stddeb, "MCI_OPEN // mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n",
wDevID, uDevTyp, lpParms->wDeviceID);
@@ -1263,7 +1285,7 @@
dwret = WAVE_DriverProc( 0, 0, MCI_OPEN_DRIVER,
dwParam, (DWORD)lp16Parms);
break;
- case MCI_DEVTYPE_SEQUENCER:
+ case MCI_DEVTYPE_SEQUENCER:
dwret = MIDI_DriverProc( 0, 0, MCI_OPEN_DRIVER,
dwParam, (DWORD)lp16Parms);
break;
@@ -1275,7 +1297,10 @@
dprintf_mmsys(stddeb, "MCI_OPEN // No DIGITAL_VIDEO yet !\n");
return MCIERR_DEVICE_NOT_INSTALLED;
default:
+#if testing16
+ dwret = Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,0,GetDrv(wDevID)->hdrv,MCI_OPEN_DRIVER,dwParam,(DWORD)lp16Parms);
dprintf_mmsys(stddeb, "MCI_OPEN // Invalid Device Name '%08lx' !\n", (DWORD)lpParms->lpstrDeviceType);
+#endif
return MCIERR_INVALID_DEVICE_NAME;
}
@@ -1289,40 +1314,56 @@
return dwret;
}
+/**************************************************************************
+ * mciGetDriverData [MMSYSTEM.708]
+ */
+DWORD WINAPI mciGetDriverData16(HDRVR16 hdrv) {
+ fprintf(stderr,"mciGetDriverData(%04x),stub!\n",hdrv);
+ return 0x42;
+}
/**************************************************************************
-* mciClose [internal]
-*/
+ * mciSetDriverData [MMSYSTEM.707]
+ */
+DWORD WINAPI mciSetDriverData16(HDRVR16 hdrv,DWORD data) {
+ fprintf(stderr,"mciSetDriverData(%04x,%08lx),stub!\n",hdrv,data);
+ return 0;
+}
+
+/**************************************************************************
+ * mciClose [internal]
+ */
DWORD mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
{
DWORD dwRet = MCIERR_INTERNAL;
dprintf_mmsys(stddeb, "mciClose(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
- switch(GetDrv(wDevID)->wType) {
- case MCI_DEVTYPE_CD_AUDIO:
- dwRet = CDAUDIO_DriverProc(GetDrv(wDevID)->wDeviceID,0,
- MCI_CLOSE, dwParam, (DWORD)lpParms);
- break;
- case MCI_DEVTYPE_WAVEFORM_AUDIO:
- dwRet = WAVE_DriverProc(GetDrv(wDevID)->wDeviceID, 0,
- MCI_CLOSE, dwParam,
- (DWORD)lpParms);
- break;
- case MCI_DEVTYPE_SEQUENCER:
- dwRet = MIDI_DriverProc(GetDrv(wDevID)->wDeviceID, 0,
- MCI_CLOSE, dwParam,
- (DWORD)lpParms);
- break;
- case MCI_DEVTYPE_ANIMATION:
- dwRet = ANIM_DriverProc(GetDrv(wDevID)->wDeviceID, 0,
- MCI_CLOSE, dwParam,
- (DWORD)lpParms);
- break;
- default:
- dprintf_mmsys(stddeb, "mciClose() // unknown device type=%04X !\n", GetDrv(wDevID)->wType);
- dwRet = MCIERR_DEVICE_NOT_INSTALLED;
- }
- GetDrv(wDevID)->wType = 0;
+ switch(GetDrv(wDevID)->modp.wType) {
+ case MCI_DEVTYPE_CD_AUDIO:
+ dwRet = CDAUDIO_DriverProc(GetDrv(wDevID)->modp.wDeviceID,0,
+ MCI_CLOSE, dwParam, (DWORD)lpParms);
+ break;
+ case MCI_DEVTYPE_WAVEFORM_AUDIO:
+ dwRet = WAVE_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0,
+ MCI_CLOSE, dwParam,
+ (DWORD)lpParms);
+ break;
+ case MCI_DEVTYPE_SEQUENCER:
+ dwRet = MIDI_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0,
+ MCI_CLOSE, dwParam,
+ (DWORD)lpParms);
+ break;
+ /*
+ case MCI_DEVTYPE_ANIMATION:
+ dwRet = ANIM_DriverProc(GetDrv(wDevID)->modp.wDeviceID, 0,
+ MCI_CLOSE, dwParam,
+ (DWORD)lpParms);
+ break;
+ */
+ default:
+ dwRet = Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,GetDrv(wDevID)->modp.wDeviceID,GetDrv(wDevID)->hdrv,MCI_CLOSE,dwParam,(DWORD)lpParms);
+ }
+ GetDrv(wDevID)->modp.wType = 0;
if (dwParam&MCI_NOTIFY)
mciDriverNotify(lpParms->dwCallback,wDevID,
@@ -1334,8 +1375,8 @@
/**************************************************************************
-* mciSysinfo [internal]
-*/
+ * mciSysinfo [internal]
+ */
DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS16 lpParms)
{
int len;
@@ -1382,6 +1423,63 @@
}
/**************************************************************************
+ * mciLoadCommandResource
+ */
+UINT16 mciLoadCommandResource16(HANDLE16 hinst,LPCSTR resname,UINT16 type)
+{
+ char buf[200];
+ OFSTRUCT ofs;
+ HANDLE16 xhinst;
+ HRSRC16 hrsrc;
+ HGLOBAL16 hmem;
+ LPSTR segstr;
+ SEGPTR xmem;
+ LPBYTE lmem;
+ static mcidevtype = 0;
+
+ fprintf(stderr,"mciLoadCommandResource16(%04x,%s,%d),stub!\n",
+ hinst,resname,type
+ );
+ if (!lstrcmpi32A(resname,"core")) {
+ fprintf(stderr,"mciLoadCommandResource(...,\"core\",...), have to use internal tables... (not there yet)\n");
+ return 0;
+ }
+ /* if file exists "resname.mci", then load resource "resname" from it
+ * otherwise directly from driver
+ */
+ strcpy(buf,resname);
+ strcat(buf,".mci");
+ if (OpenFile32(buf,&ofs,OF_EXIST)!=HFILE_ERROR32) {
+ xhinst = LoadLibrary16(buf);
+ if (xhinst >32)
+ hinst = xhinst;
+ } /* else use passed hinst */
+ segstr = SEGPTR_STRDUP(resname);
+ hrsrc = FindResource16(hinst,SEGPTR_GET(segstr),type);
+ SEGPTR_FREE(segstr);
+ if (!hrsrc) {
+ fprintf(stderr,"mciLoadCommandResource:no special commandlist found in resource\n");
+ return MCI_NO_COMMAND_TABLE;
+ }
+ hmem = LoadResource16(hinst,hrsrc);
+ if (!hmem) {
+ fprintf(stderr,"mciLoadCommandResource:couldn't load resource??\n");
+ return MCI_NO_COMMAND_TABLE;
+ }
+ xmem = WIN16_LockResource16(hmem);
+ if (!xmem) {
+ fprintf(stderr,"mciLoadCommandResource:couldn't lock resource??\n");
+ FreeResource16(hmem);
+ return MCI_NO_COMMAND_TABLE;
+ }
+ lmem = PTR_SEG_TO_LIN(xmem);
+ fprintf(stderr,"first resource entry is %s\n",(char*)lmem);
+ /* parse resource, register stuff, return unique id */
+ return ++mcidevtype;
+}
+
+
+/**************************************************************************
* mciSound [internal]
* not used anymore ??
@@ -1441,8 +1539,19 @@
}
/**************************************************************************
-* mciSendCommand [MMSYSTEM.701]
-*/
+ * mciSendCommandA [WINMM.49]
+ */
+DWORD WINAPI mciSendCommand32A(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1,
+ DWORD dwParam2)
+{
+ fprintf(stderr,"mciSendCommand32A(%08x,%08x,%08lx,%08lx),stub!\n",
+ wDevID,wMsg,dwParam1,dwParam2
+ );
+ return 0; /* ok */
+}
+/**************************************************************************
+ * mciSendCommand [MMSYSTEM.701]
+ */
DWORD WINAPI mciSendCommand(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1,
DWORD dwParam2)
{
@@ -1460,24 +1569,28 @@
return mciSysInfo( dwParam1,
(LPMCI_SYSINFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
default:
- switch(GetDrv(wDevID)->wType)
+ switch(GetDrv(wDevID)->modp.wType)
{
case MCI_DEVTYPE_CD_AUDIO:
- return CDAUDIO_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv,
+ return CDAUDIO_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv,
wMsg, dwParam1, dwParam2);
case MCI_DEVTYPE_WAVEFORM_AUDIO:
- return WAVE_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv,
+ return WAVE_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv,
wMsg, dwParam1, dwParam2);
case MCI_DEVTYPE_SEQUENCER:
- return MIDI_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv,
+ return MIDI_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv,
wMsg, dwParam1, dwParam2);
+ /*
case MCI_DEVTYPE_ANIMATION:
- return ANIM_DriverProc(GetDrv(wDevID)->wDeviceID, hDrv,
+ return ANIM_DriverProc(GetDrv(wDevID)->modp.wDeviceID, hDrv,
wMsg, dwParam1, dwParam2);
+ */
default:
+ return Callbacks->CallDriverProc(GetDrv(wDevID)->driverproc,GetDrv(wDevID)->modp.wDeviceID,GetDrv(wDevID)->hdrv,MCI_CLOSE,dwParam1,dwParam2);
+
dprintf_mci(stddeb,
"mciSendCommand() // unknown device type=%04X !\n",
- GetDrv(wDevID)->wType);
+ GetDrv(wDevID)->modp.wType);
}
}
return MMSYSERR_INVALPARAM;
@@ -1498,7 +1611,7 @@
return 0;
wDevID = MMSYSTEM_FirstDevID();
- while(MMSYSTEM_DevIDValid(wDevID) && GetDrv(wDevID)->wType) {
+ while(MMSYSTEM_DevIDValid(wDevID) && GetDrv(wDevID)->modp.wType) {
if (GetOpenDrv(wDevID)->lpstrDeviceType &&
strcmp(PTR_SEG_TO_LIN(GetOpenDrv(wDevID)->lpstrDeviceType), lpstrName) == 0)
return wDevID;
@@ -3941,10 +4054,63 @@
/**************************************************************************
-* DrvDefDriverProc [MMSYSTEM.1104]
-*/
+ * DrvDefDriverProc [MMSYSTEM.1104]
+ */
LRESULT WINAPI DrvDefDriverProc(DWORD dwDriverID, HDRVR16 hDriv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
return DefDriverProc(dwDriverID, hDriv, wMsg, dwParam1, dwParam2);
}
+
+/**************************************************************************
+ * mmThreadCreate [MMSYSTEM.1120]
+ */
+LRESULT WINAPI mmThreadCreate16(LPVOID x1, LPWORD x2, DWORD x3, DWORD x4) {
+ fprintf(stderr,"mmThreadCreate16(%p,%p,%08lx,%08lx),stub!\n",
+ x1,x2,x3,x4
+ );
+ *x2 = 0xbabe;
+ return 0;
+}
+
+/**************************************************************************
+ * mmThreadGetTask [MMSYSTEM.1125]
+ */
+LRESULT WINAPI mmThreadGetTask16(WORD hnd) {
+ fprintf(stderr,"mmThreadGetTask16(%04x),stub!\n",hnd);
+ return GetCurrentTask();
+}
+
+/**************************************************************************
+ * mmThreadSignal [MMSYSTEM.1121]
+ */
+LRESULT WINAPI mmThreadSignal16(WORD hnd) {
+ fprintf(stderr,"mmThreadSignal16(%04x), stub!\n",hnd);
+ return 0;
+}
+
+/**************************************************************************
+ * mmTaskCreate [MMSYSTEM.900]
+ */
+LRESULT WINAPI mmTaskCreate16(LPWORD lphnd,DWORD x1,DWORD x2) {
+ fprintf(stderr,"mmTaskCreate16(%p,%08lx,%08lx),stub!\n",lphnd,x1,x2);
+ *lphnd = 0xcafe;
+ return 0;
+}
+
+/**************************************************************************
+ * mmTaskSignal [MMSYSTEM.903]
+ */
+LRESULT WINAPI mmTaskSignal16(HTASK16 ht) {
+ fprintf(stderr,"mmTaskSignal(%04x),stub!\n",ht);
+ return PostAppMessage16(ht,0x400,0,0);
+}
+
+/**************************************************************************
+ * mciDriverYield [MMSYSTEM.710]
+ */
+LRESULT WINAPI mciDriverYield16(HANDLE16 hnd) {
+ fprintf(stderr,"mciDriverYield16(%04x),stub!\n",hnd);
+ return 0;
+}
+
diff --git a/multimedia/time.c b/multimedia/time.c
index c631ce0..7a4eb6d 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -24,14 +24,15 @@
static MMTIME16 mmSysTimeSMPTE;
typedef struct tagTIMERENTRY {
- WORD wDelay;
- WORD wResol;
+ UINT32 wDelay;
+ UINT32 wResol;
FARPROC16 lpFunc;
- HINSTANCE16 hInstance;
- DWORD dwUser;
- WORD wFlags;
- WORD wTimerID;
- WORD wCurTime;
+ HINSTANCE32 hInstance;
+ DWORD dwUser;
+ UINT32 wFlags;
+ UINT32 wTimerID;
+ UINT32 wCurTime;
+ UINT32 iswin32;
struct tagTIMERENTRY *Next;
} TIMERENTRY, *LPTIMERENTRY;
@@ -58,6 +59,7 @@
lpTimer->wCurTime--;
if (lpTimer->wCurTime == 0) {
lpTimer->wCurTime = lpTimer->wDelay;
+
if (lpTimer->lpFunc != (FARPROC16) NULL) {
dprintf_mmtime(stddeb, "MMSysTimeCallback // before CallBack16 !\n");
dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
@@ -77,15 +79,19 @@
* PostMessage), and must reside in DLL (therefore uses stack of active application). So I
* guess current implementation via SetTimer has to be improved upon.
*/
-
- Callbacks->CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID,
- 0, lpTimer->dwUser, 0, 0 );
+ if (lpTimer->iswin32)
+ lpTimer->lpFunc(lpTimer->wTimerID,0,lpTimer->dwUser,0,0);
+ else
+ Callbacks->CallTimeFuncProc(lpTimer->lpFunc,
+ lpTimer->wTimerID,0,
+ lpTimer->dwUser,0,0
+ );
dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
fflush(stdout);
}
if (lpTimer->wFlags & TIME_ONESHOT)
- timeKillEvent(lpTimer->wTimerID);
+ timeKillEvent32(lpTimer->wTimerID);
}
lpTimer = lpTimer->Next;
}
@@ -112,11 +118,24 @@
}
/**************************************************************************
+ * timeGetSystemTime [WINMM.140]
+ */
+MMRESULT32 WINAPI timeGetSystemTime32(LPMMTIME32 lpTime, UINT32 wSize)
+{
+ dprintf_mmsys(stddeb, "timeGetSystemTime32(%p, %u);\n", lpTime, wSize);
+ if (!mmTimeStarted)
+ StartMMTime();
+ lpTime->wType = TIME_MS;
+ lpTime->u.ms = mmSysTimeMS.u.ms;
+ return 0;
+}
+
+/**************************************************************************
* timeGetSystemTime [MMSYSTEM.601]
*/
-WORD WINAPI timeGetSystemTime(LPMMTIME16 lpTime, WORD wSize)
+MMRESULT16 WINAPI timeGetSystemTime16(LPMMTIME16 lpTime, UINT16 wSize)
{
- dprintf_mmsys(stddeb, "timeGetSystemTime(%p, %u);\n", lpTime, wSize);
+ dprintf_mmsys(stddeb, "timeGetSystemTime16(%p, %u);\n", lpTime, wSize);
if (!mmTimeStarted)
StartMMTime();
lpTime->wType = TIME_MS;
@@ -127,8 +146,49 @@
/**************************************************************************
* timeSetEvent [MMSYSTEM.602]
*/
-WORD WINAPI timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc,
- DWORD dwUser, WORD wFlags)
+MMRESULT32 WINAPI timeSetEvent32(UINT32 wDelay,UINT32 wResol,
+ LPTIMECALLBACK32 lpFunc,DWORD dwUser,
+ UINT32 wFlags)
+{
+ WORD wNewID = 0;
+ LPTIMERENTRY lpNewTimer;
+ LPTIMERENTRY lpTimer = lpTimerList;
+
+ dprintf_mmtime(stddeb, "timeSetEvent32(%u, %u, %p, %08lX, %04X);\n",
+ wDelay, wResol, lpFunc, dwUser, wFlags);
+ if (!mmTimeStarted)
+ StartMMTime();
+ lpNewTimer = (LPTIMERENTRY)xmalloc(sizeof(TIMERENTRY));
+ if (lpNewTimer == NULL)
+ return 0;
+ while (lpTimer != NULL) {
+ wNewID = MAX(wNewID, lpTimer->wTimerID);
+ lpTimer = lpTimer->Next;
+ }
+
+ lpNewTimer->Next = lpTimerList;
+ lpTimerList = lpNewTimer;
+ lpNewTimer->wTimerID = wNewID + 1;
+ lpNewTimer->wCurTime = wDelay;
+ lpNewTimer->wDelay = wDelay;
+ lpNewTimer->wResol = wResol;
+ lpNewTimer->lpFunc = (FARPROC16) lpFunc;
+ lpNewTimer->iswin32 = 1;
+ lpNewTimer->hInstance = GetTaskDS();
+ dprintf_mmtime(stddeb, "timeSetEvent // hInstance=%04X !\n", lpNewTimer->hInstance);
+ dprintf_mmtime(stddeb, "timeSetEvent // lpFunc=%p !\n",
+ lpFunc);
+ lpNewTimer->dwUser = dwUser;
+ lpNewTimer->wFlags = wFlags;
+ return lpNewTimer->wTimerID;
+}
+
+/**************************************************************************
+ * timeSetEvent [MMSYSTEM.602]
+ */
+MMRESULT16 WINAPI timeSetEvent16(UINT16 wDelay, UINT16 wResol,
+ LPTIMECALLBACK16 lpFunc,DWORD dwUser,
+ UINT16 wFlags)
{
WORD wNewID = 0;
LPTIMERENTRY lpNewTimer;
@@ -152,6 +212,7 @@
lpNewTimer->wDelay = wDelay;
lpNewTimer->wResol = wResol;
lpNewTimer->lpFunc = (FARPROC16) lpFunc;
+ lpNewTimer->iswin32 = 0;
lpNewTimer->hInstance = GetTaskDS();
dprintf_mmtime(stddeb, "timeSetEvent // hInstance=%04X !\n", lpNewTimer->hInstance);
dprintf_mmtime(stddeb, "timeSetEvent // PTR_SEG_TO_LIN(lpFunc)=%p !\n",
@@ -162,9 +223,9 @@
}
/**************************************************************************
- * timeKillEvent [MMSYSTEM.603]
+ * timeKillEvent [WINMM.142]
*/
-WORD WINAPI timeKillEvent(WORD wID)
+MMRESULT32 WINAPI timeKillEvent32(UINT32 wID)
{
LPTIMERENTRY xlptimer,*lpTimer = &lpTimerList;
while (*lpTimer) {
@@ -180,9 +241,17 @@
}
/**************************************************************************
- * timeGetDevCaps [MMSYSTEM.604]
+ * timeKillEvent [MMSYSTEM.603]
*/
-WORD WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize)
+MMRESULT16 WINAPI timeKillEvent16(UINT16 wID)
+{
+ return timeKillEvent32(wID);
+}
+
+/**************************************************************************
+ * timeGetDevCaps [WINMM.139]
+ */
+MMRESULT32 WINAPI timeGetDevCaps32(LPTIMECAPS32 lpCaps,UINT32 wSize)
{
dprintf_mmtime(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
if (!mmTimeStarted)
@@ -193,9 +262,34 @@
}
/**************************************************************************
+ * timeGetDevCaps [MMSYSTEM.604]
+ */
+MMRESULT16 WINAPI timeGetDevCaps16(LPTIMECAPS16 lpCaps, UINT16 wSize)
+{
+ dprintf_mmtime(stddeb, "timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
+ if (!mmTimeStarted)
+ StartMMTime();
+ lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL;
+ lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL;
+ return 0;
+}
+
+/**************************************************************************
+ * timeBeginPeriod [WINMM.137]
+ */
+MMRESULT32 WINAPI timeBeginPeriod32(UINT32 wPeriod)
+{
+ dprintf_mmtime(stddeb, "timeBeginPeriod32(%u) !\n", wPeriod);
+ if (!mmTimeStarted)
+ StartMMTime();
+ if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
+ return TIMERR_NOCANDO;
+ return 0;
+}
+/**************************************************************************
* timeBeginPeriod [MMSYSTEM.605]
*/
-WORD WINAPI timeBeginPeriod(WORD wPeriod)
+MMRESULT16 WINAPI timeBeginPeriod16(UINT16 wPeriod)
{
dprintf_mmtime(stddeb, "timeBeginPeriod(%u) !\n", wPeriod);
if (!mmTimeStarted)
@@ -206,9 +300,9 @@
}
/**************************************************************************
- * timeEndPeriod [MMSYSTEM.606]
+ * timeEndPeriod [WINMM.138]
*/
-WORD WINAPI timeEndPeriod(WORD wPeriod)
+MMRESULT32 WINAPI timeEndPeriod32(UINT32 wPeriod)
{
dprintf_mmtime(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
@@ -217,13 +311,30 @@
}
/**************************************************************************
- * timeGetTime [MMSYSTEM.607]
+ * timeEndPeriod [MMSYSTEM.606]
+ */
+MMRESULT16 WINAPI timeEndPeriod16(UINT16 wPeriod)
+{
+ dprintf_mmtime(stddeb, "timeEndPeriod(%u) !\n", wPeriod);
+ if (wPeriod < MMSYSTIME_MININTERVAL || wPeriod > MMSYSTIME_MAXINTERVAL)
+ return TIMERR_NOCANDO;
+ return 0;
+}
+
+/**************************************************************************
+ * timeGetTime [MMSYSTEM.607][WINMM.141]
*/
DWORD WINAPI timeGetTime()
{
+ static DWORD lasttick=0;
+ DWORD newtick;
+
dprintf_mmtime(stddeb, "timeGetTime(); !\n");
if (!mmTimeStarted)
StartMMTime();
+ newtick = GetTickCount();
+ mmSysTimeMS.u.ms+=newtick-lasttick; /* FIXME: faked timer */
+ lasttick = newtick;
dprintf_mmtime(stddeb, "timeGetTime() // Time = %ld\n",mmSysTimeMS.u.ms);
return mmSysTimeMS.u.ms;
}
diff --git a/objects/bitmap.c b/objects/bitmap.c
index c6fbbe1..4092719 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -489,6 +489,29 @@
return height * bmp->bitmap.bmWidthBytes;
}
+HANDLE16 WINAPI LoadImage16( HINSTANCE16 hinst, LPCSTR name, UINT16 type,
+ INT16 desiredx, INT16 desiredy, UINT16 loadflags)
+{
+ if (HIWORD(name)) {
+ fprintf(stddeb,"LoadImage16(0x%04x,%s,%d,%d,%d,0x%08x)\n",
+ hinst,(char *)PTR_SEG_TO_LIN(name),type,desiredx,desiredy,loadflags
+ );
+ } else {
+ fprintf(stddeb,"LoadImage16(0x%04x,%p,%d,%d,%d,0x%08x)\n",
+ hinst,name,type,desiredx,desiredy,loadflags
+ );
+ }
+ switch (type) {
+ case IMAGE_BITMAP:
+ return LoadBitmap16(hinst,name);
+ case IMAGE_ICON:
+ return LoadIcon16(hinst,name);
+ case IMAGE_CURSOR:
+ return LoadCursor16(hinst,name);
+ }
+ return 0;
+
+}
/**********************************************************************
* LoadImageA (USER32.364)
* FIXME: implementation still lacks nearly all features, see LR_*
diff --git a/objects/brush.c b/objects/brush.c
index 5ef84fb..8f2eb83 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -236,6 +236,15 @@
return TRUE;
}
+/***********************************************************************
+ * FixBrushOrgEx (GDI32.102)
+ * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
+ */
+BOOL32 WINAPI FixBrushOrgEx( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 oldorg )
+{
+ return SetBrushOrgEx(hdc,x,y,oldorg);
+}
+
/***********************************************************************
* GetSysColorBrush16 (USER.281)
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index a9a7a06..d77a5f7 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -41,9 +41,9 @@
#include "stddebug.h"
#include "debug.h"
#include "task.h"
+#include "user.h"
extern UINT16 COLOR_GetSystemPaletteSize();
-extern HGLOBAL16 USER_CallDefaultRsrcHandler( HGLOBAL16, HMODULE16, HRSRC16 );
Cursor CURSORICON_XCursor = None; /* Current X cursor */
static HCURSOR32 hActiveCursor = 0; /* Active cursor */
@@ -440,6 +440,27 @@
}
+ /**********************************************************************
+ * CreateIconFromResource (USER32)
+ */
+HICON32 WINAPI CreateIconFromResource32( LPBYTE bits, UINT32 cbSize,
+ BOOL32 bIcon, DWORD dwVersion)
+/*FIXME: bon@elektron.ikp.physik.tu-darmstadt.de 971130: Test with weditres
+ showed only blank layout. Couldn't determine if this is a problem
+ with CreateIconFromResource32 or the application. The application
+ windows behaves strange (no redraw) before CreateIconFromResource32
+*/
+{
+ HICON32 ret;
+ ret = CreateIconFromResourceEx16( bits, cbSize, bIcon, dwVersion, 0,0,0);
+ fprintf(stdnimp,"CreateIconFromResource3 probably only a stub\n");
+ dprintf_icon(stddeb,
+ "CreateIconFromResource32 %s at %p size %d winver %d return 0x%04x\n",
+ (bIcon)?"Icon":"Cursor",bits,cbSize,bIcon,ret);
+ return ret;
+}
+
+
/**********************************************************************
* CreateIconFromResourceEx32 (USER32.76)
*/
diff --git a/objects/dc.c b/objects/dc.c
index 2e0e1c1..7ff616d 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -18,46 +18,6 @@
extern void CLIPPING_UpdateGCRegion( DC * dc ); /* objects/clipping.c */
- /* Default DC values */
-static const WIN_DC_INFO DC_defaultValues =
-{
- 0, /* flags */
- NULL, /* devCaps */
- 0, /* hClipRgn */
- 0, /* hVisRgn */
- 0, /* hGCClipRgn */
- STOCK_BLACK_PEN, /* hPen */
- STOCK_WHITE_BRUSH, /* hBrush */
- STOCK_SYSTEM_FONT, /* hFont */
- 0, /* hBitmap */
- 0, /* hFirstBitmap */
- 0, /* hDevice */
- STOCK_DEFAULT_PALETTE, /* hPalette */
- R2_COPYPEN, /* ROPmode */
- ALTERNATE, /* polyFillMode */
- BLACKONWHITE, /* stretchBltMode */
- ABSOLUTE, /* relAbsMode */
- OPAQUE, /* backgroundMode */
- RGB( 255, 255, 255 ), /* backgroundColor */
- RGB( 0, 0, 0 ), /* textColor */
- 0, /* backgroundPixel */
- 0, /* textPixel */
- 0, /* brushOrgX */
- 0, /* brushOrgY */
- TA_LEFT | TA_TOP | TA_NOUPDATECP, /* textAlign */
- 0, /* charExtra */
- 0, /* breakTotalExtra */
- 0, /* breakCount */
- 0, /* breakExtra */
- 0, /* breakRem */
- 1, /* bitsPerPixel */
- MM_TEXT, /* MapMode */
- GM_COMPATIBLE, /* GraphicsMode */
- 0, /* DCOrgX */
- 0, /* DCOrgY */
- 0, /* CursPosX */
- 0 /* CursPosY */
-};
/* ROP code to GC function conversion */
const int DC_XROPfunction[16] =
@@ -134,6 +94,54 @@
/***********************************************************************
+ * DC_Init_DC_INFO
+ *
+ * Fill the WIN_DC_INFO structure.
+ */
+static void DC_Init_DC_INFO( WIN_DC_INFO *win_dc_info )
+{
+ win_dc_info->flags = 0;
+ win_dc_info->devCaps = NULL;
+ win_dc_info->hClipRgn = 0;
+ win_dc_info->hVisRgn = 0;
+ win_dc_info->hGCClipRgn = 0;
+ win_dc_info->hPen = STOCK_BLACK_PEN;
+ win_dc_info->hBrush = STOCK_WHITE_BRUSH;
+ win_dc_info->hFont = STOCK_SYSTEM_FONT;
+ win_dc_info->hBitmap = 0;
+ win_dc_info->hFirstBitmap = 0;
+ win_dc_info->hDevice = 0;
+ win_dc_info->hPalette = STOCK_DEFAULT_PALETTE;
+ win_dc_info->ROPmode = R2_COPYPEN;
+ win_dc_info->polyFillMode = ALTERNATE;
+ win_dc_info->stretchBltMode = BLACKONWHITE;
+ win_dc_info->relAbsMode = ABSOLUTE;
+ win_dc_info->backgroundMode = OPAQUE;
+ win_dc_info->backgroundColor = RGB( 255, 255, 255 );
+ win_dc_info->textColor = RGB( 0, 0, 0 );
+ win_dc_info->backgroundPixel = 0;
+ win_dc_info->textPixel = 0;
+ win_dc_info->brushOrgX = 0;
+ win_dc_info->brushOrgY = 0;
+ win_dc_info->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
+ win_dc_info->charExtra = 0;
+ win_dc_info->breakTotalExtra = 0;
+ win_dc_info->breakCount = 0;
+ win_dc_info->breakExtra = 0;
+ win_dc_info->breakRem = 0;
+ win_dc_info->bitsPerPixel = 1;
+ win_dc_info->MapMode = MM_TEXT;
+ win_dc_info->GraphicsMode = GM_COMPATIBLE;
+ win_dc_info->DCOrgX = 0;
+ win_dc_info->DCOrgY = 0;
+ win_dc_info->CursPosX = 0;
+ win_dc_info->CursPosY = 0;
+
+ PATH_InitGdiPath(&win_dc_info->path);
+}
+
+
+/***********************************************************************
* DC_AllocDC
*/
DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
@@ -159,7 +167,8 @@
dc->vportExtX = 1;
dc->vportExtY = 1;
- memcpy( &dc->w, &DC_defaultValues, sizeof(DC_defaultValues) );
+ DC_Init_DC_INFO( &dc->w );
+
return dc;
}
@@ -349,8 +358,32 @@
}
else val.line_style = LineSolid;
val.line_width = dc->u.x.pen.width;
- val.cap_style = (val.line_width <= 1) ? CapNotLast : CapRound;
- val.join_style = JoinMiter;
+ if (val.line_width <= 1) {
+ val.cap_style = CapNotLast;
+ } else {
+ switch (dc->u.x.pen.endcap)
+ {
+ case PS_ENDCAP_SQUARE:
+ val.cap_style = CapProjecting;
+ break;
+ case PS_ENDCAP_FLAT:
+ val.cap_style = CapButt;
+ break;
+ case PS_ENDCAP_ROUND:
+ default:
+ val.cap_style = CapRound;
+ }
+ }
+ switch (dc->u.x.pen.linejoin)
+ {
+ case PS_JOIN_BEVEL:
+ val.join_style = JoinBevel;
+ case PS_JOIN_MITER:
+ val.join_style = JoinMiter;
+ case PS_JOIN_ROUND:
+ default:
+ val.join_style = JoinRound;
+ }
XChangeGC( display, dc->u.x.gc,
GCFunction | GCForeground | GCBackground | GCLineWidth |
GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
@@ -453,6 +486,8 @@
newdc->hSelf = (HDC32)handle;
newdc->saveLevel = 0;
+ PATH_InitGdiPath( &newdc->w.path );
+
/* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
newdc->w.hGCClipRgn = newdc->w.hVisRgn = 0;
@@ -572,6 +607,21 @@
return 0;
}
dcs = (DC *) GDI_HEAP_LOCK( hdcs );
+
+ /* Copy path. The reason why path saving / restoring is in SaveDC/
+ * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
+ * functions are only in Win16 (which doesn't have paths) and that
+ * SetDCState doesn't allow us to signal an error (which can happen
+ * when copying paths).
+ */
+ if (!PATH_AssignGdiPath( &dcs->w.path, &dc->w.path ))
+ {
+ GDI_HEAP_UNLOCK( hdc );
+ GDI_HEAP_UNLOCK( hdcs );
+ DeleteDC32( hdcs );
+ return 0;
+ }
+
dcs->header.hNext = dc->header.hNext;
dc->header.hNext = hdcs;
dprintf_dc(stddeb, "SaveDC(%04x): returning %d\n", hdc, dc->saveLevel+1 );
@@ -597,6 +647,7 @@
BOOL32 WINAPI RestoreDC32( HDC32 hdc, INT32 level )
{
DC * dc, * dcs;
+ BOOL32 success;
dprintf_dc(stddeb, "RestoreDC: %04x %d\n", hdc, level );
dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
@@ -620,6 +671,7 @@
return FALSE;
}
+ success=TRUE;
while (dc->saveLevel >= level)
{
HDC16 hdcs = dc->header.hNext;
@@ -629,11 +681,18 @@
return FALSE;
}
dc->header.hNext = dcs->header.hNext;
- if (--dc->saveLevel < level) SetDCState( hdc, hdcs );
+ if (--dc->saveLevel < level)
+ {
+ SetDCState( hdc, hdcs );
+ if (!PATH_AssignGdiPath( &dc->w.path, &dcs->w.path ))
+ /* FIXME: This might not be quite right, since we're
+ * returning FALSE but still destroying the saved DC state */
+ success=FALSE;
+ }
DeleteDC32( hdcs );
}
GDI_HEAP_UNLOCK( hdc );
- return TRUE;
+ return success;
}
@@ -823,6 +882,8 @@
if (dc->w.hVisRgn) DeleteObject32( dc->w.hVisRgn );
if (dc->w.hGCClipRgn) DeleteObject32( dc->w.hGCClipRgn );
+ PATH_DestroyGdiPath(&dc->w.path);
+
return GDI_FreeObject( hdc );
}
diff --git a/objects/dib.c b/objects/dib.c
index 3c1be2e..b5d1cf2 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -291,6 +291,7 @@
srcbits += linebytes;
}
} else {
+ lines = -lines;
for (h = 0; h < lines; h++) {
DIB_SetImageBits_1_Line(dstwidth, colors, bmpImage, h, srcbits);
srcbits += linebytes;
@@ -327,6 +328,7 @@
bits = srcbits;
}
} else {
+ lines = -lines;
for (h = 0; h < lines; h++) {
for (i = dstwidth/2, x = 0; i > 0; i--) {
BYTE pix = *bits++;
@@ -731,6 +733,7 @@
bits = (srcbits += linebytes);
}
} else {
+ lines = -lines;
for (h = 0; h < lines; h++) {
for (x = 0; x < dstwidth; x++, bits += 4) {
XPutPixel( bmpImage, x, h,
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index dd49530..fe3c6f9 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -90,6 +90,10 @@
{ 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
};
+/* Filler to make the location counter dword aligned again. This is necessary
+ since (a) FONTOBJ is packed, (b) gcc places initialised variables in the code
+ segment, and (c) Solaris assembler is stupid. */
+static UINT16 align_OEMFixedFont = 1;
static FONTOBJ AnsiFixedFont =
{
@@ -97,6 +101,7 @@
{ 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
};
+static UINT16 align_AnsiFixedFont = 1;
static FONTOBJ AnsiVarFont =
{
@@ -104,6 +109,7 @@
{ 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
};
+static UINT16 align_AnsiVarFont = 1;
static FONTOBJ SystemFont =
{
@@ -111,6 +117,7 @@
{ 16, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "System" }
};
+static UINT16 align_SystemFont = 1;
static FONTOBJ DeviceDefaultFont =
{
@@ -118,6 +125,7 @@
{ 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "" }
};
+static UINT16 align_DeviceDefaultFont = 1;
static FONTOBJ SystemFixedFont =
{
@@ -125,6 +133,16 @@
{ 12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, "" }
};
+static UINT16 align_SystemFixedFont = 1;
+
+/* FIXME: Is this correct? */
+static FONTOBJ DefaultGuiFont =
+{
+ { 9, FONT_MAGIC, 1 }, /* header */
+ { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
+ 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" }
+};
+static UINT16 align_DefaultGuiFont = 1;
static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] =
@@ -145,7 +163,8 @@
(GDIOBJHDR *) &SystemFont,
(GDIOBJHDR *) &DeviceDefaultFont,
NULL, /* DEFAULT_PALETTE created by PALETTE_Init */
- (GDIOBJHDR *) &SystemFixedFont
+ (GDIOBJHDR *) &SystemFixedFont,
+ (GDIOBJHDR *) &DefaultGuiFont
};
/******************************************************************************
@@ -213,6 +232,15 @@
extern BOOL32 X11DRV_Init(void);
extern BOOL32 DIB_Init(void);
+ /* Kill some warnings. */
+ (void)align_OEMFixedFont;
+ (void)align_AnsiFixedFont;
+ (void)align_AnsiVarFont;
+ (void)align_SystemFont;
+ (void)align_DeviceDefaultFont;
+ (void)align_SystemFixedFont;
+ (void)align_DefaultGuiFont;
+
/* TWEAK: Initialize font hints */
ReadFontInformation("OEMFixed", &OEMFixedFont, 12, 0, 0, 0, 0);
ReadFontInformation("AnsiFixed", &AnsiFixedFont, 12, 0, 0, 0, 0);
@@ -515,6 +543,28 @@
return GetObject32A( handle, count, buffer );
}
+/***********************************************************************
+ * GetCurrentObject (GDI32.166)
+ */
+HANDLE32 WINAPI GetCurrentObject(HDC32 hdc,UINT32 type)
+{
+ DC * dc = DC_GetDCPtr( hdc );
+
+ if (!dc)
+ return 0;
+ switch (type) {
+ case OBJ_PEN: return dc->w.hPen;
+ case OBJ_BRUSH: return dc->w.hBrush;
+ case OBJ_PAL: return dc->w.hPalette;
+ case OBJ_FONT: return dc->w.hFont;
+ case OBJ_BITMAP: return dc->w.hBitmap;
+ default:
+ /* the SDK only mentions those above */
+ fprintf(stderr,"GetCurrentObject(%08x,%d), unknown type.\n",hdc,type);
+ return 0;
+ }
+}
+
/***********************************************************************
* SelectObject16 (GDI.45)
diff --git a/objects/metafile.c b/objects/metafile.c
index 7785313..373c851 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -277,6 +277,10 @@
mr = (METARECORD *)((char *)mh + offset);
dprintf_metafile(stddeb,"offset = %04x size = %08lx function = %04x\n",
offset,mr->rdSize,mr->rdFunction);
+ if (!mr->rdSize) {
+ fprintf(stderr,"METAFILE entry got size 0 at offset %d, total mf length is %ld\n",offset,mh->mtSize*2);
+ break; /* would loop endlessly otherwise */
+ }
offset += mr->rdSize * 2;
PlayMetaFileRecord16( hdc, ht, mr, mh->mtNoObjects );
}
@@ -650,6 +654,8 @@
dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
else
{
+ dprintf_metafile(stddeb,"EXTTEXTOUT: %s len: %ld\n",
+ sot,mr->rdSize);
fprintf(stderr,
"Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
len,s1,mr->rdSize,mr->rdParam[3]);
diff --git a/objects/palette.c b/objects/palette.c
index c8adcaa..f7f4a04 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -20,9 +20,6 @@
/* #define DEBUG_PALETTE */
#include "debug.h"
- /* lookup pixel among static entries of the system palette */
-extern int COLOR_LookupSystemPixel(COLORREF);
-
static UINT32 SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
@@ -36,8 +33,6 @@
*/
HPALETTE16 PALETTE_Init(void)
{
- extern const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void);
-
int i;
HPALETTE16 hpalette;
LOGPALETTE * palPtr;
@@ -117,6 +112,14 @@
return hpalette;
}
+/***********************************************************************
+ * CreateHalftonePalette (GDI32.47)
+ */
+HPALETTE32 WINAPI CreateHalftonePalette(HDC32 hdc)
+{
+ fprintf(stdnimp,"CreateHalftonePalette: empty stub!\n");
+ return NULL;
+}
/***********************************************************************
* GetPaletteEntries16 (GDI.363)
diff --git a/objects/pen.c b/objects/pen.c
index c2c63ad..ca3a191 100644
--- a/objects/pen.c
+++ b/objects/pen.c
@@ -73,6 +73,30 @@
return hpen;
}
+/***********************************************************************
+ * ExtCreatePen32 (GDI32.93)
+ *
+ * FIXME: PS_USERSTYLE not handled
+ */
+
+HPEN32 WINAPI ExtCreatePen32( DWORD style, DWORD width,
+ const LOGBRUSH32 * brush, DWORD style_count,
+ const DWORD *style_bits )
+{
+ LOGPEN32 logpen;
+
+ if ((style & PS_STYLE_MASK) == PS_USERSTYLE)
+ fprintf(stderr, "ExtCreatePen: PS_USERSTYLE not handled\n");
+ if ((style & PS_TYPE_MASK) == PS_GEOMETRIC)
+ if (brush->lbHatch)
+ fprintf(stderr, "ExtCreatePen: Hatches not implemented\n");
+
+ logpen.lopnStyle = style & ~PS_TYPE_MASK;
+ logpen.lopnWidth.x = (style & PS_GEOMETRIC) ? width : 1;
+ logpen.lopnWidth.y = 0;
+ logpen.lopnColor = brush->lbColor;
+ return CreatePenIndirect32( &logpen );
+}
/***********************************************************************
* PEN_GetObject16
diff --git a/objects/text.c b/objects/text.c
index 04f8f8b..60ec10c 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -13,6 +13,7 @@
#include "stddebug.h"
/* #define DEBUG_TEXT */
#include "debug.h"
+#include "cache.h"
#define TAB 9
#define LF 10
@@ -420,21 +421,117 @@
/***********************************************************************
+ * TEXT_GrayString
+ *
+ * FIXME: The call to 16-bit code only works because the wine GDI is a 16-bit
+ * heap and we can guarantee that the handles fit in an INT16. We have to
+ * rethink the strategy once the migration to NT handles is complete.
+ * We are going to get a lot of code-duplication once this migration is
+ * completed...
+ *
+ */
+static BOOL32 TEXT_GrayString(HDC32 hdc, HBRUSH32 hb,
+ GRAYSTRINGPROC32 fn, LPARAM lp, INT32 len,
+ INT32 x, INT32 y, INT32 cx, INT32 cy,
+ BOOL32 unicode, BOOL32 _32bit)
+{
+ HBITMAP32 hbm, hbmsave;
+ HBRUSH32 hbsave;
+ HFONT32 hfsave;
+ HDC32 memdc = CreateCompatibleDC32(hdc);
+ int slen = len;
+ BOOL32 retval = TRUE;
+ RECT32 r;
+ COLORREF fg, bg;
+
+ if(!hdc) return FALSE;
+
+ if(len == 0)
+ {
+ if(unicode)
+ slen = lstrlen32W((LPCWSTR)lp);
+ else if(_32bit)
+ slen = lstrlen32A((LPCSTR)lp);
+ else
+ slen = lstrlen32A((LPCSTR)PTR_SEG_TO_LIN(lp));
+ }
+
+ if((cx == 0 || cy == 0) && slen != -1)
+ {
+ SIZE32 s;
+ if(unicode)
+ GetTextExtentPoint32W(hdc, (LPCWSTR)lp, slen, &s);
+ else if(_32bit)
+ GetTextExtentPoint32A(hdc, (LPCSTR)lp, slen, &s);
+ else
+ GetTextExtentPoint32A(hdc, (LPCSTR)PTR_SEG_TO_LIN(lp), slen, &s);
+ if(cx == 0) cx = s.cx;
+ if(cy == 0) cy = s.cy;
+ }
+
+ r.left = r.top = 0;
+ r.right = cx;
+ r.bottom = cy;
+
+ hbm = CreateBitmap32(cx, cy, 1, 1, NULL);
+ hbmsave = (HBITMAP32)SelectObject32(memdc, hbm);
+ FillRect32(memdc, &r, (HBRUSH32)GetStockObject32(BLACK_BRUSH));
+ SetTextColor32(memdc, RGB(255, 255, 255));
+ SetBkColor32(memdc, RGB(0, 0, 0));
+ hfsave = (HFONT32)SelectObject32(memdc, GetCurrentObject(hdc, OBJ_FONT));
+
+ if(fn)
+ if(_32bit)
+ retval = fn(memdc, lp, slen);
+ else
+ retval = (BOOL32)((BOOL16)((GRAYSTRINGPROC16)fn)((HDC16)memdc, lp, (INT16)slen));
+ else
+ if(unicode)
+ TextOut32W(memdc, 0, 0, (LPCWSTR)lp, slen);
+ else if(_32bit)
+ TextOut32A(memdc, 0, 0, (LPCSTR)lp, slen);
+ else
+ TextOut32A(memdc, 0, 0, (LPCSTR)PTR_SEG_TO_LIN(lp), slen);
+
+ SelectObject32(memdc, hfsave);
+
+/*
+ * Windows doc says that the bitmap isn't grayed when len == -1 and
+ * the callback function returns FALSE. However, testing this on
+ * win95 showed otherwise...
+*/
+#ifdef GRAYSTRING_USING_DOCUMENTED_BEHAVIOUR
+ if(retval || len != -1)
+#endif
+ {
+ hbsave = (HBRUSH32)SelectObject32(memdc, CACHE_GetPattern55AABrush());
+ PatBlt32(memdc, 0, 0, cx, cy, 0x000A0329);
+ SelectObject32(memdc, hbsave);
+ }
+
+ if(hb) hbsave = (HBRUSH32)SelectObject32(hdc, hb);
+ fg = SetTextColor32(hdc, RGB(0, 0, 0));
+ bg = SetBkColor32(hdc, RGB(255, 255, 255));
+ BitBlt32(hdc, x, y, cx, cy, memdc, 0, 0, 0x00E20746);
+ SetTextColor32(hdc, fg);
+ SetBkColor32(hdc, bg);
+ if(hb) SelectObject32(hdc, hbsave);
+
+ SelectObject32(memdc, hbmsave);
+ DeleteObject32(hbm);
+ DeleteDC32(memdc);
+ return retval;
+}
+
+
+/***********************************************************************
* GrayString16 (USER.185)
*/
BOOL16 WINAPI GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 gsprc,
LPARAM lParam, INT16 cch, INT16 x, INT16 y,
INT16 cx, INT16 cy )
{
- BOOL16 ret;
- COLORREF current_color;
-
- if (!cch) cch = lstrlen16( (LPCSTR)PTR_SEG_TO_LIN(lParam) );
- if (gsprc) return gsprc( hdc, lParam, cch );
- current_color = SetTextColor32( hdc, GetSysColor32(COLOR_GRAYTEXT) );
- ret = TextOut16( hdc, x, y, (LPCSTR)PTR_SEG_TO_LIN(lParam), cch );
- SetTextColor32( hdc, current_color );
- return ret;
+ return TEXT_GrayString(hdc, hbr, (GRAYSTRINGPROC32)gsprc, lParam, cch, x, y, cx, cy, FALSE, FALSE);
}
@@ -445,15 +542,7 @@
LPARAM lParam, INT32 cch, INT32 x, INT32 y,
INT32 cx, INT32 cy )
{
- BOOL32 ret;
- COLORREF current_color;
-
- if (!cch) cch = lstrlen32A( (LPCSTR)lParam );
- if (gsprc) return gsprc( hdc, lParam, cch );
- current_color = SetTextColor32( hdc, GetSysColor32(COLOR_GRAYTEXT) );
- ret = TextOut32A( hdc, x, y, (LPCSTR)lParam, cch );
- SetTextColor32( hdc, current_color );
- return ret;
+ return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, FALSE, TRUE);
}
@@ -464,15 +553,7 @@
LPARAM lParam, INT32 cch, INT32 x, INT32 y,
INT32 cx, INT32 cy )
{
- BOOL32 ret;
- COLORREF current_color;
-
- if (!cch) cch = lstrlen32W( (LPCWSTR)lParam );
- if (gsprc) return gsprc( hdc, lParam, cch );
- current_color = SetTextColor32( hdc, GetSysColor32(COLOR_GRAYTEXT) );
- ret = TextOut32W( hdc, x, y, (LPCWSTR)lParam, cch );
- SetTextColor32( hdc, current_color );
- return ret;
+ return TEXT_GrayString(hdc, hbr, gsprc, lParam, cch, x, y, cx, cy, TRUE, TRUE);
}
@@ -655,8 +736,10 @@
INT32 WINAPI GetTextCharsetInfo(HDC32 hdc,LPCHARSETINFO csi,DWORD flags)
{
fprintf(stdnimp,"GetTextCharsetInfo(0x%x,%p,%08lx), stub!\n",hdc,csi,flags);
- csi->ciCharset = DEFAULT_CHARSET;
- csi->ciACP = GetACP();
+ if (csi) {
+ csi->ciCharset = DEFAULT_CHARSET;
+ csi->ciACP = GetACP();
+ }
/* ... fill fontstruct too ... */
return DEFAULT_CHARSET;
}
diff --git a/ole/Makefile.in b/ole/Makefile.in
index feeca6c..1d923733 100644
--- a/ole/Makefile.in
+++ b/ole/Makefile.in
@@ -7,6 +7,8 @@
C_SRCS = \
compobj.c \
+ ifs.c \
+ folders.c \
ole2.c \
ole2disp.c \
ole2nls.c \
@@ -18,4 +20,3 @@
@MAKE_RULES@
### Dependencies:
-
diff --git a/ole/folders.c b/ole/folders.c
new file mode 100644
index 0000000..cf0def5
--- /dev/null
+++ b/ole/folders.c
@@ -0,0 +1,174 @@
+/*
+ * Shell Folder stuff
+ *
+ * Copyright 1997 Marcus Meissner
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ole.h"
+#include "ole2.h"
+#include "stddebug.h"
+#include "debug.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+
+/******************************************************************************
+ * IEnumIDList implementation
+ */
+
+static ULONG WINAPI IEnumIDList_AddRef(LPENUMIDLIST this) {
+ fprintf(stderr,"IEnumIDList(%p)->AddRef()\n",this);
+ return ++(this->ref);
+}
+
+static ULONG WINAPI IEnumIDList_Release(LPENUMIDLIST this) {
+ fprintf(stderr,"IEnumIDList(%p)->Release()\n",this);
+ if (!--(this->ref)) {
+ fprintf(stderr," -> freeing IEnumIDList(%p)\n",this);
+ HeapFree(GetProcessHeap(),0,this);
+ return 0;
+ }
+ return this->ref;
+}
+
+static HRESULT WINAPI IEnumIDList_Next(
+ LPENUMIDLIST this,ULONG celt,LPITEMIDLIST *rgelt,ULONG *pceltFetched
+) {
+ fprintf(stderr,"IEnumIDList(%p)->Next(%ld,%p,%p),stub!\n",
+ this,celt,rgelt,pceltFetched
+ );
+ *pceltFetched = 0; /* we don't have any ... */
+ return 0;
+}
+
+static IEnumIDList_VTable eidlvt = {
+ 1,
+ IEnumIDList_AddRef,
+ IEnumIDList_Release,
+ IEnumIDList_Next,
+ 5,6,7
+};
+
+LPENUMIDLIST IEnumIDList_Constructor() {
+ LPENUMIDLIST lpeidl;
+
+ lpeidl= (LPENUMIDLIST)HeapAlloc(GetProcessHeap(),0,sizeof(IEnumIDList));
+ lpeidl->ref = 1;
+ lpeidl->lpvtbl = &eidlvt;
+ return lpeidl;
+}
+
+/******************************************************************************
+ * IShellFolder implementation
+ */
+static ULONG WINAPI IShellFolder_Release(LPSHELLFOLDER this) {
+ fprintf(stderr,"IShellFolder(%p)->Release()\n",this);
+ if (!--(this->ref)) {
+ fprintf(stderr," -> freeing IShellFolder(%p)\n",this);
+ HeapFree(GetProcessHeap(),0,this);
+ return 0;
+ }
+ return this->ref;
+}
+
+static ULONG WINAPI IShellFolder_AddRef(LPSHELLFOLDER this) {
+ fprintf(stderr,"IShellFolder(%p)->AddRef()\n",this);
+ return ++(this->ref);
+}
+
+static HRESULT WINAPI IShellFolder_GetAttributesOf(
+ LPSHELLFOLDER this,UINT32 cidl,LPCITEMIDLIST *apidl,DWORD *rgfInOut
+) {
+ fprintf(stderr,"IShellFolder(%p)->GetAttributesOf(%d,%p,%p),stub!\n",
+ this,cidl,apidl,rgfInOut
+ );
+ return 0;
+}
+
+static HRESULT WINAPI IShellFolder_BindToObject(
+ LPSHELLFOLDER this,LPCITEMIDLIST pidl,LPBC pbcReserved,REFIID riid,LPVOID * ppvOut
+) {
+ char xclsid[50];
+
+ StringFromCLSID(riid,xclsid);
+ fprintf(stderr,"IShellFolder(%p)->BindToObject(%p,%p,%s,%p),stub!\n",
+ this,pidl,pbcReserved,xclsid,ppvOut
+ );
+ *ppvOut = IShellFolder_Constructor();
+ return 0;
+}
+
+static HRESULT WINAPI IShellFolder_ParseDisplayName(
+ LPSHELLFOLDER this,HWND32 hwndOwner,LPBC pbcReserved,
+ LPOLESTR lpszDisplayName,DWORD *pchEaten,LPITEMIDLIST *ppidl,
+ DWORD *pdwAttributes
+) {
+ fprintf(stderr,"IShellFolder(%p)->ParseDisplayName(%08x,%p,%s,%p,%p,%p),stub!\n",
+ this,hwndOwner,pbcReserved,lpszDisplayName,pchEaten,ppidl,pdwAttributes
+ );
+ *(DWORD*)pbcReserved = NULL;
+ return 0;
+}
+
+static HRESULT WINAPI IShellFolder_EnumObjects(
+ LPSHELLFOLDER this,HWND32 hwndOwner,DWORD grfFlags,
+ LPENUMIDLIST* ppenumIDList
+) {
+ fprintf(stderr,"IShellFolder(%p)->EnumObjects(0x%04x,0x%08lx,%p),stub!\n",
+ this,hwndOwner,grfFlags,ppenumIDList
+ );
+ *ppenumIDList = IEnumIDList_Constructor();
+ return 0;
+}
+
+static HRESULT WINAPI IShellFolder_CreateViewObject(
+ LPSHELLFOLDER this,HWND32 hwndOwner,REFIID riid,LPVOID *ppv
+) {
+ char xclsid[50];
+
+ StringFromCLSID(riid,xclsid);
+ fprintf(stderr,"IShellFolder(%p)->CreateViewObject(0x%04x,%s,%p),stub!\n",
+ this,hwndOwner,xclsid,ppv
+ );
+ *(DWORD*)ppv = NULL;
+ return 0;
+}
+
+
+static struct IShellFolder_VTable sfvt = {
+ 1,
+ IShellFolder_AddRef,
+ IShellFolder_Release,
+ IShellFolder_ParseDisplayName,
+ IShellFolder_EnumObjects,
+ IShellFolder_BindToObject,
+ 7,8,
+ IShellFolder_CreateViewObject,
+ IShellFolder_GetAttributesOf,
+ 11,12,13
+};
+
+LPSHELLFOLDER IShellFolder_Constructor() {
+ LPSHELLFOLDER sf;
+
+ sf = (LPSHELLFOLDER)HeapAlloc(GetProcessHeap(),0,sizeof(IShellFolder));
+ sf->ref = 1;
+ sf->lpvtbl = &sfvt;
+ return sf;
+}
+
+static struct IShellLink_VTable slvt = {
+ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
+};
+
+LPSHELLLINK IShellLink_Constructor() {
+ LPSHELLLINK sl;
+
+ sl = (LPSHELLLINK)HeapAlloc(GetProcessHeap(),0,sizeof(IShellLink));
+ sl->ref = 1;
+ sl->lpvtbl = &slvt;
+ return sl;
+}
diff --git a/ole/ifs.c b/ole/ifs.c
new file mode 100644
index 0000000..958a0ae
--- /dev/null
+++ b/ole/ifs.c
@@ -0,0 +1,136 @@
+/*
+ * basic interfaces
+ *
+ * Copyright 1997 Marcus Meissner
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "winerror.h"
+#include "ole.h"
+#include "ole2.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "shlobj.h"
+#include "stddebug.h"
+#include "debug.h"
+
+static ULONG WINAPI IUnknown_AddRef(LPUNKNOWN this) {
+ dprintf_relay(stddeb,"IUnknown(%p)->AddRef()\n",this);
+ return ++(this->ref);
+}
+static ULONG WINAPI IUnknown_Release(LPUNKNOWN this) {
+ dprintf_relay(stddeb,"IUnknown(%p)->Release()\n",this);
+ if (!--(this->ref)) {
+ HeapFree(GetProcessHeap(),0,this);
+ return 0;
+ }
+ return this->ref;
+}
+
+static HRESULT WINAPI IUnknown_QueryInterface(LPUNKNOWN this,REFIID refiid,LPVOID *obj) {
+ char xrefiid[50];
+
+ StringFromCLSID((LPCLSID)refiid,xrefiid);
+ dprintf_relay(stddeb,"IUnknown(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
+
+ if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
+ *obj = this;
+ return 0;
+ }
+ return OLE_E_ENUM_NOMORE;
+}
+
+static IUnknown_VTable uvt = {
+ IUnknown_QueryInterface,
+ IUnknown_AddRef,
+ IUnknown_Release
+};
+
+
+LPUNKNOWN
+IUnknown_Constructor() {
+ LPUNKNOWN unk;
+
+ fprintf(stderr,"cloning IUnknown.\n");
+ unk = (LPUNKNOWN)HeapAlloc(GetProcessHeap(),0,sizeof(IUnknown));
+ unk->lpvtbl = &uvt;
+ unk->ref = 1;
+ return unk;
+}
+
+static ULONG WINAPI IMalloc_AddRef(LPMALLOC this) {
+ dprintf_relay(stddeb,"IMalloc(%p)->AddRef()\n",this);
+ return 1; /* cannot be freed */
+}
+
+static ULONG WINAPI IMalloc_Release(LPMALLOC this) {
+ dprintf_relay(stddeb,"IMalloc(%p)->Release()\n",this);
+ return 1; /* cannot be freed */
+}
+
+static HRESULT WINAPI IMalloc_QueryInterface(LPMALLOC this,REFIID refiid,LPVOID *obj) {
+ char xrefiid[50];
+
+ StringFromCLSID((LPCLSID)refiid,xrefiid);
+ dprintf_relay(stddeb,"IMalloc(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
+ if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
+ !memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
+ ) {
+ *obj = this;
+ return 0;
+ }
+ return OLE_E_ENUM_NOMORE;
+}
+
+static LPVOID WINAPI IMalloc_Alloc(LPMALLOC this,DWORD cb) {
+ dprintf_relay(stddeb,"IMalloc(%p)->Alloc(%ld)\n",this,cb);
+ return HeapAlloc(GetProcessHeap(),0,cb);
+}
+
+static LPVOID WINAPI IMalloc_Realloc(LPMALLOC this,LPVOID pv,DWORD cb) {
+ dprintf_relay(stddeb,"IMalloc(%p)->Realloc(%p,%ld)\n",this,pv,cb);
+ return HeapReAlloc(GetProcessHeap(),0,pv,cb);
+}
+static VOID WINAPI IMalloc_Free(LPMALLOC this,LPVOID pv) {
+ dprintf_relay(stddeb,"IMalloc(%p)->Free(%p)\n",this,pv);
+ HeapFree(GetProcessHeap(),0,pv);
+}
+
+static DWORD WINAPI IMalloc_GetSize(LPMALLOC this,LPVOID pv) {
+ dprintf_relay(stddeb,"IMalloc(%p)->GetSize(%p)\n",this,pv);
+ return HeapSize(GetProcessHeap(),0,pv);
+}
+
+static LPINT32 WINAPI IMalloc_DidAlloc(LPMALLOC this,LPVOID pv) {
+ dprintf_relay(stddeb,"IMalloc(%p)->DidAlloc(%p)\n",this,pv);
+ return (LPINT32)0xffffffff;
+}
+static LPVOID WINAPI IMalloc_HeapMinimize(LPMALLOC this) {
+ dprintf_relay(stddeb,"IMalloc(%p)->HeapMinimize()\n",this);
+ return NULL;
+}
+
+static IMalloc_VTable VT_IMalloc = {
+ IMalloc_QueryInterface,
+ IMalloc_AddRef,
+ IMalloc_Release,
+ IMalloc_Alloc,
+ IMalloc_Realloc,
+ IMalloc_Free,
+ IMalloc_GetSize,
+ IMalloc_DidAlloc,
+ IMalloc_HeapMinimize,
+};
+
+LPMALLOC
+IMalloc_Constructor() {
+ LPMALLOC this;
+
+ fprintf(stderr,"cloning IMalloc\n");
+ this = (LPMALLOC)HeapAlloc(GetProcessHeap(),0,sizeof(IMalloc));
+ this->lpvtbl = &VT_IMalloc;
+ this->ref = 1;
+ return this;
+}
diff --git a/programs/Makefile.in b/programs/Makefile.in
index 0118d6d..2f2e839 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -1,4 +1,8 @@
-SUBDIRS = progman winhelp winver
+SUBDIRS = \
+ notepad \
+ progman \
+ winhelp \
+ winver
all: $(SUBDIRS)
diff --git a/programs/notepad/ChangeLog b/programs/notepad/ChangeLog
new file mode 100644
index 0000000..aca5fa0
--- /dev/null
+++ b/programs/notepad/ChangeLog
@@ -0,0 +1,5 @@
+Fri Dec 05 20:51:55 1997 Marcel Baur <mbaur@g26.ethz.ch>
+ * [notepad.c] [notepad.h] [notepad.rc] [En.rc] [De.rc]
+ [license.c] [license.h] [License_En.c]
+ [README] [TODO] [ChangeLog]
+ Originals by Marcel Baur
diff --git a/programs/notepad/De.rc b/programs/notepad/De.rc
new file mode 100644
index 0000000..ca2a109
--- /dev/null
+++ b/programs/notepad/De.rc
@@ -0,0 +1,91 @@
+/*
+ * Notepad (German resources)
+ *
+ * Copyright 1997 Marcel Baur <mbaur@g26.ethz.ch>
+ */
+
+#define LANGUAGE_ID De
+#define LANGUAGE_NUMBER 2
+#define LANGUAGE_MENU_ITEM "&Deutsch"
+
+/* Menu */
+
+#define MENU_FILE "&Datei"
+#define MENU_FILE_NEW "&Neu..."
+#define MENU_FILE_OPEN "Ö&ffnen..."
+#define MENU_FILE_SAVE "&Speichern"
+#define MENU_FILE_SAVEAS "Speichern &unter..."
+#define MENU_FILE_PRINT "&Drucken"
+#define MENU_FILE_PAGESETUP "Seite ein&richten..."
+#define MENU_FILE_PRINTSETUP "Drucker&einrichtung..."
+#define MENU_FILE_EXIT "&Beenden"
+
+#define MENU_EDIT "&Bearbeiten"
+#define MENU_EDIT_UNDO "&Rückgängig\tStrg+Z"
+#define MENU_EDIT_CUT "&Ausschneiden\tStrg+X"
+#define MENU_EDIT_COPY "&Kopieren\tStrg+C"
+#define MENU_EDIT_PASTE "&Einfügen\tStrg+V"
+#define MENU_EDIT_DELETE "&Löschen\tEntf"
+#define MENU_EDIT_SELECTALL "Alles &markieren"
+#define MENU_EDIT_TIMEDATE "&Uhrzeit/Datum\tF5"
+#define MENU_EDIT_WRAP "&Zeilenumbruch"
+
+#define MENU_SEARCH "&Suchen"
+#define MENU_SEARCH_SEARCH "Suchen..."
+#define MENU_SEARCH_NEXT "&Weitersuchen\tF3"
+
+#define MENU_LANGUAGE "&Sprache"
+
+#define MENU_HELP "&Hilfe"
+#define MENU_HELP_CONTENTS "&Inhalt"
+#define MENU_HELP_SEARCH "&Suchen..."
+#define MENU_HELP_HELP_ON_HELP "&Hilfe benutzen"
+
+#define MENU_INFO "Inf&o..."
+#define MENU_INFO_LICENSE "&Lizenz"
+#define MENU_INFO_NO_WARRANTY "&KEINE GARANTIE"
+#define MENU_INFO_ABOUT_WINE "&Über WINE"
+
+
+/* Dialogs */
+
+#define DIALOG_OK "OK"
+#define DIALOG_CANCEL "Abbrechen"
+#define DIALOG_BROWSE "&Durchsuchen..."
+#define DIALOG_HELP "&Hilfe"
+
+#define DIALOG_PAGESETUP_CAPTION "Seite einrichten"
+#define DIALOG_PAGESETUP_HEAD "&Kopfzeile:"
+#define DIALOG_PAGESETUP_TAIL "&Fußzeile:"
+#define DIALOG_PAGESETUP_BORDERS "Ränder"
+#define DIALOG_PAGESETUP_LEFT "&Links:"
+#define DIALOG_PAGESETUP_RIGHT "&Right:"
+#define DIALOG_PAGESETUP_TOP "&Oben:"
+#define DIALOG_PAGESETUP_BOTTOM "&Unten:"
+
+
+/* Strings */
+#define STRING_NOTEPAD "Editor"
+#define STRING_ERROR "FEHLER"
+#define STRING_WARNING "ACHTUNG"
+#define STRING_INFO "Information"
+
+#define STRING_UNTITLED "(unbenannt)"
+
+#define STRING_ALLFILES "Alle Dateien (*.*)"
+#define STRING_TEXTFILES "Textdateien (*.TXT)"
+
+#define STRING_TOOLARGE "'%s' ist zu gross für den Editor\n \
+Benutzen Sie bitte einen anderen Editor, um diese Datei zu bearbeiten."
+
+#define STRING_NOTEXT "Sie haben keinen Text eingegeben, der \
+gespeichert\n werden könnte. Geben Sie Text ein, und versuchen Sie es \
+\nerneut."
+
+#define STRING_NOTFOUND "'%s' kann nicht gefunden werden."
+
+#define STRING_OUT_OF_MEMORY "Nicht genügend Arbeitsspeicher, \
+um diese Funktion \nabzuschließen. Beenden Sie eine oder mehrere \
+\nAnwendungen, um den verfügbaren Arbeitsspeicher zu \nerhöhen."
+
+
diff --git a/programs/notepad/En.rc b/programs/notepad/En.rc
new file mode 100644
index 0000000..35ab98a
--- /dev/null
+++ b/programs/notepad/En.rc
@@ -0,0 +1,91 @@
+/*
+ * Notepad (English resources)
+ *
+ * Copyright 1997 Marcel Baur <mbaur@g26.ethz.ch>
+ * FIXME: See TODO about how to fix weak translations.
+ */
+
+#define LANGUAGE_ID En
+#define LANGUAGE_NUMBER 0
+#define LANGUAGE_MENU_ITEM "&English"
+
+/* Menu */
+
+#define MENU_FILE "&File"
+#define MENU_FILE_NEW "&New..."
+#define MENU_FILE_OPEN "O&pen"
+#define MENU_FILE_SAVE "&Save"
+#define MENU_FILE_SAVEAS "&Save as..."
+#define MENU_FILE_PRINT "&Print"
+#define MENU_FILE_PAGESETUP "Page Se&tup..."
+#define MENU_FILE_PRINTSETUP "P&rinter Setup..."
+#define MENU_FILE_EXIT "&Exit"
+
+#define MENU_EDIT "&Edit"
+#define MENU_EDIT_UNDO "&Undo\tCtrl+Z"
+#define MENU_EDIT_CUT "Cu&t\Ctrl+X"
+#define MENU_EDIT_COPY "&Copy\tCtrl+C"
+#define MENU_EDIT_PASTE "&Paste\tCtrl+V"
+#define MENU_EDIT_DELETE "&Delete\tDel"
+#define MENU_EDIT_SELECTALL "Select &all"
+#define MENU_EDIT_TIMEDATE "&Time/Date\tF5"
+#define MENU_EDIT_WRAP "&Wrap long lines"
+
+#define MENU_SEARCH "&Search"
+#define MENU_SEARCH_SEARCH "Search..."
+#define MENU_SEARCH_NEXT "&Search next\tF3"
+
+#define MENU_LANGUAGE "&Language"
+
+#define MENU_HELP "&Help"
+#define MENU_HELP_CONTENTS "&Contents"
+#define MENU_HELP_SEARCH "&Search..."
+#define MENU_HELP_HELP_ON_HELP "&Help on help"
+
+#define MENU_INFO "Inf&o..."
+#define MENU_INFO_LICENSE "&License"
+#define MENU_INFO_NO_WARRANTY "&NO WARRANTY"
+#define MENU_INFO_ABOUT_WINE "&About Wine"
+
+/* Dialogs */
+
+#define DIALOG_OK "OK"
+#define DIALOG_CANCEL "Cancel"
+#define DIALOG_BROWSE "&Browse..."
+#define DIALOG_HELP "&Help"
+
+#define DIALOG_PAGESETUP_CAPTION "Page Setup"
+#define DIALOG_PAGESETUP_HEAD "&Header:"
+#define DIALOG_PAGESETUP_TAIL "&Footer:"
+#define DIALOG_PAGESETUP_BORDER "Borders:"
+#define DIALOG_PAGESETUP_LEFT "&Left:"
+#define DIALOG_PAGESETUP_RIGHT "&Right:"
+#define DIALOG_PAGESETUP_TOP "&Top:"
+#define DIALOG_PAGESETUP_BOTTOM "&Bottom:"
+
+
+/* Strings */
+#define STRING_NOTEPAD "Notepad"
+#define STRING_ERROR "ERROR"
+#define STRING_WARNING "WARNING"
+#define STRING_INFO "Information"
+
+#define STRING_UNTITLED "(untitled)"
+
+#define STRING_ALLFILES "All files (*.*)"
+#define STRING_TEXTFILES "Text files (*.*)"
+
+#define STRING_TOOLARGE "File '%s' ist too large for notepad.\n \
+Please use a different editor."
+
+#define STRING_NOTEXT "You didn't enter any text. \
+\nPlease type something and try again"
+
+#define STRING_NOTFOUND "'%s' can not be found."
+
+#define STRING_OUT_OF_MEMORY "Not enough memory to complete this \
+task. \nClose one or more applications to increase the amount of \nfree \
+memory."
+
+
+
diff --git a/programs/notepad/License_En.c b/programs/notepad/License_En.c
new file mode 100644
index 0000000..bec66d9
--- /dev/null
+++ b/programs/notepad/License_En.c
@@ -0,0 +1,48 @@
+#include "windows.h"
+#include "license.h"
+
+static CHAR LicenseCaption_En[] = "LICENSE";
+static CHAR License_En[] = "\
+You may without charge, royalty or other payment, copy and\
+ distribute copies of this work and derivative works of this work\
+ in source or binary form provided that: (1)\
+ you appropriately publish on each copy an appropriate copyright\
+ notice; (2) faithfully reproduce all prior copyright notices\
+ included in the original work (you may also add your own\
+ copyright notice); and (3) agree to indemnify and hold all prior\
+ authors, copyright holders and licensors of the work harmless\
+ from and against all damages arising from use of the work.\
+\n\
+You may distribute sources of derivative works of the work\
+ provided that (1) (a) all source files of the original work that\
+ have been modified, (b) all source files of the derivative work\
+ that contain any party of the original work, and (c) all source\
+ files of the derivative work that are necessary to compile, link\
+ and run the derivative work without unresolved external calls and\
+ with the same functionality of the original work (\"Necessary\
+ Sources\") carry a prominent notice explaining the nature and date\
+ of the modification and/or creation. You are encouraged to make\
+ the Necessary Sources available under this license in order to\
+ further the development and acceptance of the work.\
+\n\
+EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED\
+ WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING\
+ BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A\
+ PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS\
+ OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR\
+ LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF\
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.";
+
+static CHAR NoWarrantyCaption_En[] = "NO WARRANTY";
+static CHAR NoWarranty_En[] = "\
+EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED\
+ WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING\
+ BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A\
+ PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS\
+ OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR\
+ LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF\
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.";
+
+LICENSE WineLicense_En = {License_En, LicenseCaption_En,
+ NoWarranty_En, NoWarrantyCaption_En};
+
diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in
new file mode 100644
index 0000000..f8a83d6
--- /dev/null
+++ b/programs/notepad/Makefile.in
@@ -0,0 +1,47 @@
+DEFS = -DWINELIB
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = none
+PROGRAMS = notepad
+ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
+RCFLAGS = -w32 -h
+
+LANGUAGES = En De
+LICENSELANG = En
+
+MOSTSRCS = \
+ license.c \
+ notepad.c
+
+# Some strings need addresses >= 0x10000
+STRINGSRCS = \
+ $(LICENSELANG:%=License_%.c)
+
+RC_SRCS = \
+ notepad.rc \
+ $(LANGUAGES:%=%.rc)
+
+C_SRCS = $(MOSTSRCS) $(STRINGSRCS)
+
+MOSTOBJS = $(MOSTSRCS:.c=.o)
+STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
+
+all: check_winerc $(PROGRAMS)
+
+depend:: $(RC_SRCS:.rc=.h)
+
+@MAKE_RULES@
+
+notepad: $(MOSTOBJS) $(STRINGOBJS)
+ $(CC) -o notepad $(MOSTOBJS) $(LDOPTIONS) $(ALL_LIBS) $(STRINGOBJS)
+
+install: dummy
+ $(INSTALL_PROGRAM) notepad $(bindir)/notepad
+
+$(RC_SRCS:.rc=.c) $(RC_SRCS:.rc=.h): $(WINERC)
+
+dummy:
+
+### Dependencies:
diff --git a/programs/notepad/README b/programs/notepad/README
new file mode 100644
index 0000000..2e03ea9
--- /dev/null
+++ b/programs/notepad/README
@@ -0,0 +1,19 @@
+
+NOTEPAD for WINE
+================
+
+This is an early release of notepad and most of the code is still
+broken. It will probably compile but the application will not make
+much sense yet.
+
+Please see file TODO for things to do and keep the file ChangeLog
+up to date.
+
+Code is currently under heavy construction. Nearly all files will
+change until next release. You can speed up development of notepad
+if you send patches and additions directly to my personal email
+address <mbaur@g26.ethz.ch>.
+
+I also try to read news:comp.emulators.ms-windows.wine frequently,
+so I can also integrate patches posted via usenet.
+
diff --git a/programs/notepad/TODO b/programs/notepad/TODO
new file mode 100644
index 0000000..d2d28b4
--- /dev/null
+++ b/programs/notepad/TODO
@@ -0,0 +1,8 @@
+
+ - En.rc is translated from german version of Notepad.
+ I don't know what the real strings are, as I do not have an english
+ copy of Notepad. Please check strings in En.rc and submit corrections.
+
+ - create new *.rc files for all languages you know.
+
+
diff --git a/programs/notepad/license.c b/programs/notepad/license.c
new file mode 100644
index 0000000..eee36e1
--- /dev/null
+++ b/programs/notepad/license.c
@@ -0,0 +1,45 @@
+/*
+ * Notepad (license.h)
+ */
+
+#include "windows.h"
+#include "license.h"
+
+static LICENSE* SelectLanguage(LPCSTR Language)
+{
+/* if (!lstrcmp(Language, "Cz")) return(&WineLicense_Cz); */
+/* if (!lstrcmp(Language, "Da")) return(&WineLicense_Da); */
+/* if (!lstrcmp(Language, "De")) return(&WineLicense_De); */
+/* if (!lstrcmp(Language, "En")) return(&WineLicense_En); */
+/* if (!lstrcmp(Language, "Eo")) return(&WineLicense_Eo); */
+/* if (!lstrcmp(Language, "Es")) return(&WineLicense_Es); */
+/* if (!lstrcmp(Language, "Fi")) return(&WineLicense_Fi); */
+/* if (!lstrcmp(Language, "Fr")) return(&WineLicense_Fr); */
+/* if (!lstrcmp(Language, "Hu")) return(&WineLicense_Hu); */
+/* if (!lstrcmp(Language, "It")) return(&WineLicense_It); */
+/* if (!lstrcmp(Langauge, "Ko")) return(&WineLicense_Ko); */
+/* if (!lstrcmp(Language, "No")) return(&WineLicense_No); */
+/* if (!lstrcmp(Language, "Pl")) return(&WineLicense_Pl); */
+/* if (!lstrcmp(Language, "Po")) return(&WineLicense_Po); */
+/* if (!lstrcmp(Language, "Va")) return(&WineLicense_Va); */
+ return(&WineLicense_En);
+}
+
+
+VOID WineLicense(HWND Wnd, LPCSTR Language)
+{
+ LICENSE *License = SelectLanguage(Language);
+
+ MessageBox(Wnd, License->License, License->LicenseCaption,
+ MB_ICONINFORMATION | MB_OK);
+}
+
+
+VOID WineWarranty(HWND Wnd, LPCSTR Language)
+{
+ LICENSE *License = SelectLanguage(Language);
+
+ MessageBox(Wnd, License->Warranty, License->WarrantyCaption,
+ MB_ICONEXCLAMATION | MB_OK);
+}
+
diff --git a/programs/notepad/license.h b/programs/notepad/license.h
new file mode 100644
index 0000000..c9a1e8d
--- /dev/null
+++ b/programs/notepad/license.h
@@ -0,0 +1,29 @@
+/*
+ * Notepad (license.h)
+ */
+
+VOID WineLicense(HWND hWnd, LPCSTR lpszLanguage);
+VOID WineWarranty(HWND hWnd, LPCSTR language);
+
+typedef struct
+{
+ LPCSTR License, LicenseCaption;
+ LPCSTR Warranty, WarrantyCaption;
+} LICENSE;
+
+/* extern LICENSE WineLicense_Cz; */
+/* extern LICENSE WineLicense_Da; */
+/* extern LICENSE WineLicense_De; */
+extern LICENSE WineLicense_En;
+/* extern LICENSE WineLicense_Eo; */
+/* extern LICENSE WineLicense_Es; */
+/* extern LICENSE WineLicense_Fi; */
+/* extern LICENSE WineLicense_Fr; */
+/* extern LICENSE WineLicense_Hu; */
+/* extern LICENSE WineLicense_It; */
+/* extern LICENSE WineLicense_Ko; */
+/* extern LICENSE WineLicense_No; */
+/* extern LICENSE WineLicense_Pl; */
+/* extern LICENSE WineLicense_Po; */
+/* extern LICENSE WineLicense_Va; */
+
diff --git a/programs/notepad/notepad.rc b/programs/notepad/notepad.rc
new file mode 100644
index 0000000..0079af5
--- /dev/null
+++ b/programs/notepad/notepad.rc
@@ -0,0 +1,58 @@
+/*
+ * Notepad (notepad.rc)
+ *
+ * Copyright 1997 Marcel Baur <mbaur@g26.ethz.ch>
+ */
+
+#define CONCAT(a, b) a##b
+
+/* Main Menu */
+
+CONCAT(MENU_, LANGUAGE_ID) MENU
+{
+ POPUP MENU_FILE {
+ MENUITEM MENU_FILE_NEW, NP_NEW
+ MENUITEM MENU_FILE_OPEN, NP_OPEN
+ MENUITEM MENU_FILE_SAVE, NP_SAVE
+ MENUITEM MENU_FILE_SAVEAS, NP_SAVEAS
+ MENUITEM MENU_FILE_PRINT, NP_PRINT
+ MENUITEM MENU_FILE_PAGESETUP, NP_PAGESETUP
+ MENUITEM MENU_FILE_PRINTSETUP, NP_PRINTSETUP
+ MENUITEM SEPARATOR
+ MENUITEM MENU_FILE_EXIT, NP_EXIT
+ }
+ POPUP MENU_EDIT {
+ MENUITEM MENU_EDIT_UNDO, NP_EDIT_UNDO
+ MENUITEM SEPARATOR
+ MENUITEM MENU_EDIT_CUT, NP_EDIT_CUT, GRAYED
+ MENUITEM MENU_EDIT_COPY, NP_EDIT_COPY, GRAYED
+ MENUITEM MENU_EDIT_PASTE, NP_EDIT_PASTE, GRAYED
+ MENUITEM MENU_EDIT_DELETE, NP_EDIT_DELETE, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM MENU_EDIT_SELECTALL, NP_EDIT_SELECTALL
+ MENUITEM MENU_EDIT_TIMEDATE, NP_EDIT_TIMEDATE
+ MENUITEM SEPARATOR
+ MENUITEM MENU_EDIT_WRAP, NP_EDIT_WRAP
+ }
+ POPUP MENU_SEARCH {
+ MENUITEM MENU_SEARCH_SEARCH, NP_SEARCH_SEARCH
+ MENUITEM MENU_SEARCH_NEXT, NP_SEARCH_NEXT
+ }
+ POPUP MENU_LANGUAGE {
+ /* Dummy item, will be removed */
+ MENUITEM SEPARATOR
+ }
+ POPUP MENU_HELP {
+ MENUITEM MENU_HELP_CONTENTS, PM_CONTENTS
+ MENUITEM MENU_HELP_SEARCH, PM_SEARCH
+ MENUITEM MENU_HELP_HELP_ON_HELP, PM_HELPONHELP
+ MENUITEM SEPARATOR
+
+ POPUP MENU_INFO {
+ MENUITEM MENU_INFO_LICENSE, PM_LICENSE
+ MENUITEM MENU_INFO_NO_WARRANTY, PM_NO_WARRANTY
+ MENUITEM MENU_INFO_ABOUT_WINE, PM_ABOUT_WINE
+ }
+}
+}
+
diff --git a/rc/winerc.c b/rc/winerc.c
index ea8aa65..058343b 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -8,7 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
diff --git a/relay32/Makefile.in b/relay32/Makefile.in
new file mode 100644
index 0000000..74603e6
--- /dev/null
+++ b/relay32/Makefile.in
@@ -0,0 +1,63 @@
+DEFS = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = relay32
+
+DLLS = \
+ advapi32.spec \
+ comctl32.spec \
+ comdlg32.spec \
+ crtdll.spec \
+ dciman32.spec \
+ gdi32.spec \
+ kernel32.spec \
+ lz32.spec \
+ mpr.spec \
+ msvfw32.spec \
+ ntdll.spec \
+ ole32.spec \
+ olecli32.spec \
+ olesvr32.spec \
+ shell32.spec \
+ tapi32.spec \
+ user32.spec \
+ version.spec \
+ w32skrnl.spec \
+ winmm.spec \
+ winspool.spec \
+ wow32.spec \
+ wsock32.spec
+
+C_SRCS = \
+ builtin32.c \
+ relay386.c
+
+SPEC_FILES = $(DLLS:.spec=.c)
+
+EXTRA_OBJS = $(DLLS:.spec=.o)
+
+GEN_ASM_SRCS = \
+ call32.s
+
+.SUFFIXES: .spec
+
+.spec.c:
+ $(BUILD) -o $@ -spec $<
+
+all: checkbuild $(MODULE).o
+
+@MAKE_RULES@
+
+$(SPEC_FILES): $(BUILD)
+
+$(EXTRA_OBJS): $(TOPSRCDIR)/include/builtin32.h
+
+call32.s: $(BUILD)
+ $(BUILD) -o $@ -call32
+
+clean::
+ $(RM) $(SPEC_FILES)
+
+### Dependencies:
diff --git a/if1632/advapi32.spec b/relay32/advapi32.spec
similarity index 100%
rename from if1632/advapi32.spec
rename to relay32/advapi32.spec
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
new file mode 100644
index 0000000..8bdf3eb
--- /dev/null
+++ b/relay32/builtin32.c
@@ -0,0 +1,379 @@
+/*
+ * Win32 builtin functions
+ *
+ * Copyright 1997 Alexandre Julliard
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "builtin32.h"
+#include "module.h"
+#include "task.h"
+#include "process.h"
+#include "stddebug.h"
+#include "debug.h"
+
+typedef struct
+{
+ BYTE call; /* 0xe8 call callfrom32 (relative) */
+ DWORD callfrom32 WINE_PACKED; /* RELAY_CallFrom32 relative addr */
+ BYTE ret; /* 0xc2 ret $n or 0xc3 ret */
+ WORD args; /* nb of args to remove from the stack */
+} DEBUG_ENTRY_POINT;
+
+typedef struct
+{
+ BYTE pushl; /* 0x68 pushl $func_to_call */
+ DWORD func WINE_PACKED; /* func to call */
+ BYTE jmp; /* 0xe9 jmp CALL32_Regs (relative) */
+ DWORD call32_regs WINE_PACKED; /* CALL32_Regs relative addr */
+ WORD nop; /* 0x9090 nop;nop */
+} REG_ENTRY_POINT;
+
+typedef struct
+{
+ const BUILTIN32_DESCRIPTOR *descr; /* DLL descriptor */
+ DEBUG_ENTRY_POINT *dbg_funcs; /* Relay debugging functions table*/
+ BOOL32 used; /* Used by default */
+} BUILTIN32_DLL;
+
+
+extern const BUILTIN32_DESCRIPTOR ADVAPI32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR COMCTL32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR COMDLG32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR CRTDLL_Descriptor;
+extern const BUILTIN32_DESCRIPTOR DCIMAN32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR GDI32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR KERNEL32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR LZ32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR MPR_Descriptor;
+extern const BUILTIN32_DESCRIPTOR MSVFW32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR NTDLL_Descriptor;
+extern const BUILTIN32_DESCRIPTOR OLE32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR OLECLI32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR OLESVR32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR SHELL32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR TAPI32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR USER32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR VERSION_Descriptor;
+extern const BUILTIN32_DESCRIPTOR W32SKRNL_Descriptor;
+extern const BUILTIN32_DESCRIPTOR WINMM_Descriptor;
+extern const BUILTIN32_DESCRIPTOR WINSPOOL_Descriptor;
+extern const BUILTIN32_DESCRIPTOR WOW32_Descriptor;
+extern const BUILTIN32_DESCRIPTOR WSOCK32_Descriptor;
+
+static BUILTIN32_DLL BuiltinDLLs[] =
+{
+ { &ADVAPI32_Descriptor, NULL, TRUE },
+ { &COMCTL32_Descriptor, NULL, FALSE },
+ { &COMDLG32_Descriptor, NULL, TRUE },
+ { &CRTDLL_Descriptor, NULL, TRUE },
+ { &DCIMAN32_Descriptor, NULL, TRUE },
+ { &GDI32_Descriptor, NULL, TRUE },
+ { &KERNEL32_Descriptor, NULL, TRUE },
+ { &LZ32_Descriptor, NULL, TRUE },
+ { &MPR_Descriptor, NULL, TRUE },
+ { &MSVFW32_Descriptor, NULL, TRUE },
+ { &NTDLL_Descriptor, NULL, TRUE },
+ { &OLE32_Descriptor, NULL, FALSE },
+ { &OLECLI32_Descriptor, NULL, FALSE },
+ { &OLESVR32_Descriptor, NULL, FALSE },
+ { &SHELL32_Descriptor, NULL, TRUE },
+ { &TAPI32_Descriptor, NULL, TRUE },
+ { &USER32_Descriptor, NULL, TRUE },
+ { &VERSION_Descriptor, NULL, TRUE },
+ { &W32SKRNL_Descriptor, NULL, TRUE },
+ { &WINMM_Descriptor, NULL, TRUE },
+ { &WINSPOOL_Descriptor, NULL, TRUE },
+ { &WOW32_Descriptor, NULL, TRUE },
+ { &WSOCK32_Descriptor, NULL, TRUE },
+ /* Last entry */
+ { NULL, NULL, FALSE }
+};
+
+
+/***********************************************************************
+ * BUILTIN32_DoLoadModule
+ *
+ * Load a built-in Win32 module. Helper function for BUILTIN32_LoadModule.
+ */
+static HMODULE32 BUILTIN32_DoLoadModule( BUILTIN32_DLL *dll )
+{
+ extern void RELAY_CallFrom32();
+ extern void CALL32_Regs();
+
+ HMODULE16 hModule;
+ NE_MODULE *pModule;
+ OFSTRUCT ofs;
+ IMAGE_DATA_DIRECTORY *dir;
+ IMAGE_DOS_HEADER *dos;
+ IMAGE_NT_HEADERS *nt;
+ IMAGE_SECTION_HEADER *sec;
+ IMAGE_EXPORT_DIRECTORY *exp;
+ LPVOID *funcs;
+ LPSTR *names;
+ DEBUG_ENTRY_POINT *debug;
+ REG_ENTRY_POINT *regs;
+ PE_MODREF *pem;
+ INT32 i, size;
+ BYTE *addr;
+
+ /* Allocate the module */
+
+ size = (sizeof(IMAGE_DOS_HEADER)
+ + sizeof(IMAGE_NT_HEADERS)
+ + 2 * sizeof(IMAGE_SECTION_HEADER)
+ + sizeof(IMAGE_EXPORT_DIRECTORY)
+ + dll->descr->nb_funcs * sizeof(LPVOID)
+ + dll->descr->nb_names * sizeof(LPSTR)
+ + dll->descr->nb_reg_funcs * sizeof(REG_ENTRY_POINT));
+#ifdef __i386__
+ if (debugging_relay)
+ size += dll->descr->nb_funcs * sizeof(DEBUG_ENTRY_POINT);
+#endif
+ addr = VirtualAlloc( NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+ if (!addr) return 0;
+ dos = (IMAGE_DOS_HEADER *)addr;
+ nt = (IMAGE_NT_HEADERS *)(dos + 1);
+ sec = (IMAGE_SECTION_HEADER *)(nt + 1);
+ exp = (IMAGE_EXPORT_DIRECTORY *)(sec + 2);
+ funcs = (LPVOID *)(exp + 1);
+ names = (LPSTR *)(funcs + dll->descr->nb_funcs);
+ regs = (REG_ENTRY_POINT *)(names + dll->descr->nb_names);
+ debug = (DEBUG_ENTRY_POINT *)(regs + dll->descr->nb_reg_funcs);
+
+ /* Build the DOS and NT headers */
+
+ dos->e_magic = IMAGE_DOS_SIGNATURE;
+ dos->e_lfanew = sizeof(*dos);
+
+ nt->Signature = IMAGE_NT_SIGNATURE;
+ nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
+ nt->FileHeader.NumberOfSections = 2; /* exports + code */
+ nt->FileHeader.SizeOfOptionalHeader = sizeof(nt->OptionalHeader);
+ nt->FileHeader.Characteristics = IMAGE_FILE_DLL;
+
+ nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
+ nt->OptionalHeader.SizeOfCode = 0x1000;
+ nt->OptionalHeader.SizeOfInitializedData = 0;
+ nt->OptionalHeader.SizeOfUninitializedData = 0;
+ nt->OptionalHeader.ImageBase = (DWORD)addr;
+ nt->OptionalHeader.SectionAlignment = 0x1000;
+ nt->OptionalHeader.FileAlignment = 0x1000;
+ nt->OptionalHeader.MajorOperatingSystemVersion = 1;
+ nt->OptionalHeader.MinorOperatingSystemVersion = 0;
+ nt->OptionalHeader.MajorSubsystemVersion = 4;
+ nt->OptionalHeader.MinorSubsystemVersion = 0;
+ nt->OptionalHeader.SizeOfImage = size;
+ nt->OptionalHeader.SizeOfHeaders = (BYTE *)exp - addr;
+ nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
+
+ /* Build the export directory */
+
+ dir = &nt->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
+ dir->VirtualAddress = (BYTE *)exp - addr;
+ dir->Size = sizeof(*exp)
+ + dll->descr->nb_funcs * sizeof(LPVOID)
+ + dll->descr->nb_names * sizeof(LPSTR);
+
+ /* Build the exports section */
+
+ strcpy( sec->Name, ".edata" );
+ sec->Misc.VirtualSize = dir->Size;
+ sec->VirtualAddress = (BYTE *)exp - addr;
+ sec->SizeOfRawData = dir->Size;
+ sec->PointerToRawData = (BYTE *)exp - addr;
+ sec->Characteristics = (IMAGE_SCN_CNT_INITIALIZED_DATA |
+ IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
+ IMAGE_SCN_MEM_WRITE);
+
+ /* Build the code section */
+
+ sec++;
+ strcpy( sec->Name, ".code" );
+ sec->SizeOfRawData = dll->descr->nb_reg_funcs * sizeof(REG_ENTRY_POINT);
+#ifdef __i386__
+ if (debugging_relay)
+ sec->SizeOfRawData += dll->descr->nb_funcs * sizeof(DEBUG_ENTRY_POINT);
+#endif
+ sec->Misc.VirtualSize = sec->SizeOfRawData;
+ sec->VirtualAddress = (BYTE *)regs - addr;
+ sec->PointerToRawData = (BYTE *)regs - addr;
+ sec->Characteristics = (IMAGE_SCN_CNT_INITIALIZED_DATA |
+ IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ);
+
+ /* Build the exports section data */
+
+ exp->Name = (BYTE *)dll->descr->name - addr; /*??*/
+ exp->Base = dll->descr->base;
+ exp->NumberOfFunctions = dll->descr->nb_funcs;
+ exp->NumberOfNames = dll->descr->nb_names;
+ exp->AddressOfFunctions = (LPDWORD *)((BYTE *)funcs - addr);
+ exp->AddressOfNames = (LPDWORD *)((BYTE *)names - addr);
+ exp->AddressOfNameOrdinals = (LPWORD *)((BYTE *)dll->descr->ordinals - addr);
+
+ /* Build the funcs table */
+
+ if (debugging_relay) dll->dbg_funcs = debug;
+ for (i = 0; i < dll->descr->nb_funcs; i++, funcs++, debug++)
+ {
+ BYTE args = dll->descr->args[i];
+ if (!dll->descr->functions[i]) continue;
+#ifdef __i386__
+ switch(args)
+ {
+ case 0xfe: /* register func */
+ regs->pushl = 0x68;
+ regs->func = (DWORD)dll->descr->functions[i];
+ regs->jmp = 0xe9;
+ regs->call32_regs = (DWORD)CALL32_Regs - (DWORD)®s->nop;
+ regs->nop = 0x9090;
+ if (debugging_relay)
+ {
+ debug->call = 0xe8;
+ debug->callfrom32 = (DWORD)regs - (DWORD)&debug->ret;
+ debug->ret = 0x90; /* nop */
+ debug->args = 0;
+ *funcs = (LPVOID)((BYTE *)debug - addr);
+ }
+ else *funcs = (LPVOID)((BYTE *)regs - addr);
+ regs++;
+ break;
+ case 0xff: /* stub or extern */
+ *funcs = (LPVOID)((BYTE *)dll->descr->functions[i] - addr);
+ break;
+ default: /* normal function (stdcall or cdecl) */
+ if (debugging_relay)
+ {
+ debug->call = 0xe8;
+ debug->callfrom32 = (DWORD)RELAY_CallFrom32 -
+ (DWORD)&debug->ret;
+ debug->ret = (args & 0x80) ? 0xc3 : 0xc2; /*ret/ret $n*/
+ debug->args = (args & 0x7f) * sizeof(int);
+ *funcs = (LPVOID)((BYTE *)debug - addr);
+ }
+ else
+ *funcs = (LPVOID)((BYTE *)dll->descr->functions[i] - addr);
+ break;
+ }
+#else /* __i386__ */
+ *funcs = (LPVOID)((BYTE *)dll->descr->functions[i] - addr);
+#endif /* __i386__ */
+ }
+
+ /* Build the names table */
+
+ for (i = 0; i < exp->NumberOfNames; i++, names++)
+ if (dll->descr->names[i])
+ *names = (LPSTR)((BYTE *)dll->descr->names[i] - addr);
+
+ /* Create a modref */
+
+ pem = (PE_MODREF *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(*pem) );
+ pem->module = (HMODULE32)addr;
+ pem->pe_export = exp;
+ pem->next = pCurrentProcess->modref_list;
+ pCurrentProcess->modref_list = pem;
+
+ /* Create a Win16 dummy module */
+
+ sprintf( ofs.szPathName, "%s.DLL", dll->descr->name );
+ hModule = MODULE_CreateDummyModule( &ofs );
+ pModule = (NE_MODULE *)GlobalLock16( hModule );
+ pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN |
+ NE_FFLAGS_LIBMODULE | NE_FFLAGS_WIN32;
+ pModule->module32 = (HMODULE32)addr;
+ return pModule->module32;
+}
+
+
+/***********************************************************************
+ * BUILTIN32_LoadModule
+ *
+ * Load a built-in module. If the 'force' parameter is FALSE, we only
+ * load the module if it has not been disabled via the -dll option.
+ */
+HMODULE32 BUILTIN32_LoadModule( LPCSTR name, BOOL32 force )
+{
+ BUILTIN32_DLL *table;
+ char dllname[16], *p;
+
+ /* Fix the name in case we have a full path and extension */
+
+ if ((p = strrchr( name, '\\' ))) name = p + 1;
+ lstrcpyn32A( dllname, name, sizeof(dllname) );
+ if ((p = strrchr( dllname, '.' ))) *p = '\0';
+
+ for (table = BuiltinDLLs; table->descr; table++)
+ if (!lstrcmpi32A( table->descr->name, dllname )) break;
+ if (!table->descr) return 0;
+ if (!table->used && !force) return 0;
+
+ return BUILTIN32_DoLoadModule( table );
+}
+
+
+/***********************************************************************
+ * BUILTIN32_GetEntryPoint
+ *
+ * Return the name of the DLL entry point corresponding
+ * to a relay entry point address. This is used only by relay debugging.
+ *
+ * This function _must_ return the real entry point to call
+ * after the debug info is printed.
+ */
+ENTRYPOINT32 BUILTIN32_GetEntryPoint( char *buffer, void *relay,
+ unsigned int *typemask )
+{
+ BUILTIN32_DLL *dll;
+ int ordinal, i;
+
+ /* First find the module */
+
+ for (dll = BuiltinDLLs; dll->descr; dll++)
+ if (((void *)dll->dbg_funcs <= relay) &&
+ ((void *)(dll->dbg_funcs + dll->descr->nb_funcs) > relay))
+ break;
+ assert(dll->descr);
+
+ /* Now find the function */
+
+ ordinal = ((DWORD)relay-(DWORD)dll->dbg_funcs) / sizeof(DEBUG_ENTRY_POINT);
+ for (i = 0; i < dll->descr->nb_names; i++)
+ if (dll->descr->ordinals[i] == ordinal) break;
+ assert( i < dll->descr->nb_names );
+
+ sprintf( buffer, "%s.%d: %s", dll->descr->name, ordinal + dll->descr->base,
+ dll->descr->names[i] );
+ *typemask = dll->descr->argtypes[ordinal];
+ return dll->descr->functions[ordinal];
+}
+
+
+/***********************************************************************
+ * BUILTIN32_Unimplemented
+ *
+ * This function is called for unimplemented 32-bit entry points (declared
+ * as 'stub' in the spec file).
+ */
+void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR *descr, int ordinal )
+{
+ const char *func_name = "???";
+ int i;
+
+ __RESTORE_ES; /* Just in case */
+
+ for (i = 0; i < descr->nb_names; i++)
+ if (descr->ordinals[i] + descr->base == ordinal) break;
+ if (i < descr->nb_names) func_name = descr->names[i];
+
+ fprintf( stderr, "No handler for Win32 routine %s.%d: %s",
+ descr->name, ordinal, func_name );
+#ifdef __GNUC__
+ fprintf( stderr, " (called from %p)", __builtin_return_address(1) );
+#endif
+ fprintf( stderr, "\n" );
+ TASK_KillCurrentTask(1);
+}
diff --git a/if1632/comctl32.spec b/relay32/comctl32.spec
similarity index 100%
rename from if1632/comctl32.spec
rename to relay32/comctl32.spec
diff --git a/if1632/comdlg32.spec b/relay32/comdlg32.spec
similarity index 100%
rename from if1632/comdlg32.spec
rename to relay32/comdlg32.spec
diff --git a/if1632/crtdll.spec b/relay32/crtdll.spec
similarity index 99%
rename from if1632/crtdll.spec
rename to relay32/crtdll.spec
index 91b4e2d..a41af77 100644
--- a/if1632/crtdll.spec
+++ b/relay32/crtdll.spec
@@ -427,7 +427,7 @@
423 cdecl localtime(ptr) localtime
424 cdecl log(double) log
425 cdecl log10(double) log10
-426 stub longjmp
+426 cdecl longjmp(ptr long) CRTDLL_longjmp
427 cdecl malloc(ptr) CRTDLL_malloc
428 cdecl mblen(ptr long) CRTDLL_mblen
429 cdecl mbstowcs(ptr ptr long) CRTDLL_mbstowcs
diff --git a/relay32/dciman32.spec b/relay32/dciman32.spec
new file mode 100644
index 0000000..c7d10bc
--- /dev/null
+++ b/relay32/dciman32.spec
@@ -0,0 +1,25 @@
+name dciman32
+type win32
+
+ 1 stub DCIBeginAccess
+ 2 stub DCICloseProvider
+ 3 stub DCICreateOffscreen
+ 4 stub DCICreateOverlay
+ 5 stub DCICreatePrimary
+ 6 stub DCIDestroy
+ 7 stub DCIDraw
+ 8 stub DCIEndAccess
+ 9 stub DCIEnum
+ 10 stub DCIOpenProvider
+ 11 stub DCISetClipList
+ 12 stub DCISetDestination
+ 13 stub DCISetSrcDestClip
+ 14 stub DllEntryPoint
+ 15 stub GetDCRegionData
+ 16 stub GetWindowRegionData
+ 17 stub WinWatchClose
+ 18 stub WinWatchDidStatusChange
+ 19 stub WinWatchGetClipList
+ 20 stub WinWatchNotify
+ 21 stub WinWatchOpen
+ 22 stub dcithk_ThunkData32
diff --git a/if1632/gdi32.spec b/relay32/gdi32.spec
similarity index 96%
rename from if1632/gdi32.spec
rename to relay32/gdi32.spec
index 686cfcf..e068279 100644
--- a/if1632/gdi32.spec
+++ b/relay32/gdi32.spec
@@ -2,7 +2,7 @@
type win32
0 stub AbortDoc
- 1 stub AbortPath
+ 1 stdcall AbortPath(long) AbortPath32
2 stdcall AddFontResourceA(str) AddFontResource32A
3 stub AddFontResourceTracking
4 stdcall AddFontResourceW(wstr) AddFontResource32W
@@ -10,14 +10,14 @@
6 stdcall AnimatePalette(long long long ptr) AnimatePalette32
7 stdcall Arc(long long long long long long long long long) Arc32
8 stub ArcTo
- 9 stub BeginPath
+ 9 stdcall BeginPath(long) BeginPath32
10 stdcall BitBlt(long long long long long long long long long) BitBlt32
11 stub CancelDC
12 stub CheckColorsInGamut
13 stub ChoosePixelFormat
14 stdcall Chord(long long long long long long long long long) Chord32
15 stub CloseEnhMetaFile
- 16 stub CloseFigure
+ 16 stdcall CloseFigure(long) CloseFigure32
17 stub CloseMetaFile
18 stub ColorMatchToTarget
19 stdcall CombineRgn(long long long long) CombineRgn32
@@ -50,7 +50,7 @@
45 stdcall CreateFontIndirectW(ptr) CreateFontIndirect32W
46 stdcall CreateFontW(long long long long long long long long
long long long long long wstr) CreateFont32W
- 47 stub CreateHalftonePalette
+ 47 stdcall CreateHalftonePalette(long) CreateHalftonePalette
48 stdcall CreateHatchBrush(long long) CreateHatchBrush32
49 stdcall CreateICA(str str str ptr) CreateIC32A
50 stdcall CreateICW(wstr wstr wstr ptr) CreateIC32W
@@ -82,7 +82,7 @@
75 stdcall Ellipse(long long long long long) Ellipse32
76 stub EndDoc
77 stub EndPage
- 78 stub EndPath
+ 78 stdcall EndPath(long) EndPath32
79 stub EnumEnhMetaFile
80 stdcall EnumFontFamiliesA(long str ptr long) EnumFontFamilies32A
81 stdcall EnumFontFamiliesExA(long str ptr long long) EnumFontFamiliesEx32A
@@ -97,16 +97,16 @@
90 stdcall EqualRgn(long long) EqualRgn32
91 stdcall Escape(long long long ptr ptr) Escape32
92 stdcall ExcludeClipRect(long long long long long) ExcludeClipRect32
- 93 stub ExtCreatePen
+ 93 stdcall ExtCreatePen(long long ptr long ptr) ExtCreatePen32
94 stub ExtCreateRegion
95 stdcall ExtEscape(long long long ptr long ptr) ExtEscape32
96 stdcall ExtFloodFill(long long long long long) ExtFloodFill32
97 stub ExtSelectClipRgn
98 stdcall ExtTextOutA(long long long long ptr str long ptr) ExtTextOut32A
99 stdcall ExtTextOutW(long long long long ptr wstr long ptr) ExtTextOut32W
-100 stub FillPath
+100 stdcall FillPath(long) FillPath32
101 stdcall FillRgn(long long long) FillRgn32
-102 stub FixBrushOrgEx
+102 stdcall FixBrushOrgEx(long long long ptr) FixBrushOrgEx
103 stub FlattenPath
104 stdcall FloodFill(long long long long) FloodFill32
105 stdcall FrameRgn(long long long long long) FrameRgn32
@@ -170,7 +170,7 @@
163 stdcall GetClipRgn(long long) GetClipRgn32
164 stub GetColorAdjustment
165 stub GetColorSpace
-166 stub GetCurrentObject
+166 stdcall GetCurrentObject(long long) GetCurrentObject
167 stdcall GetCurrentPositionEx(long ptr) GetCurrentPositionEx32
168 stdcall GetDCOrgEx(long ptr) GetDCOrgEx
169 stdcall GetDIBColorTable(long long long ptr) GetDIBColorTable32
@@ -214,7 +214,7 @@
207 stub GetOutlineTextMetricsA
208 stub GetOutlineTextMetricsW
209 stdcall GetPaletteEntries(long long long ptr) GetPaletteEntries32
-210 stub GetPath
+210 stdcall GetPath(long ptr ptr long) GetPath32
211 stdcall GetPixel(long long long) GetPixel32
212 stub GetPixelFormat
213 stdcall GetPolyFillMode(long) GetPolyFillMode32
@@ -265,7 +265,7 @@
258 stdcall OffsetWindowOrgEx(long long long ptr) OffsetWindowOrgEx32
259 stdcall PaintRgn(long long) PaintRgn32
260 stdcall PatBlt(long long long long long long) PatBlt32
-261 stub PathToRegion
+261 stdcall PathToRegion(long) PathToRegion32
262 stdcall Pie(long long long long long long long long long) Pie32
263 stub PlayEnhMetaFile
264 stub PlayEnhMetaFileRecord
@@ -300,7 +300,7 @@
293 stdcall ScaleViewportExtEx(long long long long long ptr) ScaleViewportExtEx32
294 stdcall ScaleWindowExtEx(long long long long long ptr) ScaleWindowExtEx32
295 stub SelectBrushLocal
-296 stub SelectClipPath
+296 stdcall SelectClipPath(long long) SelectClipPath32
297 stdcall SelectClipRgn(long long) SelectClipRgn32
298 stub SelectFontLocal
299 stdcall SelectObject(long long) SelectObject32
diff --git a/if1632/kernel32.spec b/relay32/kernel32.spec
similarity index 97%
rename from if1632/kernel32.spec
rename to relay32/kernel32.spec
index 4de6ca3..7dde6b4 100644
--- a/if1632/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -169,7 +169,7 @@
178 stdcall CreateThread(ptr long ptr long long ptr) CreateThread
179 stub CreateToolhelp32Snapshot
180 stub DebugActiveProcess
-181 register DebugBreak() DebugBreak32
+181 stub DebugBreak
182 stub DefineDosDeviceA
183 stub DefineDosDeviceW
184 stdcall DeleteAtom(long) DeleteAtom32
@@ -236,11 +236,11 @@
245 stdcall FindAtomW(wstr) FindAtom32W
247 stub FindCloseChangeNotification
246 stdcall FindClose(long) FindClose32
-248 stub FindFirstChangeNotificationA
+248 stdcall FindFirstChangeNotificationA(str long long) FindFirstChangeNotification32A
249 stub FindFirstChangeNotificationW
250 stdcall FindFirstFileA(str ptr) FindFirstFile32A
251 stdcall FindFirstFileW(wstr ptr) FindFirstFile32W
-252 stub FindNextChangeNotification
+252 stdcall FindNextChangeNotification(long) FindNextChangeNotification
253 stdcall FindNextFileA(long ptr) FindNextFile32A
254 stdcall FindNextFileW(long ptr) FindNextFile32W
255 stdcall FindResourceA(long str str) FindResource32A
@@ -284,7 +284,7 @@
293 stdcall GetComputerNameA(ptr ptr) GetComputerName32A
294 stdcall GetComputerNameW(ptr ptr) GetComputerName32W
295 stdcall GetConsoleCP() GetConsoleCP
-296 stub GetConsoleCursorInfo
+296 stdcall GetConsoleCursorInfo(long ptr) GetConsoleCursorInfo32
297 stdcall GetConsoleMode(long ptr) GetConsoleMode
298 stdcall GetConsoleOutputCP() GetConsoleOutputCP
299 stdcall GetConsoleScreenBufferInfo(long ptr) GetConsoleScreenBufferInfo
@@ -346,7 +346,7 @@
355 stub GetNumberFormatA
356 stub GetNumberFormatW
357 stdcall GetNumberOfConsoleInputEvents(long ptr) GetNumberOfConsoleInputEvents
-358 stub GetNumberOfConsoleMouseButtons
+358 stdcall GetNumberOfConsoleMouseButtons(long ptr) GetNumberOfConsoleMouseButtons
359 stdcall GetOEMCP() GetOEMCP
360 stub GetOverlappedResult
361 stdcall GetPriorityClass(long) GetPriorityClass
@@ -538,8 +538,8 @@
547 stub OpenVxDHandle
548 stdcall OutputDebugStringA(str) OutputDebugString32A
549 stdcall OutputDebugStringW(wstr) OutputDebugString32W
-550 stub PeekConsoleInputA
-551 stub PeekConsoleInputW
+550 stdcall PeekConsoleInputA(ptr ptr long ptr) PeekConsoleInput32A
+551 stdcall PeekConsoleInputW(ptr ptr long ptr) PeekConsoleInput32W
552 stub PeekNamedPipe
553 stub PostQueuedCompletionStatus
554 stub PrepareTape
@@ -590,7 +590,7 @@
599 register SMapLS_IP_EBP_36() SMapLS_IP_EBP_36
600 register SMapLS_IP_EBP_40() SMapLS_IP_EBP_40
601 register SMapLS_IP_EBP_8() SMapLS_IP_EBP_8
-602 stub SUnMapLS
+602 register SUnMapLS() SUnMapLS
603 register SUnMapLS_IP_EBP_12() SUnMapLS_IP_EBP_12
604 register SUnMapLS_IP_EBP_16() SUnMapLS_IP_EBP_16
605 register SUnMapLS_IP_EBP_20() SUnMapLS_IP_EBP_20
@@ -614,7 +614,7 @@
623 stub SetConsoleActiveScreenBuffer
624 stub SetConsoleCP
625 stdcall SetConsoleCtrlHandler(ptr long) SetConsoleCtrlHandler
-626 stub SetConsoleCursorInfo
+626 stdcall SetConsoleCursorInfo(long ptr) SetConsoleCursorInfo32
627 stdcall SetConsoleCursorPosition(long long) SetConsoleCursorPosition
628 stdcall SetConsoleMode(long long) SetConsoleMode
629 stub SetConsoleOutputCP
@@ -728,7 +728,7 @@
737 stdcall WriteConsoleW(long ptr long ptr ptr) WriteConsole32W
738 stdcall WriteFile(long ptr long ptr ptr) WriteFile
739 stub WriteFileEx
-740 stub WritePrivateProfileSectionA
+740 stdcall WritePrivateProfileSectionA(str str str) WritePrivateProfileSection32A
741 stub WritePrivateProfileSectionW
742 stdcall WritePrivateProfileStringA(str str str str) WritePrivateProfileString32A
743 stdcall WritePrivateProfileStringW(wstr wstr wstr wstr) WritePrivateProfileString32W
@@ -860,15 +860,15 @@
868 stub GetConsoleInputExeNameW
869 stub GetConsoleKeyboardLayoutNameA
870 stub GetConsoleKeyboardLayoutNameW
-871 stub GetDiskFreeSpaceExA
-873 stub GetDiskFreeSpaceExW
+871 stdcall GetDiskFreeSpaceExA (str ptr ptr ptr) GetDiskFreeSpaceEx32A
+873 stdcall GetDiskFreeSpaceExW (wstr ptr ptr ptr) GetDiskFreeSpaceEx32W
874 stub GetFileAttributesExA
875 stub GetFileAttributesExW
876 stub GetProcessPriorityBoost
877 stub GetThreadPriorityBoost
878 stub InterlockedCompareExchange
879 stub InterlockedExchangeAdd
-880 stub IsProcessorFeaturePresent
+880 stdcall IsProcessorFeaturePresent(long) IsProcessorFeaturePresent
881 stub OpenWaitableTimerA
882 stub OpenWaitableTimerW
883 stub ReadConsoleInputExA
diff --git a/if1632/lz32.spec b/relay32/lz32.spec
similarity index 100%
rename from if1632/lz32.spec
rename to relay32/lz32.spec
diff --git a/if1632/mpr.spec b/relay32/mpr.spec
similarity index 100%
rename from if1632/mpr.spec
rename to relay32/mpr.spec
diff --git a/relay32/msvfw32.spec b/relay32/msvfw32.spec
new file mode 100644
index 0000000..1f75461
--- /dev/null
+++ b/relay32/msvfw32.spec
@@ -0,0 +1,52 @@
+name msvfw32
+type win32
+
+ 2 stub VideoForWindowsVersion
+ 3 stub DrawDibBegin
+ 4 stub DrawDibChangePalette
+ 5 stub DrawDibClose
+ 6 stub DrawDibDraw
+ 7 stub DrawDibEnd
+ 8 stub DrawDibGetBuffer
+ 9 stub DrawDibGetPalette
+ 10 stub DrawDibOpen
+ 11 stub DrawDibProfileDisplay
+ 12 stub DrawDibRealize
+ 13 stub DrawDibSetPalette
+ 14 stub DrawDibStart
+ 15 stub DrawDibStop
+ 16 stub DrawDibTime
+ 17 stub GetOpenFileNamePreview
+ 18 stub GetOpenFileNamePreviewA
+ 19 stub GetOpenFileNamePreviewW
+ 20 stub GetSaveFileNamePreviewA
+ 21 stub GetSaveFileNamePreviewW
+ 22 stub ICClose
+ 23 stub ICCompress
+ 24 stub ICCompressorChoose
+ 25 stub ICCompressorFree
+ 26 stub ICDecompress
+ 27 stub ICDraw
+ 28 stub ICDrawBegin
+ 29 stub ICGetDisplayFormat
+ 30 stub ICGetInfo
+ 31 stub ICImageCompress
+ 32 stub ICImageDecompress
+ 33 stub ICInfo
+ 34 stub ICInstall
+ 35 stub ICLocate
+ 36 stub ICMThunk32
+ 37 stub ICOpen
+ 38 stub ICOpenFunction
+ 39 stub ICRemove
+ 40 stub ICSendMessage
+ 41 stub ICSeqCompressFrame
+ 42 stub ICSeqCompressFrameEnd
+ 43 stub ICSeqCompressFrameStart
+ 44 stub MCIWndCreate
+ 45 stub MCIWndCreateA
+ 46 stub MCIWndCreateW
+ 47 stub MCIWndRegisterClass
+ 48 stub StretchDIB
+ 49 stub ls_ThunkData32
+ 50 stub sl_ThunkData32
diff --git a/if1632/ntdll.spec b/relay32/ntdll.spec
similarity index 100%
rename from if1632/ntdll.spec
rename to relay32/ntdll.spec
diff --git a/if1632/ole32.spec b/relay32/ole32.spec
similarity index 92%
rename from if1632/ole32.spec
rename to relay32/ole32.spec
index 18cec80..3faa9e5 100644
--- a/if1632/ole32.spec
+++ b/relay32/ole32.spec
@@ -3,12 +3,12 @@
1 stub BindMoniker
2 stub CLSIDFromProgID
- 3 stub CLSIDFromString
- 4 stub CoBuildVersion
+ 3 stdcall CLSIDFromString(str ptr) CLSIDFromString
+ 4 stdcall CoBuildVersion() CoBuildVersion
5 stub CoCreateFreeThreadedMarshaler
6 stub CoCreateGuid
7 stub CoCreateInstance
- 8 stub CoDisconnectObject
+ 8 stdcall CoDisconnectObject(ptr long) CoDisconnectObject
9 stub CoDosDateTimeToFileTime
10 stub CoFileTimeNow
11 stub CoFileTimeToDosDateTime
@@ -20,13 +20,13 @@
17 stub CoGetCurrentLogicalThreadId
18 stub CoGetCurrentProcess
19 stub CoGetInterfaceAndReleaseStream
- 20 stub CoGetMalloc
+ 20 stdcall CoGetMalloc(long ptr) CoGetMalloc
21 stub CoGetMarshalSizeMax
22 stub CoGetPSClsid
23 stub CoGetStandardMarshal
24 stub CoGetState
25 stub CoGetTreatAsClass
- 26 stub CoInitialize
+ 26 stdcall CoInitialize(long) CoInitialize
27 stub CoInitializeWOW
28 stub CoIsHandlerConnected
29 stub CoIsOle1Class
@@ -47,7 +47,7 @@
44 stub CoTaskMemFree
45 stub CoTaskMemRealloc
46 stub CoTreatAsClass
- 47 stub CoUninitialize
+ 47 stdcall CoUninitialize() CoUnitialize
48 stub CoUnloadingWOW
49 stub CoUnmarshalHresult
50 stub CoUnmarshalInterface
@@ -151,7 +151,7 @@
148 stub StgOpenStorage
149 stub StgOpenStorageOnILockBytes
150 stub StgSetTimes
-151 stub StringFromCLSID
+151 stdcall StringFromCLSID(ptr ptr) StringFromCLSID
152 stub StringFromGUID2
153 stub StringFromIID
154 stub UtConvertDvtd16toDvtd32
diff --git a/if1632/olecli32.spec b/relay32/olecli32.spec
similarity index 100%
rename from if1632/olecli32.spec
rename to relay32/olecli32.spec
diff --git a/if1632/olesvr32.spec b/relay32/olesvr32.spec
similarity index 100%
rename from if1632/olesvr32.spec
rename to relay32/olesvr32.spec
diff --git a/relay32/relay386.c b/relay32/relay386.c
new file mode 100644
index 0000000..1531e4a
--- /dev/null
+++ b/relay32/relay386.c
@@ -0,0 +1,203 @@
+/*
+ * 386-specific Win32 relay functions
+ *
+ * Copyright 1997 Alexandre Julliard
+ */
+
+#ifdef __i386__
+
+#include <assert.h>
+#include "winnt.h"
+#include "windows.h"
+#include "builtin32.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+/***********************************************************************
+ * RELAY_CallFrom32
+ *
+ * Stack layout on entry to this function:
+ * ... ...
+ * (esp+12) arg2
+ * (esp+8) arg1
+ * (esp+4) ret_addr
+ * (esp) return addr to relay code
+ */
+int RELAY_CallFrom32( int ret_addr, ... )
+{
+ int i, ret;
+ char buffer[80];
+ FARPROC32 func;
+ unsigned int mask, typemask;
+
+ int *args = &ret_addr;
+ /* Relay addr is the return address for this function */
+ BYTE *relay_addr = (BYTE *)args[-1];
+ WORD nb_args = *(WORD *)(relay_addr + 1) / sizeof(int);
+
+ assert(debugging_relay);
+ func = (FARPROC32)BUILTIN32_GetEntryPoint( buffer, relay_addr - 5,
+ &typemask );
+ printf( "Call %s(", buffer );
+ args++;
+ for (i = 0, mask = 3; i < nb_args; i++, mask <<= 2)
+ {
+ if (i) printf( "," );
+ if ((typemask & mask) && HIWORD(args[i]))
+ {
+ if (typemask & (2<<(2*i)))
+ {
+ char buff[80];
+ lstrcpynWtoA( buff, (LPWSTR)args[i], sizeof(buff) );
+ printf( "%08x L\"%s\"", args[i], buff );
+ }
+ else printf( "%08x \"%s\"", args[i], (char *)args[i] );
+ }
+ else printf( "%08x", args[i] );
+ }
+ printf( ") ret=%08x\n", ret_addr );
+ if (*relay_addr == 0xc3) /* cdecl */
+ {
+ LRESULT (*cfunc)() = (LRESULT(*)())func;
+ switch(nb_args)
+ {
+ case 0: ret = cfunc(); break;
+ case 1: ret = cfunc(args[0]); break;
+ case 2: ret = cfunc(args[0],args[1]); break;
+ case 3: ret = cfunc(args[0],args[1],args[2]); break;
+ case 4: ret = cfunc(args[0],args[1],args[2],args[3]); break;
+ case 5: ret = cfunc(args[0],args[1],args[2],args[3],args[4]); break;
+ case 6: ret = cfunc(args[0],args[1],args[2],args[3],args[4],
+ args[5]); break;
+ case 7: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6]); break;
+ case 8: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7]); break;
+ case 9: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8]); break;
+ case 10: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9]); break;
+ case 11: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10]); break;
+ case 12: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],
+ args[11]); break;
+ case 13: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],args[11],
+ args[12]); break;
+ case 14: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],args[11],
+ args[12],args[13]); break;
+ case 15: ret = cfunc(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],args[11],
+ args[12],args[13],args[14]); break;
+ default:
+ fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
+ nb_args );
+ assert(FALSE);
+ }
+ }
+ else /* stdcall */
+ {
+ switch(nb_args)
+ {
+ case 0: ret = func(); break;
+ case 1: ret = func(args[0]); break;
+ case 2: ret = func(args[0],args[1]); break;
+ case 3: ret = func(args[0],args[1],args[2]); break;
+ case 4: ret = func(args[0],args[1],args[2],args[3]); break;
+ case 5: ret = func(args[0],args[1],args[2],args[3],args[4]); break;
+ case 6: ret = func(args[0],args[1],args[2],args[3],args[4],
+ args[5]); break;
+ case 7: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6]); break;
+ case 8: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7]); break;
+ case 9: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8]); break;
+ case 10: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9]); break;
+ case 11: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10]); break;
+ case 12: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],
+ args[11]); break;
+ case 13: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],args[11],
+ args[12]); break;
+ case 14: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],args[11],
+ args[12],args[13]); break;
+ case 15: ret = func(args[0],args[1],args[2],args[3],args[4],args[5],
+ args[6],args[7],args[8],args[9],args[10],args[11],
+ args[12],args[13],args[14]); break;
+ default:
+ fprintf( stderr, "RELAY_CallFrom32: Unsupported nb args %d\n",
+ nb_args );
+ assert(FALSE);
+ }
+ }
+ printf( "Ret %s() retval=%08x ret=%08x\n", buffer, ret, ret_addr );
+ return ret;
+}
+
+
+/***********************************************************************
+ * RELAY_CallFrom32Regs
+ *
+ * 'stack' points to the relay addr on the stack.
+ * Stack layout:
+ * ... ...
+ * (esp+216) ret_addr
+ * (esp+212) return to relay debugging code (only when debugging_relay)
+ * (esp+208) entry point to call
+ * (esp+4) CONTEXT
+ * (esp) return addr to relay code
+ */
+void RELAY_CallFrom32Regs( CONTEXT context,
+ void (CALLBACK *entry_point)(CONTEXT *),
+ BYTE *relay_addr, int ret_addr )
+{
+ if (!debugging_relay)
+ {
+ /* Simply call the entry point */
+ entry_point( &context );
+ }
+ else
+ {
+ char buffer[80];
+ unsigned int typemask;
+
+ __RESTORE_ES;
+ /* Fixup the context structure because of the extra parameter */
+ /* pushed by the relay debugging code */
+
+ EIP_reg(&context) = ret_addr;
+ ESP_reg(&context) += sizeof(int);
+
+ BUILTIN32_GetEntryPoint( buffer, relay_addr - 5, &typemask );
+ printf("Call %s(regs) ret=%08x\n", buffer, ret_addr );
+ printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
+ EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
+ EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
+ printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+ EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
+ DS_reg(&context), ES_reg(&context), FS_reg(&context),
+ GS_reg(&context), EFL_reg(&context) );
+
+ /* Now call the real function */
+ entry_point( &context );
+
+ printf("Ret %s() retval=regs ret=%08x\n", buffer, ret_addr );
+ printf(" EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx ESI=%08lx EDI=%08lx\n",
+ EAX_reg(&context), EBX_reg(&context), ECX_reg(&context),
+ EDX_reg(&context), ESI_reg(&context), EDI_reg(&context) );
+ printf(" EBP=%08lx ESP=%08lx EIP=%08lx DS=%04lx ES=%04lx FS=%04lx GS=%04lx EFL=%08lx\n",
+ EBP_reg(&context), ESP_reg(&context), EIP_reg(&context),
+ DS_reg(&context), ES_reg(&context), FS_reg(&context),
+ GS_reg(&context), EFL_reg(&context) );
+ }
+}
+
+#endif /* __i386__ */
diff --git a/if1632/shell32.spec b/relay32/shell32.spec
similarity index 90%
rename from if1632/shell32.spec
rename to relay32/shell32.spec
index 9867e60..f31d8a3 100644
--- a/if1632/shell32.spec
+++ b/relay32/shell32.spec
@@ -5,7 +5,7 @@
# (these need to have these exact ordinals, for some win95 dlls
# import shell32.dll by ordinal)
- 2 stub SHELL32_2
+ 2 stdcall SHELL32_2(long long long long long long) SHELL32_2
3 stub CheckEscapesA
4 stub SHELL32_4
5 stub SHELL32_5
@@ -29,10 +29,10 @@
27 stub SHELL32_27
28 stub SHELL32_28
29 stdcall SHELL32_29(str) SHELL32_29
- 30 stub SHELL32_30
- 31 stub SHELL32_31
+ 30 stdcall SHELL32_30(ptr long) SHELL32_30
+ 31 stdcall SHELL32_31(str) SHELL32_31
32 stdcall SHELL32_32(str) SHELL32_32
- 33 stub SHELL32_33
+ 33 stdcall SHELL32_33(str) SHELL32_33
34 stdcall SHELL32_34(str) SHELL32_34
35 stdcall SHELL32_35(str) SHELL32_35
36 stdcall SHELL32_36(str str) SHELL32_36
@@ -55,19 +55,19 @@
53 stub DragQueryFileAorW
54 stub DragQueryFileW
55 stub SHELL32_55
- 56 stub SHELL32_56
+ 56 stdcall SHELL32_56(str) SHELL32_56
57 stub SHELL32_57
- 58 stub SHELL32_58
+ 58 stdcall SHELL32_58(long long long long) SHELL32_58
59 stub SHELL32_59
60 stub SHELL32_60
61 stub SHELL32_61
62 stdcall SHELL32_62(long long long long) SHELL32_62
- 63 stub SHELL32_63
+ 63 stdcall SHELL32_63(long long long long str str str) SHELL32_63
64 stub SHELL32_64
65 stub SHELL32_65
66 stub SHELL32_66
67 stub SHELL32_67
- 68 stub SHELL32_68
+ 68 stdcall SHELL32_68(long long long) SHELL32_68
69 stub SHELL32_69
70 stub SHELL32_70
71 stdcall SHELL32_71(ptr ptr) SHELL32_71
@@ -88,7 +88,7 @@
86 stub SHELL32_86
87 stub SHELL32_87
88 stub SHELL32_88
- 89 stub SHELL32_89
+ 89 stdcall SHELL32_89(long long long) SHELL32_89
90 stub SHELL32_90
91 stub SHELL32_91
92 stub SHELL32_92
@@ -100,7 +100,7 @@
98 stub SHELL32_98
99 stub SHELL32_99
100 stdcall SHELL32_100(long) SHELL32_100
- 101 stub ExtractAssociatedIconExA
+ 101 stdcall ExtractAssociatedIconA(long ptr long) ExtractAssociatedIcon32A
102 stdcall SHELL32_102(ptr ptr long ptr ptr) SHELL32_102
103 stub SHELL32_103
104 stub SHELL32_104
@@ -219,10 +219,10 @@
217 stdcall SHGetFileInfo(ptr long ptr long long) SHGetFileInfo32A
218 stdcall SHGetFileInfoA(ptr long ptr long long) SHGetFileInfo32A
219 stub SHGetInstanceExplorer
- 220 stub SHGetMalloc
- 221 stub SHGetPathFromIDList
+ 220 stdcall SHGetMalloc(ptr) SHGetMalloc
+ 221 stdcall SHGetPathFromIDList(ptr ptr) SHGetPathFromIDList
222 stub SHGetPathFromIDListA
- 223 stub SHGetSpecialFolderLocation
+ 223 stdcall SHGetSpecialFolderLocation(long long ptr) SHGetSpecialFolderLocation
224 stub SHHelpShortcuts_RunDLL
225 stub SHLoadInProc
226 stub SheChangeDirA
@@ -248,8 +248,8 @@
246 stub ShellExecuteEx
247 stub ShellExecuteExA
248 stub ShellExecuteW
- 249 stub Shell_NotifyIcon
- 250 stub Shell_NotifyIconA
+ 249 stdcall Shell_NotifyIcon(long ptr) Shell_NotifyIcon
+ 250 stdcall Shell_NotifyIconA(long ptr) Shell_NotifyIconA
251 stub Shl1632_ThunkData32
252 stub Shl3216_ThunkData32
505 stub SHELL32_505
diff --git a/relay32/tapi32.spec b/relay32/tapi32.spec
new file mode 100644
index 0000000..011d0ab
--- /dev/null
+++ b/relay32/tapi32.spec
@@ -0,0 +1,117 @@
+name tapi32
+type win32
+
+ 1 stub lineAccept
+ 2 stub lineAddProvider
+ 3 stub lineAddToConference
+ 4 stub lineAnswer
+ 5 stub lineBlindTransfer
+ 6 stub lineClose
+ 7 stub lineCompleteCall
+ 8 stub lineCompleteTransfer
+ 9 stub lineConfigDialog
+ 10 stub lineConfigDialogEdit
+ 11 stub lineConfigProvider
+ 12 stub lineDeallocateCall
+ 13 stub lineDevSpecific
+ 14 stub lineDevSpecificFeature
+ 15 stub lineDial
+ 16 stub lineDrop
+ 17 stub lineForward
+ 18 stub lineGatherDigits
+ 19 stub lineGenerateDigits
+ 20 stub lineGenerateTone
+ 21 stub lineGetAddressCaps
+ 22 stub lineGetAddressID
+ 23 stub lineGetAddressStatus
+ 24 stub lineGetAppPriority
+ 25 stub lineGetCallInfo
+ 26 stub lineGetCallStatus
+ 27 stub lineGetConfRelatedCalls
+ 28 stub lineGetCountry
+ 29 stub lineGetDevCaps
+ 30 stub lineGetDevConfig
+ 31 stub lineGetID
+ 32 stub lineGetIcon
+ 33 stub lineGetLineDevStatus
+ 34 stub lineGetNewCalls
+ 35 stub lineGetNumRings
+ 36 stub lineGetProviderList
+ 37 stub lineGetRequest
+ 38 stub lineGetStatusMessages
+ 39 stub lineGetTranslateCaps
+ 40 stub lineHandoff
+ 41 stub lineHold
+ 42 stub lineInitialize
+ 43 stub lineMakeCall
+ 44 stub lineMonitorDigits
+ 45 stub lineMonitorMedia
+ 46 stub lineMonitorTones
+ 47 stub lineNegotiateAPIVersion
+ 48 stub lineNegotiateExtVersion
+ 49 stub lineOpen
+ 50 stub linePark
+ 51 stub linePickup
+ 52 stub linePrepareAddToConference
+ 53 stub lineRedirect
+ 54 stub lineRegisterRequestRecipient
+ 55 stub lineReleaseUserUserInfo
+ 56 stub lineRemoveFromConference
+ 57 stub lineRemoveProvider
+ 58 stub lineSecureCall
+ 59 stub lineSendUserUserInfo
+ 60 stub lineSetAppPriority
+ 61 stub lineSetAppSpecific
+ 62 stub lineSetCallParams
+ 63 stub lineSetCallPrivilege
+ 64 stub lineSetCurrentLocation
+ 65 stub lineSetDevConfig
+ 66 stub lineSetMediaControl
+ 67 stub lineSetMediaMode
+ 68 stub lineSetNumRings
+ 69 stub lineSetStatusMessages
+ 70 stub lineSetTerminal
+ 71 stub lineSetTollList
+ 72 stub lineSetupConference
+ 73 stub lineSetupTransfer
+ 74 stub lineShutdown
+ 75 stub lineSwapHold
+ 76 stub lineTranslateAddress
+ 77 stub lineTranslateDialog
+ 78 stub lineUncompleteCall
+ 79 stub lineUnhold
+ 80 stub lineUnpark
+ 81 stub phoneClose
+ 82 stub phoneConfigDialog
+ 83 stub phoneDevSpecific
+ 84 stub phoneGetButtonInfo
+ 85 stub phoneGetData
+ 86 stub phoneGetDevCaps
+ 87 stub phoneGetDisplay
+ 88 stub phoneGetGain
+ 89 stub phoneGetHookSwitch
+ 90 stub phoneGetID
+ 91 stub phoneGetIcon
+ 92 stub phoneGetLamp
+ 93 stub phoneGetRing
+ 94 stub phoneGetStatus
+ 95 stub phoneGetStatusMessages
+ 96 stub phoneGetVolume
+ 97 stub phoneInitialize
+ 98 stub phoneNegotiateAPIVersion
+ 99 stub phoneNegotiateExtVersion
+100 stub phoneOpen
+101 stub phoneSetButtonInfo
+102 stub phoneSetData
+103 stub phoneSetDisplay
+104 stub phoneSetGain
+105 stub phoneSetHookSwitch
+106 stub phoneSetLamp
+107 stub phoneSetRing
+108 stub phoneSetStatusMessages
+109 stub phoneSetVolume
+110 stub phoneShutdown
+111 stub tapiGetLocationInfo
+112 stub tapiRequestDrop
+113 stub tapiRequestMakeCall
+114 stub tapiRequestMediaCall
diff --git a/if1632/user32.spec b/relay32/user32.spec
similarity index 98%
rename from if1632/user32.spec
rename to relay32/user32.spec
index f0f98be..5c099ba 100644
--- a/if1632/user32.spec
+++ b/relay32/user32.spec
@@ -76,7 +76,7 @@
73 stdcall CreateDialogParamA(long ptr long ptr long) CreateDialogParam32A
74 stdcall CreateDialogParamW(long ptr long ptr long) CreateDialogParam32W
75 stdcall CreateIcon(long long long long long ptr ptr) CreateIcon32
- 76 stub CreateIconFromResource
+ 76 stdcall CreateIconFromResource (ptr long long long) CreateIconFromResource32
77 stdcall CreateIconFromResourceEx(ptr long long long long long long) CreateIconFromResourceEx32
78 stdcall CreateIconIndirect(ptr) CreateIconIndirect
79 stub CreateMDIWindowA
@@ -396,8 +396,8 @@
391 stdcall MessageBoxA(long str str long) MessageBox32A
392 stdcall MessageBoxExA(long str str long long) MessageBoxEx32A
393 stdcall MessageBoxExW(long wstr wstr long long) MessageBoxEx32W
-394 stub MessageBoxIndirectA
-395 stub MessageBoxIndirectW
+394 stdcall MessageBoxIndirectA(ptr) MessageBoxIndirect32A
+395 stdcall MessageBoxIndirectW(ptr) MessageBoxIndirect32W
396 stdcall MessageBoxW(long wstr wstr long) MessageBox32W
397 stdcall ModifyMenuA(long long long long ptr) ModifyMenu32A
398 stdcall ModifyMenuW(long long long long ptr) ModifyMenu32W
@@ -459,8 +459,8 @@
454 stdcall SendMessageA(long long long long) SendMessage32A
455 stub SendMessageCallbackA
456 stub SendMessageCallbackW
-457 stub SendMessageTimeoutA
-458 stub SendMessageTimeoutW
+457 stdcall SendMessageTimeoutA(long long long long ptr ptr) SendMessageTimeout32A
+458 stdcall SendMessageTimeoutW(long long long long ptr ptr) SendMessageTimeout32W
459 stdcall SendMessageW(long long long long) SendMessage32W
460 stub SendNotifyMessageA
461 stub SendNotifyMessageW
@@ -589,8 +589,8 @@
584 stub mouse_event
585 varargs wsprintfA() wsprintf32A
586 varargs wsprintfW() wsprintf32W
-587 stdcall wvsprintfA(str str ptr) wvsprintf32A
-588 stdcall wvsprintfW(wstr wstr ptr) wvsprintf32W
+587 stdcall wvsprintfA(ptr str ptr) wvsprintf32A
+588 stdcall wvsprintfW(ptr wstr ptr) wvsprintf32W
#late additions
589 stub ChangeDisplaySettingsA
590 stub ChangeDisplaySettingsW
diff --git a/if1632/version.spec b/relay32/version.spec
similarity index 100%
rename from if1632/version.spec
rename to relay32/version.spec
diff --git a/if1632/w32skrnl.spec b/relay32/w32skrnl.spec
similarity index 100%
rename from if1632/w32skrnl.spec
rename to relay32/w32skrnl.spec
diff --git a/if1632/winmm.spec b/relay32/winmm.spec
similarity index 90%
rename from if1632/winmm.spec
rename to relay32/winmm.spec
index 3c70167..de1a4e5 100644
--- a/if1632/winmm.spec
+++ b/relay32/winmm.spec
@@ -2,6 +2,8 @@
type win32
1 stdcall PlaySoundA(ptr long long) PlaySound32A
+ 2 stdcall WINMM_2(ptr long long) PlaySound32A
+ 3 stub WINMM_3
4 stub CloseDriver
5 stub DefDriverProc
6 stub DriverCallback
@@ -15,7 +17,7 @@
14 stub GetDriverModuleHandle
15 stdcall OpenDriver(ptr ptr long) OpenDriver
16 stub OpenDriverA
- 17 stub PlaySound
+ 17 stdcall PlaySound(ptr long long) PlaySound32A
18 stdcall PlaySoundW(ptr long long) PlaySound32W
19 stub SendDriverMessage
20 stdcall auxGetDevCapsA(long ptr long) auxGetDevCaps32A
@@ -25,12 +27,12 @@
24 stdcall auxOutMessage(long long long long) auxOutMessage32
25 stdcall auxSetVolume(long long) auxSetVolume32
26 stub joyConfigChanged
- 27 stub joyGetDevCapsA
- 28 stub joyGetDevCapsW
- 29 stub joyGetNumDevs
- 30 stub joyGetPos
+ 27 stdcall joyGetDevCapsA(long ptr long) joyGetDevCaps32A
+ 28 stdcall joyGetDevCapsW(long ptr long) joyGetDevCaps32W
+ 29 stdcall joyGetNumDevs() joyGetNumDevs32
+ 30 stdcall joyGetPos(long ptr) joyGetPos32
31 stub joyGetPosEx
- 32 stub joyGetThreshold
+ 32 stdcall joyGetThreshold(long ptr) joyGetThreshold32
33 stub joyReleaseCapture
34 stub joySetCapture
35 stub joySetThreshold
@@ -47,7 +49,7 @@
46 stdcall mciGetErrorStringW(long ptr long) mciGetErrorString32W
47 stub mciGetYieldProc
48 stub mciLoadCommandResource
- 49 stub mciSendCommandA
+ 49 stdcall mciSendCommandA(long long long long) mciSendCommand32A
50 stub mciSendCommandW
51 stdcall mciSendStringA(ptr ptr long long) mciSendString
52 stub mciSendStringW
@@ -135,13 +137,13 @@
134 stdcall mmsystemGetVersion() mmsystemGetVersion32
135 stdcall sndPlaySoundA(ptr long) sndPlaySound
136 stub sndPlaySoundW
-137 stub timeBeginPeriod
-138 stub timeEndPeriod
-139 stub timeGetDevCaps
-140 stub timeGetSystemTime
+137 stdcall timeBeginPeriod(long) timeBeginPeriod32
+138 stdcall timeEndPeriod(long) timeEndPeriod32
+139 stdcall timeGetDevCaps(ptr long) timeGetDevCaps32
+140 stdcall timeGetSystemTime(ptr long) timeGetSystemTime32
141 stdcall timeGetTime() timeGetTime
-142 stub timeKillEvent
-143 stub timeSetEvent
+142 stdcall timeKillEvent(long) timeKillEvent32
+143 stdcall timeSetEvent(long long ptr long long) timeSetEvent32
144 stdcall waveInAddBuffer(long ptr long) waveInAddBuffer32
145 stdcall waveInClose(long) waveInClose32
146 stdcall waveInGetDevCapsA(long ptr long) waveInGetDevCaps32A
diff --git a/if1632/winspool.spec b/relay32/winspool.spec
similarity index 98%
rename from if1632/winspool.spec
rename to relay32/winspool.spec
index f5bd31a..be7721f 100644
--- a/if1632/winspool.spec
+++ b/relay32/winspool.spec
@@ -96,7 +96,7 @@
193 stub GetPrinterDriverW
194 stub GetPrinterW
195 stub InitializeDll
-196 stub OpenPrinterA
+196 stdcall OpenPrinterA(str ptr ptr) OpenPrinter32A
197 stub OpenPrinterW
198 stub PlayGdiScriptOnPrinterIC
199 stub PrinterMessageBoxA
diff --git a/relay32/wow32.spec b/relay32/wow32.spec
new file mode 100644
index 0000000..2f5b548
--- /dev/null
+++ b/relay32/wow32.spec
@@ -0,0 +1,20 @@
+name wow32
+type win32
+
+# 1
+ 2 stub WOWCallback16
+ 3 stub WOWCallback16Ex
+ 4 stub WOWDirectedYield16
+ 5 stub WOWGetVDMPointer
+ 6 stub WOWGetVDMPointerFix
+ 7 stub WOWGetVDMPointerUnfix
+ 8 stub WOWGlobalAlloc16
+ 9 stub WOWGlobalAllocLock16
+ 10 stub WOWGlobalFree16
+ 11 stub WOWGlobalLock16
+ 12 stub WOWGlobalLockSize16
+ 13 stub WOWGlobalUnlock16
+ 14 stub WOWGlobalUnlockFree16
+ 15 stub WOWHandle16
+ 16 stub WOWHandle32
+ 17 stub WOWYield16
diff --git a/if1632/wsock32.spec b/relay32/wsock32.spec
similarity index 78%
rename from if1632/wsock32.spec
rename to relay32/wsock32.spec
index 829fe95..7dc4def 100644
--- a/if1632/wsock32.spec
+++ b/relay32/wsock32.spec
@@ -10,8 +10,8 @@
007 stdcall getsockopt(long long long ptr ptr) WINSOCK_getsockopt32
008 stdcall htonl(long) WINSOCK_htonl
009 stdcall htons(long) WINSOCK_htons
-010 stdcall inet_addr(ptr) inet_addr
-011 stdcall inet_ntoa(ptr) inet_ntoa
+010 stdcall inet_addr(ptr) WINSOCK_inet_addr
+011 stdcall inet_ntoa(ptr) WINSOCK_inet_ntoa32
012 stdcall ioctlsocket(long long ptr) WINSOCK_ioctlsocket32
013 stdcall listen(long long) WINSOCK_listen32
014 stdcall ntohl(long) WINSOCK_ntohl
@@ -31,14 +31,14 @@
055 stdcall getservbyname(str str) WINSOCK_getservbyname32
056 stdcall getservbyport(long str) WINSOCK_getservbyport32
057 stdcall gethostname(ptr long) WINSOCK_gethostname32
-101 stdcall WSAAsyncSelect(long long long long) WSAAsyncSelect
-102 stub WSAAsyncGetHostByAddr
+101 stdcall WSAAsyncSelect(long long long long) WSAAsyncSelect32
+102 stdcall WSAAsyncGetHostByAddr(long long ptr long long ptr long) WSAAsyncGetHostByAddr32
103 stdcall WSAAsyncGetHostByName(long long ptr ptr long) WSAAsyncGetHostByName32
-104 stub WSAAsyncGetProtoByNumber
-105 stub WSAAsyncGetProtoByName
-106 stub WSAAsyncGetServByPort
-107 stub WSAAsyncGetServByName
-108 stub WSACancelAsyncRequest
+104 stdcall WSAAsyncGetProtoByNumber(long long long ptr long) WSAAsyncGetProtoByNumber32
+105 stdcall WSAAsyncGetProtoByName(long long ptr ptr long) WSAAsyncGetProtoByName32
+106 stdcall WSAAsyncGetServByPort(long long long ptr ptr long) WSAAsyncGetServByPort32
+107 stdcall WSAAsyncGetServByName(long long ptr ptr ptr long) WSAAsyncGetServByName32
+108 stdcall WSACancelAsyncRequest(long) WSACancelAsyncRequest32
109 stdcall WSASetBlockingHook(ptr) WSASetBlockingHook32
110 stdcall WSAUnhookBlockingHook() WSAUnhookBlockingHook32
111 stdcall WSAGetLastError() WSAGetLastError
@@ -52,7 +52,7 @@
# applications *should* 'degrade gracefully if these are not present
# ... as it is, they don't
#1000 stub WSApSetPostRoutine
-1001 stdcall WsControl(long long long long long long) WsControl
+1001 stdcall WsControl(long long ptr ptr ptr ptr) WsControl
1100 stdcall inet_network(ptr) inet_network
1101 stdcall getnetbyname(ptr) getnetbyname
#1102 stub rcmd
@@ -61,7 +61,7 @@
#1105 stub sethostname
#1106 stub dn_expand
1107 stub WSARecvEx
-1108 stub s_perror
+1108 stdcall s_perror(ptr) WS_s_perror
1109 stub GetAddressByNameA
1110 stub GetAddressByNameW
#1111 stub EnumProtocolsA
diff --git a/resources/sysres_De.rc b/resources/sysres_De.rc
index b866fd4..3534338 100644
--- a/resources/sysres_De.rc
+++ b/resources/sysres_De.rc
@@ -17,14 +17,14 @@
{
POPUP ""
BEGIN
- MENUITEM "&Undo", EM_UNDO32
+ MENUITEM "&Rückgängig", EM_UNDO32
MENUITEM SEPARATOR
- MENUITEM "Cu&t", WM_CUT
- MENUITEM "&Copy", WM_COPY
- MENUITEM "&Paste", WM_PASTE
- MENUITEM "&Delete", WM_CLEAR
+ MENUITEM "&Ausschneiden", WM_CUT
+ MENUITEM "&Kopieren", WM_COPY
+ MENUITEM "&Einfügen", WM_PASTE
+ MENUITEM "&Löschen", WM_CLEAR
MENUITEM SEPARATOR
- MENUITEM "Select &All", EM_SETSEL32
+ MENUITEM "&Alles markieren", EM_SETSEL32
END
}
diff --git a/scheduler/process.c b/scheduler/process.c
index e3bd71b..b819080 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -658,6 +658,7 @@
ret = GetEnvironmentVariable32A(x,d,cursize-(d-xdst));
if (ret) {
d+=strlen(d);
+ s=end;
} else {
CHECK_FREE(strlen(x)+2);
*d++='%';
@@ -667,9 +668,9 @@
}
HeapFree(heap,0,x);
} else
- *d=*s;
+ *d++=*s;
- s++;d++;
+ s++;
} else {
CHECK_FREE(1);
*d++=*s++;
diff --git a/tools/build.c b/tools/build.c
index 3f39bda..c692a41 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -960,102 +960,47 @@
/*******************************************************************
* BuildSpec32File
*
- * Build a Win32 assembly file from a spec file.
+ * Build a Win32 C file from a spec file.
*/
static int BuildSpec32File( char * specfile, FILE *outfile )
{
ORDDEF *odp;
- int i, nb_names, nb_stubs;
- char buffer[1024];
- unsigned char *args, *p;
+ int i, nb_names, nb_reg_funcs = 0;
- fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
- fprintf( outfile, "\t.file\t\"%s\"\n", specfile );
-#ifdef USE_STABS
- getcwd(buffer, sizeof(buffer));
-
- /*
- * The stabs help the internal debugger as they are an indication that it
- * is sensible to step into a thunk/trampoline.
- */
- fprintf( outfile, ".stabs \"%s/\",100,0,0,Code_Start\n", buffer);
- fprintf( outfile, ".stabs \"%s\",100,0,0,Code_Start\n", specfile);
-#endif
-
- fprintf( outfile, "\t.text\n" );
- fprintf( outfile, "\t.align 4\n" );
- fprintf( outfile, "Code_Start:\n" );
-
- /* Output code for all register functions */
-
- for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
- {
- if (odp->type != TYPE_REGISTER) continue;
- fprintf( outfile, "\n/* %s.%d (%s) */\n", DLLName, i, odp->name);
- fprintf( outfile, "\t.align 4\n" );
-#ifdef USE_STABS
- fprintf( outfile, ".stabs \"%s_%d:F1\",36,0,%d,%s_%d\n",
- DLLName, i, odp->lineno, DLLName, i);
-#endif
- fprintf( outfile, "%s_%d:\n", DLLName, i );
-#ifdef USE_STABS
- fprintf( outfile, ".stabn 68,0,%d,0\n", odp->lineno);
-#endif
- fprintf( outfile, "\tpushl $" PREFIX "%s\n",odp->u.func.link_name);
- fprintf( outfile, "\tjmp " PREFIX "CALL32_Regs\n" );
- }
+ fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n\n",
+ specfile );
+ fprintf( outfile, "#include \"builtin32.h\"\n\n" );
/* Output code for all stubs functions */
- nb_stubs = 0;
+ fprintf( outfile, "extern const BUILTIN32_DESCRIPTOR %s_Descriptor;\n",
+ DLLName );
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
{
if (odp->type != TYPE_STUB) continue;
- fprintf( outfile, "\n/* %s.%d (%s) */\n", DLLName, i, odp->name);
-#ifdef USE_STABS
- fprintf( outfile, ".stabs \"%s_%d:F1\",36,0,%d,%s_%d\n",
- DLLName, i, odp->lineno, DLLName, i);
-#endif
- fprintf( outfile, "%s_%d:\n", DLLName, i );
-#ifdef USE_STABS
- fprintf( outfile, ".stabn 68,0,%d,0\n", odp->lineno);
-#endif
- fprintf( outfile, "\tpushl $Name_%d\n", i );
- fprintf( outfile, "\tpushl $%d\n", i );
- if (++nb_stubs == 1)
- {
- fprintf( outfile, "DoStub:\n" );
- fprintf( outfile, "\tpushl $DLLName\n" );
- fprintf( outfile, "\tcall " PREFIX "RELAY_Unimplemented32\n" );
- }
- else fprintf( outfile, "\tjmp DoStub\n" );
+ fprintf( outfile, "static void __stub_%d() { BUILTIN32_Unimplemented(&%s_Descriptor,%d); }\n",
+ i, DLLName, i );
}
- /* Output the DLL functions table */
+ /* Output the DLL functions prototypes */
- fprintf( outfile, "\t.text\n" );
- fprintf( outfile, "\t.align 4\n" );
- fprintf( outfile, "Functions:\n" );
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
{
switch(odp->type)
{
- case TYPE_INVALID:
- fprintf( outfile, "\t.long 0\n" );
- break;
case TYPE_VARARGS:
- fprintf( outfile, "\t.long " PREFIX "%s\n",odp->u.vargs.link_name);
+ fprintf( outfile, "extern void %s();\n", odp->u.vargs.link_name );
break;
case TYPE_EXTERN:
- fprintf( outfile, "\t.long " PREFIX "%s\n", odp->u.ext.link_name );
- break;
- case TYPE_STDCALL:
- case TYPE_CDECL:
- fprintf( outfile, "\t.long " PREFIX "%s\n", odp->u.func.link_name);
+ fprintf( outfile, "extern void %s();\n", odp->u.ext.link_name );
break;
case TYPE_REGISTER:
+ case TYPE_STDCALL:
+ case TYPE_CDECL:
+ fprintf( outfile, "extern void %s();\n", odp->u.func.link_name );
+ break;
+ case TYPE_INVALID:
case TYPE_STUB:
- fprintf( outfile, "\t.long %s_%d\n", DLLName, i );
break;
default:
fprintf(stderr,"build: function type %d not available for Win32\n",
@@ -1064,18 +1009,54 @@
}
}
- /* Output the DLL names table */
+ /* Output the DLL functions table */
- fprintf( outfile, "FuncNames:\n" );
+ fprintf( outfile, "\nstatic const ENTRYPOINT32 Functions[%d] =\n{\n",
+ Limit - Base + 1 );
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
{
- if (odp->type != TYPE_INVALID)
- fprintf( outfile, "\t.long Name_%d\n", i );
+ switch(odp->type)
+ {
+ case TYPE_INVALID:
+ fprintf( outfile, " 0" );
+ break;
+ case TYPE_VARARGS:
+ fprintf( outfile, " %s", odp->u.vargs.link_name );
+ break;
+ case TYPE_EXTERN:
+ fprintf( outfile, " %s", odp->u.ext.link_name );
+ break;
+ case TYPE_REGISTER:
+ case TYPE_STDCALL:
+ case TYPE_CDECL:
+ fprintf( outfile, " %s", odp->u.func.link_name);
+ break;
+ case TYPE_STUB:
+ fprintf( outfile, " __stub_%d", i );
+ break;
+ default:
+ return -1;
+ }
+ if (i < Limit) fprintf( outfile, ",\n" );
}
+ fprintf( outfile, "\n};\n\n" );
+
+ /* Output the DLL names table */
+
+ nb_names = 0;
+ fprintf( outfile, "static const char * const FuncNames[] =\n{\n" );
+ for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
+ {
+ if (odp->type == TYPE_INVALID) continue;
+ if (nb_names++) fprintf( outfile, ",\n" );
+ fprintf( outfile, " \"%s\"", odp->name );
+ }
+ fprintf( outfile, "\n};\n\n" );
/* Output the DLL argument types */
- fprintf( outfile, "ArgTypes:\n" );
+ fprintf( outfile, "static const unsigned int ArgTypes[%d] =\n{\n",
+ Limit - Base + 1 );
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
{
unsigned int j, mask = 0;
@@ -1085,73 +1066,67 @@
if (odp->u.func.arg_types[j] == 't') mask |= 1<< (j*2);
if (odp->u.func.arg_types[j] == 'W') mask |= 2<< (j*2);
}
- fprintf( outfile, "\t.long %d\n",mask);
+ fprintf( outfile, " %d", mask );
+ if (i < Limit) fprintf( outfile, ",\n" );
}
+ fprintf( outfile, "\n};\n\n" );
/* Output the DLL ordinals table */
- fprintf( outfile, "FuncOrdinals:\n" );
+ fprintf( outfile, "static const unsigned short FuncOrdinals[] =\n{\n" );
nb_names = 0;
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
{
if (odp->type == TYPE_INVALID) continue;
- nb_names++;
- /* Some assemblers do not have .word */
- fprintf( outfile, "\t.byte %d,%d\n",
- LOBYTE(i - Base), HIBYTE(i - Base) );
+ if (nb_names++) fprintf( outfile, ",\n" );
+ fprintf( outfile, " %d", i - Base );
}
-
- /* Output the DLL names */
-
- for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
- {
- if (odp->type != TYPE_INVALID)
- fprintf( outfile, "Name_%d:\t.ascii \"%s\\0\"\n", i, odp->name );
- }
+ fprintf( outfile, "\n};\n\n" );
/* Output the DLL functions arguments */
- args = p = (unsigned char *)xmalloc( Limit - Base + 1 );
+ fprintf( outfile, "static const unsigned char FuncArgs[%d] =\n{\n",
+ Limit - Base + 1 );
for (i = Base, odp = OrdinalDefinitions + Base; i <= Limit; i++, odp++)
{
+ unsigned char args;
switch(odp->type)
{
case TYPE_STDCALL:
- *p++ = (unsigned char)strlen(odp->u.func.arg_types);
+ args = (unsigned char)strlen(odp->u.func.arg_types);
break;
case TYPE_CDECL:
- *p++ = 0x80 | (unsigned char)strlen(odp->u.func.arg_types);
+ args = 0x80 | (unsigned char)strlen(odp->u.func.arg_types);
break;
case TYPE_REGISTER:
- *p++ = 0xfe;
+ args = 0xfe;
+ nb_reg_funcs++;
break;
default:
- *p++ = 0xff;
+ args = 0xff;
break;
}
+ fprintf( outfile, " 0x%02x", args );
+ if (i < Limit) fprintf( outfile, ",\n" );
}
- DumpBytes( outfile, args, Limit - Base + 1, NULL, "FuncArgs" );
+ fprintf( outfile, "\n};\n\n" );
/* Output the DLL descriptor */
- fprintf( outfile, "DLLName:\t.ascii \"%s\\0\"\n", DLLName );
- fprintf( outfile, "\t.align 4\n" );
- fprintf( outfile, "\t.globl " PREFIX "%s_Descriptor\n", DLLName );
- fprintf( outfile, PREFIX "%s_Descriptor:\n", DLLName );
- fprintf( outfile, "\t.long DLLName\n" ); /* Name */
- fprintf( outfile, "\t.long %d\n", Base ); /* Base */
- fprintf( outfile, "\t.long %d\n", Limit+1-Base ); /* Number of functions */
- fprintf( outfile, "\t.long %d\n", nb_names ); /* Number of names */
- fprintf( outfile, "\t.long Functions\n" ); /* Functions */
- fprintf( outfile, "\t.long FuncNames\n" ); /* Function names */
- fprintf( outfile, "\t.long FuncOrdinals\n" ); /* Function ordinals */
- fprintf( outfile, "\t.long FuncArgs\n" ); /* Function arguments */
- fprintf( outfile, "\t.long ArgTypes\n" ); /* Function argtypes */
-#ifdef USE_STABS
- fprintf( outfile, "\t.text\n");
- fprintf( outfile, "\t.stabs \"\",100,0,0,.Letext\n");
- fprintf( outfile, ".Letext:\n");
-#endif
+ fprintf( outfile, "const BUILTIN32_DESCRIPTOR %s_Descriptor =\n{\n",
+ DLLName );
+ fprintf( outfile, " \"%s\",\n", DLLName );
+ fprintf( outfile, " %d,\n", Base );
+ fprintf( outfile, " %d,\n", Limit - Base + 1 );
+ fprintf( outfile, " %d,\n", nb_names );
+ fprintf( outfile, " %d,\n", nb_reg_funcs );
+ fprintf( outfile,
+ " Functions,\n"
+ " FuncNames,\n"
+ " FuncOrdinals,\n"
+ " FuncArgs,\n"
+ " ArgTypes\n"
+ "};\n" );
return 0;
}
@@ -1747,7 +1722,8 @@
* Prototypes for the CallTo16 functions:
* extern WINAPI WORD CallTo16_word_xxx( FARPROC16 func, args... );
* extern WINAPI LONG CallTo16_long_xxx( FARPROC16 func, args... );
- * extern WINAPI void CallTo16_regs_{short,long}( const CONTEXT *context );
+ * extern WINAPI void CallTo16_sreg_( const CONTEXT *context );
+ * extern WINAPI void CallTo16_lreg_( const CONTEXT *context );
*/
static void BuildCallTo16Func( FILE *outfile, char *profile )
{
@@ -1756,7 +1732,8 @@
char *args = profile + 5;
if (!strncmp( "word_", profile, 5 )) short_ret = 1;
- else if (!strncmp( "regs_", profile, 5 )) reg_func = 1;
+ else if (!strncmp( "sreg_", profile, 5 )) reg_func = 1;
+ else if (!strncmp( "lreg_", profile, 5 )) reg_func = 2;
else if (strncmp( "long_", profile, 5 ))
{
fprintf( stderr, "Invalid function name '%s'.\n", profile );
@@ -1793,7 +1770,7 @@
fprintf( outfile, PREFIX "CALLTO16_Restore:\n" );
}
fprintf( outfile, "\tpopl %%ebp\n" );
- fprintf( outfile, "\tret $%d\n", strlen(args) + 1 );
+ fprintf( outfile, "\tret $%d\n", 4 * strlen(args) + 4 );
/* Start of the actual CallTo16 routine */
@@ -1853,10 +1830,10 @@
fprintf( outfile, "\tmovl %d(%%ebx),%%edi\n", CONTEXTOFFSET(Edi) );
/* Push the return address
- * With _short suffix, we push 16:16 address (normal lret)
- * With _long suffix, we push 16:32 address (0x66 lret, for KERNEL32_45)
+ * With sreg suffix, we push 16:16 address (normal lret)
+ * With lreg suffix, we push 16:32 address (0x66 lret, for KERNEL32_45)
*/
- if (!strncmp(profile,"regs_short",10))
+ if (reg_func == 1)
fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_regs\n" );
else
{
@@ -2042,6 +2019,7 @@
fprintf( outfile, ".stabs \"CALL32_Init:F1\",36,0,0," PREFIX "CALL32_Init\n");
#endif
fprintf( outfile, "\t.globl " PREFIX "CALL32_Init\n" );
+ fprintf( outfile, "\t.type " PREFIX "CALL32_Init,@function\n" );
fprintf( outfile, PREFIX "CALL32_Init:\n" );
fprintf( outfile, "\tleal -256(%%esp),%%eax\n" );
fprintf( outfile, "\tmovl %%eax,CALL32_Original32_esp\n" );
@@ -2350,6 +2328,8 @@
fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
fprintf( outfile, "\t.text\n" );
+#ifdef __i386__
+
#ifdef USE_STABS
fprintf( outfile, "\t.file\t\"%s\"\n", outname );
getcwd(buffer, sizeof(buffer));
@@ -2379,6 +2359,12 @@
fprintf( outfile, ".Letext:\n");
#endif
+#else /* __i386__ */
+
+ /* Just to avoid an empty file */
+ fprintf( outfile, "\t.long 0\n" );
+
+#endif /* __i386__ */
return 0;
}
diff --git a/win32/Makefile.in b/win32/Makefile.in
index d42613d..7c683e1 100644
--- a/win32/Makefile.in
+++ b/win32/Makefile.in
@@ -15,6 +15,7 @@
file.c \
init.c \
k32obj.c \
+ kernel32.c \
newfns.c \
ordinals.c \
process.c \
diff --git a/win32/code_page.c b/win32/code_page.c
index ed6ea822..2771061 100644
--- a/win32/code_page.c
+++ b/win32/code_page.c
@@ -85,54 +85,82 @@
/***********************************************************************
* MultiByteToWideChar (KERNEL32.392)
*/
-int WINAPI MultiByteToWideChar(UINT32 page, DWORD flags, char *src, int srclen,
+int WINAPI MultiByteToWideChar(UINT32 page, DWORD flags,
+ const char *src, int srclen,
WCHAR *dst, int dstlen)
{
- if (srclen == -1)
- srclen = lstrlen32A(src)+1;
- if (!dstlen || !dst)
- return srclen;
+ int ret;
- lstrcpynAtoW(dst,src,srclen); /* FIXME */
- return srclen-1;
+ if (srclen == -1)
+ srclen = lstrlen32A(src)+1;
+ if (!dstlen || !dst)
+ return srclen;
+
+ ret = srclen;
+ while (srclen > 0 && dstlen > 0) {
+ *dst = (WCHAR)(unsigned char)*src;
+ if (!*src)
+ return ret;
+ dst++; src++;
+ dstlen--; srclen--;
+ }
+ if (dstlen == 0) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+ return ret;
}
int WINAPI WideCharToMultiByte(UINT32 page, DWORD flags, WCHAR *src, int srclen,
char *dst, int dstlen, char* defchar, BOOL32 *used)
{
- int count = 0;
- int dont_copy= (dstlen==0);
- if(page!=GetACP() && page!=CP_OEMCP && page!=CP_ACP)
- fprintf(stdnimp,"Conversion in CP %d not supported\n",page);
+ int count = 0;
+ int eos = 0;
+ int dont_copy= (dstlen==0);
+ if (page!=GetACP() && page!=CP_OEMCP && page!=CP_ACP)
+ fprintf(stdnimp,"Conversion in CP %d not supported\n",page);
#if 0
- if(flags)
- fprintf(stdnimp,"WideCharToMultiByte flags %lx not supported\n",flags);
+ if (flags)
+ fprintf(stdnimp,"WideCharToMultiByte flags %lx not supported\n",flags);
#endif
- if(used)
- *used=0;
- while(srclen && (dont_copy || dstlen))
- {
- if(!dont_copy){
- if(*src<256)
- *dst = *src;
- else
- {
- /* FIXME: Is this correct ?*/
- if(flags & WC_DEFAULTCHAR){
- *dst = defchar ? *defchar : '?';
- if(used)*used=1;
- }
- }
- dstlen--;
- dst++;
- }
- count++;
- if(!*src)
- break;
- if(srclen!=-1)srclen--;
- src++;
+ if(used)
+ *used=0;
+ if (srclen == -1)
+ srclen = lstrlen32W(src)+1;
+ while(srclen && (dont_copy || dstlen))
+ {
+ if(!dont_copy){
+ if(*src<256)
+ *dst = *src;
+ else
+ {
+ /* ??? The WC_DEFAULTCHAR flag only gets used in
+ * combination with the WC_COMPOSITECHECK flag or at
+ * least this is what it seems from using the function
+ * on NT4.0 in combination with reading the documentation.
+ */
+ *dst = defchar ? *defchar : '?';
+ if(used)*used=1;
+ }
+ dstlen--;
+ dst++;
}
+ count++;
+ srclen--;
+ if(!*src) {
+ eos = 1;
+ break;
+ }
+ src++;
+ }
+ if (dont_copy)
return count;
+
+ if (!eos && srclen > 0) {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return 0;
+ }
+ return count;
}
diff --git a/win32/console.c b/win32/console.c
index d10a1ca..fa8166f 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -2,6 +2,7 @@
* Win32 kernel functions
*
* Copyright 1995 Martin von Loewis and Cameron Heide
+ * Copyright 1997 Karl Garrison
*/
#include <stdio.h>
@@ -81,9 +82,7 @@
{
*mode = ENABLE_PROCESSED_INPUT |
ENABLE_LINE_INPUT |
- ENABLE_ECHO_INPUT |
- ENABLE_WINDOW_INPUT |
- ENABLE_MOUSE_INPUT;
+ ENABLE_ECHO_INPUT;
return TRUE;
}
@@ -118,7 +117,7 @@
* WriteConsoleA (KERNEL32.567)
*/
BOOL32 WINAPI WriteConsole32A( HANDLE32 hConsoleOutput,
- LPVOID lpBuffer,
+ LPCVOID lpBuffer,
DWORD nNumberOfCharsToWrite,
LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved )
@@ -133,7 +132,7 @@
* WriteConsoleW (KERNEL32.577)
*/
BOOL32 WINAPI WriteConsole32W( HANDLE32 hConsoleOutput,
- LPVOID lpBuffer,
+ LPCVOID lpBuffer,
DWORD nNumberOfCharsToWrite,
LPDWORD lpNumberOfCharsWritten,
LPVOID lpReserved )
@@ -199,7 +198,8 @@
/***********************************************************************
* FlushConsoleInputBuffer (KERNEL32.132)
*/
-BOOL32 WINAPI FlushConsoleInputBuffer(HANDLE32 hConsoleInput){
+BOOL32 WINAPI FlushConsoleInputBuffer(HANDLE32 hConsoleInput)
+{
fprintf(stderr,"FlushConsoleInputBuffer(%d)\n",hConsoleInput);
return TRUE;
}
@@ -222,6 +222,70 @@
*/
BOOL32 WINAPI GetNumberOfConsoleInputEvents(HANDLE32 hcon,LPDWORD nrofevents)
{
- *nrofevents = 1;
+ *nrofevents = 0;
return TRUE;
}
+
+/***********************************************************************
+ * GetNumberOfConsoleMouseButtons (KERNEL32.358)
+ */
+BOOL32 WINAPI GetNumberOfConsoleMouseButtons(LPDWORD nrofbuttons)
+{
+ *nrofbuttons = 2;
+ fprintf(stderr,"GetNumberOfConsoleMouseButtons: STUB returning 2\n");
+ return TRUE;
+}
+
+/***********************************************************************
+ * PeekConsoleInputA (KERNEL32.550)
+ */
+BOOL32 WINAPI PeekConsoleInput32A(HANDLE32 hConsoleInput,
+ LPDWORD pirBuffer,
+ DWORD cInRecords,
+ LPDWORD lpcRead)
+/* FIXME: pirBuffer should be a pointer to an INPUT_RECORD structure
+ -Karl Garrison (12/01/97) */
+{
+ pirBuffer = NULL;
+ cInRecords = 0;
+ *lpcRead = 0;
+ fprintf(stderr,"GetNumberOfConsoleMouseButtons: STUB returning NULL\n");
+ return TRUE;
+}
+
+/***********************************************************************
+ * PeekConsoleInputW (KERNEL32.551)
+ */
+BOOL32 WINAPI PeekConsoleInput32W(HANDLE32 hConsoleInput,
+ LPDWORD pirBuffer,
+ DWORD cInRecords,
+ LPDWORD lpcRead)
+/* FIXME: pirBuffer should be a pointer to an INPUT_RECORD structure
+ -Karl Garrison (12/01/97) */
+{
+ pirBuffer = NULL;
+ cInRecords = 0;
+ *lpcRead = 0;
+ fprintf(stderr,"GetNumberOfConsoleMouseButtons: STUB returning NULL\n");
+ return TRUE;
+}
+
+/***********************************************************************
+ * GetConsoleCursorInfo32 (KERNEL32.296)
+ */
+BOOL32 WINAPI GetConsoleCursorInfo32(HANDLE32 hcon, LPDWORD cinfo)
+{
+ cinfo[0] = 10; /* 10% of character box is cursor. */
+ cinfo[1] = TRUE; /* Cursur is visible. */
+ fprintf (stdnimp, "GetConsoleCursorInfo32 -- STUB!\n");
+ return TRUE;
+}
+
+/***********************************************************************
+ * SetConsoleCursorInfo32 (KERNEL32.626)
+ */
+BOOL32 WINAPI SetConsoleCursorInfo32(HANDLE32 hcon, LPDWORD cinfo)
+{
+ fprintf (stdnimp, "SetConsoleCursorInfo32 -- STUB!\n");
+ return TRUE;
+}
diff --git a/win32/environment.c b/win32/environment.c
index 90a0bf3..65ad44d 100644
--- a/win32/environment.c
+++ b/win32/environment.c
@@ -29,9 +29,9 @@
*/
LPCWSTR WINAPI GetCommandLine32W(void)
{
- static WCHAR buffer[256];
+ static WCHAR buffer[1024];
- lstrcpynAtoW(buffer,GetCommandLine32A(),256);
+ lstrcpynAtoW(buffer,GetCommandLine32A(),1024);
return buffer;
}
diff --git a/win32/kernel32.c b/win32/kernel32.c
new file mode 100644
index 0000000..a53e04e
--- /dev/null
+++ b/win32/kernel32.c
@@ -0,0 +1,663 @@
+/*
+ * KERNEL32 thunks and other undocumented stuff
+ *
+ * Copyright 1997 Marcus Meissner
+ */
+
+#include <stdio.h>
+#include "windows.h"
+#include "callback.h"
+#include "resource.h"
+#include "task.h"
+#include "user.h"
+#include "heap.h"
+#include "module.h"
+#include "stackframe.h"
+#include "selectors.h"
+#include "task.h"
+#include "win.h"
+#include "stddebug.h"
+#include "debug.h"
+
+/***********************************************************************
+ * *
+ * Win95 internal thunks *
+ * *
+ ***********************************************************************/
+
+/***********************************************************************
+ * Generates a FT_Prolog call.
+ *
+ * 0FB6D1 movzbl edx,cl
+ * 8B1495xxxxxxxx mov edx,[4*edx + xxxxxxxx]
+ * 68xxxxxxxx push FT_Prolog
+ * C3 lret
+ */
+static void _write_ftprolog(LPBYTE thunk,DWORD thunkstart) {
+ LPBYTE x;
+
+ x = thunk;
+ *x++ = 0x0f;*x++=0xb6;*x++=0xd1; /* movzbl edx,cl */
+ *x++ = 0x8B;*x++=0x14;*x++=0x95;*(DWORD*)x= thunkstart;
+ x+=4; /* mov edx, [4*edx + thunkstart] */
+ *x++ = 0x68; *(DWORD*)x = (DWORD)GetProcAddress32(GetModuleHandle32A("KERNEL32"),"FT_Prolog");
+ x+=4; /* push FT_Prolog */
+ *x++ = 0xC3; /* lret */
+ /* fill rest with 0xCC / int 3 */
+}
+
+/***********************************************************************
+ * FT_PrologPrime (KERNEL32.89)
+ */
+void WINAPI FT_PrologPrime(DWORD startind,LPBYTE thunk) {
+ _write_ftprolog(thunk,*(DWORD*)(startind+thunk));
+}
+
+/***********************************************************************
+ * Generates a QT_Thunk style call.
+ *
+ * 33C9 xor ecx, ecx
+ * 8A4DFC mov cl , [ebp-04]
+ * 8B148Dxxxxxxxx mov edx, [4*ecx + (EAX+EDX)]
+ * B8yyyyyyyy mov eax, QT_Thunk
+ * FFE0 jmp eax
+ */
+static void _write_qtthunk(LPBYTE start,DWORD thunkstart) {
+ LPBYTE x;
+
+ x = start;
+ *x++ = 0x33;*x++=0xC9; /* xor ecx,ecx */
+ *x++ = 0x8A;*x++=0x4D;*x++=0xFC; /* movb cl,[ebp-04] */
+ *x++ = 0x8B;*x++=0x14;*x++=0x8D;*(DWORD*)x= thunkstart;
+ x+=4; /* mov edx, [4*ecx + (EAX+EDX) */
+ *x++ = 0xB8; *(DWORD*)x = (DWORD)GetProcAddress32(GetModuleHandle32A("KERNEL32"),"QT_Thunk");
+ x+=4; /* mov eax , QT_Thunk */
+ *x++ = 0xFF; *x++ = 0xE0; /* jmp eax */
+ /* should fill the rest of the 32 bytes with 0xCC */
+}
+
+/***********************************************************************
+ * ThunkConnect32 (KERNEL32)
+ * Connects a 32bit and a 16bit thunkbuffer.
+ */
+struct thunkstruct
+{
+ char magic[4];
+ DWORD length;
+ DWORD ptr;
+ DWORD x0C;
+
+ DWORD x10;
+ DWORD x14;
+ DWORD x18;
+ DWORD x1C;
+ DWORD x20;
+};
+
+UINT32 WINAPI ThunkConnect32( struct thunkstruct *ths, LPSTR thunkfun16,
+ LPSTR module16, LPSTR module32, HMODULE32 hmod32,
+ DWORD dllinitarg1 )
+{
+ HINSTANCE16 hmm;
+ SEGPTR thkbuf;
+ struct thunkstruct *ths16;
+
+ dprintf_thunk(stddeb,"ThunkConnect32(<struct>,%s,%s,%s,%x,%lx)\n",
+ thunkfun16,module32,module16,hmod32,dllinitarg1
+ );
+ dprintf_thunk(stddeb," magic = %c%c%c%c\n",
+ ths->magic[0],
+ ths->magic[1],
+ ths->magic[2],
+ ths->magic[3]
+ );
+ dprintf_thunk(stddeb," length = %lx\n",ths->length);
+ if (lstrncmp32A(ths->magic,"SL01",4)&&lstrncmp32A(ths->magic,"LS01",4))
+ return 0;
+ hmm=LoadModule16(module16,NULL);
+ if (hmm<=32)
+ return 0;
+ thkbuf=(SEGPTR)WIN32_GetProcAddress16(hmm,thunkfun16);
+ if (!thkbuf)
+ return 0;
+ ths16=(struct thunkstruct*)PTR_SEG_TO_LIN(thkbuf);
+ if (lstrncmp32A(ths16->magic,ths->magic,4))
+ return 0;
+
+ if (!lstrncmp32A(ths->magic,"SL01",4)) {
+ if (ths16->length != ths->length)
+ return 0;
+ ths->x0C = (DWORD)ths16;
+
+ dprintf_thunk(stddeb," ths16 magic is 0x%08lx\n",*(DWORD*)ths16->magic);
+ if (*((DWORD*)ths16->magic) != 0x0000304C)
+ return 0;
+ if (!*(WORD*)(((LPBYTE)ths16)+0x12))
+ return 0;
+
+ }
+ if (!lstrncmp32A(ths->magic,"LS01",4)) {
+ if (ths16->length != ths->length)
+ return 0;
+ ths->ptr = (DWORD)PTR_SEG_TO_LIN(ths16->ptr);
+ /* code offset for QT_Thunk is at 0x1C... */
+ _write_qtthunk (((LPBYTE)ths) + ths->x1C,ths->ptr);
+ /* code offset for FT_Prolog is at 0x20... */
+ _write_ftprolog(((LPBYTE)ths) + ths->x20,ths->ptr);
+ return 1;
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * QT_Thunk (KERNEL32)
+ *
+ * The target address is in EDX.
+ * The 16 bit arguments start at ESP+4.
+ * The number of 16bit argumentbytes is EBP-ESP-0x44 (68 Byte thunksetup).
+ * [ok]
+ */
+VOID WINAPI QT_Thunk(CONTEXT *context)
+{
+ CONTEXT context16;
+ DWORD argsize;
+
+ memcpy(&context16,context,sizeof(context16));
+
+ CS_reg(&context16) = HIWORD(EDX_reg(context));
+ IP_reg(&context16) = LOWORD(EDX_reg(context));
+
+ argsize = EBP_reg(context)-ESP_reg(context)-0x44;
+
+ /* additional 4 bytes used by the relaycode for storing the stackptr */
+ memcpy( ((LPBYTE)CURRENT_STACK16)-argsize-4,
+ (LPBYTE)ESP_reg(context)+4,
+ argsize
+ );
+ EAX_reg(context) = Callbacks->CallRegisterShortProc(&context16,
+ -argsize);
+}
+
+
+/**********************************************************************
+ * WOWCallback16 (KERNEL32.62)
+ */
+DWORD WINAPI WOWCallback16(FARPROC16 fproc,DWORD arg)
+{
+ DWORD ret;
+ dprintf_thunk(stddeb,"WOWCallback16(%p,0x%08lx) ",fproc,arg);
+ ret = Callbacks->CallWOWCallbackProc(fproc,arg);
+ dprintf_thunk(stddeb,"... returns %ld\n",ret);
+ return ret;
+}
+
+/***********************************************************************
+ * _KERNEL32_52 (KERNEL32.52)
+ * Returns a pointer to ThkBuf in the 16bit library SYSTHUNK.DLL.
+ * [ok probably]
+ */
+LPVOID WINAPI _KERNEL32_52()
+{
+ HMODULE32 hmod = LoadLibrary16("systhunk.dll");
+
+ dprintf_thunk(stddeb, "_KERNEL32_52: systhunk.dll module %d\n", hmod);
+
+ if (hmod<=32)
+ return 0;
+ return PTR_SEG_TO_LIN(WIN32_GetProcAddress16(hmod,"ThkBuf"));
+}
+
+/***********************************************************************
+ * _KERNEL32_43 (KERNEL32.42)
+ * A thunkbuffer link routine
+ * The thunkbuf looks like:
+ *
+ * 00: DWORD length ? don't know exactly
+ * 04: SEGPTR ptr ? where does it point to?
+ * The pointer ptr is written into the first DWORD of 'thunk'.
+ * (probably correct implemented)
+ * [ok probably]
+ */
+DWORD WINAPI _KERNEL32_43(LPDWORD thunk,LPCSTR thkbuf,DWORD len,
+ LPCSTR dll16,LPCSTR dll32)
+{
+ HINSTANCE16 hmod;
+ LPDWORD addr;
+ SEGPTR segaddr;
+
+ hmod = LoadLibrary16(dll16);
+ if (hmod<32) {
+ fprintf(stderr,"KERNEL32_43->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
+ return 0;
+ }
+ segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
+ if (!segaddr) {
+ fprintf(stderr,"KERNEL32_43->no %s exported from %s!\n",thkbuf,dll16);
+ return 0;
+ }
+ addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
+ if (addr[0] != len) {
+ fprintf(stderr,"KERNEL32_43->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
+ return 0;
+ }
+ if (!addr[1])
+ return 0;
+ *(DWORD*)thunk = addr[1];
+
+ dprintf_thunk(stddeb, "_KERNEL32_43: loaded module %d, func %s (%d) @ %p (%p), returning %p\n",
+ hmod, HIWORD(thkbuf)==0 ? "<ordinal>" : thkbuf, (int)thkbuf, (void*)segaddr, addr, (void*)addr[1]);
+
+ return addr[1];
+}
+
+/***********************************************************************
+ * _KERNEL32_45 (KERNEL32.44)
+ * Another 32->16 thunk, the difference to QT_Thunk is, that the called routine
+ * uses 0x66 lret, and that we have to pass CX in DI.
+ * (there seems to be some kind of BL/BX return magic too...)
+ *
+ * [doesn't crash anymore]
+ */
+VOID WINAPI _KERNEL32_45(CONTEXT *context)
+{
+ CONTEXT context16;
+ LPBYTE curstack;
+ DWORD ret,stacksize;
+
+ dprintf_thunk(stddeb,"KERNEL32_45(%%eax=0x%08lx(%%cx=0x%04lx,%%edx=0x%08lx))\n",
+ (DWORD)EAX_reg(context),(DWORD)CX_reg(context),(DWORD)EDX_reg(context)
+ );
+ stacksize = EBP_reg(context)-ESP_reg(context);
+ dprintf_thunk(stddeb," stacksize = %ld\n",stacksize);
+
+ memcpy(&context16,context,sizeof(context16));
+
+ DI_reg(&context16) = CX_reg(context);
+ CS_reg(&context16) = HIWORD(EAX_reg(context));
+ IP_reg(&context16) = LOWORD(EAX_reg(context));
+
+ curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
+ memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
+ ret = Callbacks->CallRegisterLongProc(&context16,0);
+ STACK16_POP(stacksize);
+
+ dprintf_thunk(stddeb,". returned %08lx\n",ret);
+ EAX_reg(context) = ret;
+}
+
+/***********************************************************************
+ * _KERNEL32_40 (KERNEL32.40)
+ * YET Another 32->16 thunk, the difference to the others is still mysterious
+ * target address is EDX
+ *
+ * [crashes]
+ */
+VOID WINAPI _KERNEL32_40(CONTEXT *context)
+{
+ CONTEXT context16;
+ LPBYTE curstack;
+ DWORD ret,stacksize;
+
+ dprintf_thunk(stddeb,"_KERNEL32_40(EDX=0x%08lx)\n",
+ EDX_reg(context)
+ );
+ stacksize = EBP_reg(context)-ESP_reg(context);
+ dprintf_thunk(stddeb," stacksize = %ld\n",stacksize);
+ dprintf_thunk(stddeb,"on top of stack: 0x%04x\n",*(WORD*)ESP_reg(context));
+
+ memcpy(&context16,context,sizeof(context16));
+
+ CS_reg(&context16) = HIWORD(EDX_reg(context));
+ IP_reg(&context16) = LOWORD(EDX_reg(context));
+
+ curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
+ memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
+ ret = Callbacks->CallRegisterShortProc(&context16,0);
+ STACK16_POP(stacksize);
+
+ dprintf_thunk(stddeb,". returned %08lx\n",ret);
+ EAX_reg(context) = ret;
+}
+
+
+/***********************************************************************
+ * (KERNEL32.41)
+ * A thunk setup routine.
+ * Expects a pointer to a preinitialized thunkbuffer in the first argument
+ * looking like:
+ * 00..03: unknown (pointer, check _41, _43, _46)
+ * 04: EB1E jmp +0x20
+ *
+ * 06..23: unknown (space for replacement code, check .90)
+ *
+ * 24:>E800000000 call offset 29
+ * 29:>58 pop eax ( target of call )
+ * 2A: 2D25000000 sub eax,0x00000025 ( now points to offset 4 )
+ * 2F: BAxxxxxxxx mov edx,xxxxxxxx
+ * 34: 68yyyyyyyy push KERNEL32.90
+ * 39: C3 ret
+ *
+ * 3A: EB1E jmp +0x20
+ * 3E ... 59: unknown (space for replacement code?)
+ * 5A: E8xxxxxxxx call <32bitoffset xxxxxxxx>
+ * 5F: 5A pop edx
+ * 60: 81EA25xxxxxx sub edx, 0x25xxxxxx
+ * 66: 52 push edx
+ * 67: 68xxxxxxxx push xxxxxxxx
+ * 6C: 68yyyyyyyy push KERNEL32.89
+ * 71: C3 ret
+ * 72: end?
+ * This function checks if the code is there, and replaces the yyyyyyyy entries
+ * by the functionpointers.
+ * The thunkbuf looks like:
+ *
+ * 00: DWORD length ? don't know exactly
+ * 04: SEGPTR ptr ? where does it point to?
+ * The segpointer ptr is written into the first DWORD of 'thunk'.
+ * [ok probably]
+ */
+
+LPVOID WINAPI _KERNEL32_41(LPBYTE thunk,LPCSTR thkbuf,DWORD len,LPCSTR dll16,
+ LPCSTR dll32)
+{
+ HMODULE32 hkrnl32 = GetModuleHandle32A("KERNEL32");
+ HMODULE16 hmod;
+ LPDWORD addr,addr2;
+ DWORD segaddr;
+
+ /* FIXME: add checks for valid code ... */
+ /* write pointers to kernel32.89 and kernel32.90 (+ordinal base of 1) */
+ *(DWORD*)(thunk+0x35) = (DWORD)GetProcAddress32(hkrnl32,(LPSTR)90);
+ *(DWORD*)(thunk+0x6D) = (DWORD)GetProcAddress32(hkrnl32,(LPSTR)89);
+
+
+ hmod = LoadLibrary16(dll16);
+ if (hmod<32) {
+ fprintf(stderr,"KERNEL32_41->failed to load 16bit DLL %s, error %d\n",dll16,hmod);
+ return NULL;
+ }
+ segaddr = (DWORD)WIN32_GetProcAddress16(hmod,(LPSTR)thkbuf);
+ if (!segaddr) {
+ fprintf(stderr,"KERNEL32_41->no %s exported from %s!\n",thkbuf,dll16);
+ return NULL;
+ }
+ addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
+ if (addr[0] != len) {
+ fprintf(stderr,"KERNEL32_41->thkbuf length mismatch? %ld vs %ld\n",len,addr[0]);
+ return NULL;
+ }
+ addr2 = PTR_SEG_TO_LIN(addr[1]);
+ if (HIWORD(addr2))
+ *(DWORD*)thunk = (DWORD)addr2;
+
+ dprintf_thunk(stddeb, "_KERNEL32_41: loaded module %d, func %s(%d) @ %p (%p), returning %p\n",
+ hmod, HIWORD(thkbuf)==0 ? "<ordinal>" : thkbuf, (int)thkbuf, (void*)segaddr, addr, addr2);
+
+ return addr2;
+}
+
+/***********************************************************************
+ * (KERNEL32.90)
+ * QT Thunk priming function
+ * Rewrites the first part of the thunk to use the QT_Thunk interface
+ * and jumps to the start of that code.
+ * [ok]
+ */
+VOID WINAPI _KERNEL32_90(CONTEXT *context)
+{
+ dprintf_thunk(stddeb, "_KERNEL32_90: QT Thunk priming; context %p\n", context);
+
+ _write_qtthunk((LPBYTE)EAX_reg(context),*(DWORD*)(EAX_reg(context)+EDX_reg(context)));
+ /* we just call the real QT_Thunk right now
+ * we can bypass the relaycode, for we already have the registercontext
+ */
+ EDX_reg(context) = *(DWORD*)((*(DWORD*)(EAX_reg(context)+EDX_reg(context)))+4*(((BYTE*)EBP_reg(context))[-4]));
+ return QT_Thunk(context);
+}
+
+/***********************************************************************
+ * (KERNEL32.45)
+ * Another thunkbuf link routine.
+ * The start of the thunkbuf looks like this:
+ * 00: DWORD length
+ * 04: SEGPTR address for thunkbuffer pointer
+ * [ok probably]
+ */
+VOID WINAPI _KERNEL32_46(LPBYTE thunk,LPSTR thkbuf,DWORD len,LPSTR dll16,
+ LPSTR dll32)
+{
+ LPDWORD addr;
+ HMODULE16 hmod;
+ SEGPTR segaddr;
+
+ hmod = LoadLibrary16(dll16);
+ if (hmod < 32) {
+ fprintf(stderr,"KERNEL32_46->couldn't load %s, error %d\n",dll16,hmod);
+ return;
+ }
+ segaddr = (SEGPTR)WIN32_GetProcAddress16(hmod,thkbuf);
+ if (!segaddr) {
+ fprintf(stderr,"KERNEL32_46-> haven't found %s in %s!\n",thkbuf,dll16);
+ return;
+ }
+ addr = (LPDWORD)PTR_SEG_TO_LIN(segaddr);
+ if (addr[0] != len) {
+ fprintf(stderr,"KERNEL32_46-> length of thkbuf differs from expected length! (%ld vs %ld)\n",addr[0],len);
+ return;
+ }
+ *(DWORD*)PTR_SEG_TO_LIN(addr[1]) = (DWORD)thunk;
+
+ dprintf_thunk(stddeb, "_KERNEL32_46: loaded module %d, func %s(%d) @ %p (%p)\n",
+ hmod, HIWORD(thkbuf)==0 ? "<ordinal>" : thkbuf, (int)thkbuf, (void*)segaddr, addr);
+}
+
+/**********************************************************************
+ * _KERNEL32_87
+ * Check if thunking is initialized (ss selector set up etc.)
+ * We do that differently, so just return TRUE.
+ * [ok]
+ */
+BOOL32 WINAPI _KERNEL32_87()
+{
+ dprintf_thunk(stddeb, "_KERNEL32_87: Yes, thunking is initialized\n");
+ return TRUE;
+}
+
+/**********************************************************************
+ * _KERNEL32_88
+ * One of the real thunking functions. This one seems to be for 32<->32
+ * thunks. It should probably be capable of crossing processboundaries.
+ *
+ * And YES, I've seen nr=48 (somewhere in the Win95 32<->16 OLE coupling)
+ * [ok]
+ */
+DWORD WINAPIV _KERNEL32_88( DWORD nr, DWORD flags, FARPROC32 fun, ... )
+{
+ DWORD i,ret;
+ DWORD *args = ((DWORD *)&fun) + 1;
+
+ dprintf_thunk(stddeb,"KERNEL32_88(%ld,0x%08lx,%p,[ ",nr,flags,fun);
+ for (i=0;i<nr/4;i++) { dprintf_thunk(stddeb,"0x%08lx,",args[i]); }
+ dprintf_thunk(stddeb,"])\n");
+ switch (nr) {
+ case 0: ret = fun();
+ break;
+ case 4: ret = fun(args[0]);
+ break;
+ case 8: ret = fun(args[0],args[1]);
+ break;
+ case 12: ret = fun(args[0],args[1],args[2]);
+ break;
+ case 16: ret = fun(args[0],args[1],args[2],args[3]);
+ break;
+ case 20: ret = fun(args[0],args[1],args[2],args[3],args[4]);
+ break;
+ case 24: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5]);
+ break;
+ case 28: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
+ break;
+ case 32: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
+ break;
+ case 36: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
+ break;
+ case 40: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
+ break;
+ case 44: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
+ break;
+ case 48: ret = fun(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]);
+ break;
+ default:
+ fprintf(stderr,"_KERNEL32_88: unsupported nr of arguments, %ld\n",nr);
+ ret = 0;
+ break;
+
+ }
+ dprintf_thunk(stddeb," returning %ld ...\n",ret);
+ return ret;
+}
+
+/**********************************************************************
+ * KERNEL_619 (KERNEL)
+ * Seems to store y and z depending on x in some internal lists...
+ */
+WORD WINAPI _KERNEL_619(WORD x,DWORD y,DWORD z)
+{
+ fprintf(stderr,"KERNEL_619(0x%04x,0x%08lx,0x%08lx)\n",x,y,z);
+ return x;
+}
+
+/**********************************************************************
+ * AllocSLCallback (KERNEL32)
+ *
+ * Win95 uses some structchains for callbacks. It allocates them
+ * in blocks of 100 entries, size 32 bytes each, layout:
+ * blockstart:
+ * 0: PTR nextblockstart
+ * 4: entry *first;
+ * 8: WORD sel ( start points to blockstart)
+ * A: WORD unknown
+ * 100xentry:
+ * 00..17: Code
+ * 18: PDB *owning_process;
+ * 1C: PTR blockstart
+ *
+ * We ignore this for now. (Just a note for further developers)
+ * FIXME: use this method, so we don't waste selectors...
+ *
+ * Following code is then generated by AllocSLCallback. The code is 16 bit, so
+ * the 0x66 prefix switches from word->long registers.
+ *
+ * 665A pop edx
+ * 6668x arg2 x pushl <arg2>
+ * 6652 push edx
+ * EAx arg1 x jmpf <arg1>
+ *
+ * returns the startaddress of this thunk.
+ *
+ * Note, that they look very similair to the ones allocates by THUNK_Alloc.
+ */
+DWORD WINAPI
+AllocSLCallback(DWORD finalizer,DWORD callback) {
+ LPBYTE x,thunk = HeapAlloc( GetProcessHeap(), 0, 32 );
+ WORD sel;
+
+ x=thunk;
+ *x++=0x66;*x++=0x5a; /* popl edx */
+ *x++=0x66;*x++=0x68;*(DWORD*)x=finalizer;x+=4; /* pushl finalizer */
+ *x++=0x66;*x++=0x52; /* pushl edx */
+ *x++=0xea;*(DWORD*)x=callback;x+=4; /* jmpf callback */
+
+ *(DWORD*)(thunk+18) = GetCurrentProcessId();
+
+ sel = SELECTOR_AllocBlock( thunk , 32, SEGMENT_CODE, FALSE, FALSE );
+ return (sel<<16)|0;
+}
+
+void WINAPI
+FreeSLCallback(DWORD x) {
+ fprintf(stderr,"FreeSLCallback(0x%08lx)\n",x);
+}
+
+/**********************************************************************
+ * KERNEL_358 (KERNEL)
+ * Allocates a code segment which starts at the address passed in x. limit
+ * 0xfffff, and returns the pointer to the start.
+ */
+DWORD WINAPI
+_KERNEL_358(DWORD x) {
+ WORD sel;
+
+ fprintf(stderr,"_KERNEL_358(0x%08lx),stub\n",x);
+ if (!HIWORD(x))
+ return x;
+
+ sel = SELECTOR_AllocBlock( PTR_SEG_TO_LIN(x) , 0xffff, SEGMENT_CODE, FALSE, FALSE );
+ return (sel<<16)|(0x0000);
+}
+
+/**********************************************************************
+ * KERNEL_359 (KERNEL)
+ * Frees the code segment of the passed linear pointer (This has usually
+ * been allocated by _KERNEL_358).
+ */
+VOID WINAPI
+_KERNEL_359(DWORD x) {
+ DWORD savedsssp;
+
+ fprintf(stderr,"_KERNEL_359(0x%08lx),stub\n",x);
+ if ((HIWORD(x) & 7)!=7)
+ return;
+ savedsssp = IF1632_Saved16_ss_sp;IF1632_Saved16_ss_sp = 0;
+ SELECTOR_FreeBlock(x>>16,1);
+ IF1632_Saved16_ss_sp = savedsssp;
+ return;
+}
+
+/**********************************************************************
+ * KERNEL_472 (KERNEL)
+ * something like GetCurrenthInstance.
+ */
+VOID WINAPI
+_KERNEL_472(CONTEXT *context) {
+ fprintf(stderr,"_KERNEL_472(0x%08lx),stub\n",EAX_reg(context));
+ if (!EAX_reg(context)) {
+ TDB *pTask = (TDB*)GlobalLock16(GetCurrentTask());
+ AX_reg(context)=pTask->hInstance;
+ return;
+ }
+ if (!HIWORD(EAX_reg(context)))
+ return; /* returns the passed value */
+ /* hmm ... fixme */
+}
+
+/**********************************************************************
+ * KERNEL_431 (KERNEL.431)
+ * IsPeFile
+ */
+BOOL16 WINAPI KERNEL_431(LPSTR fn,WORD x) {
+ IMAGE_DOS_HEADER mzh;
+ HFILE32 hf;
+ OFSTRUCT ofs;
+ DWORD xmagic;
+
+ hf = OpenFile32(fn,&ofs,OF_READ);
+ if (hf==HFILE_ERROR32)
+ return FALSE;
+ if (sizeof(mzh)!=_lread32(hf,&mzh,sizeof(mzh))) {
+ _lclose32(hf);
+ return FALSE;
+ }
+ if (mzh.e_magic!=IMAGE_DOS_SIGNATURE) {
+ fprintf(stderr,"file has not got dos signature!\n");
+ _lclose32(hf);
+ return FALSE;
+ }
+ _llseek32(hf,mzh.e_lfanew,SEEK_SET);
+ if (sizeof(DWORD)!=_lread32(hf,&xmagic,sizeof(DWORD))) {
+ _lclose32(hf);
+ return FALSE;
+ }
+ _lclose32(hf);
+ return (xmagic == IMAGE_NT_SIGNATURE);
+}
diff --git a/win32/newfns.c b/win32/newfns.c
index 3192451..1ef72e5 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -49,6 +49,17 @@
return FALSE;
}
+HANDLE32 WINAPI FindFirstChangeNotification32A(LPCSTR lpPathName,BOOL32 bWatchSubtree,DWORD dwNotifyFilter) {
+ fprintf(stderr,"FindFirstChangeNotification(%s,%d,%08lx),stub\n",
+ lpPathName,bWatchSubtree,dwNotifyFilter
+ );
+ return 0xcafebabe;
+}
+
+BOOL32 WINAPI FindNextChangeNotification(HANDLE32 fcnhandle) {
+ fprintf(stderr,"FindNextChangeNotification(%08x),stub!\n",fcnhandle);
+ return FALSE;
+}
/****************************************************************************
* QueryPerformanceFrequency (KERNEL32.565)
diff --git a/win32/ordinals.c b/win32/ordinals.c
index 576d25b..10af63b 100644
--- a/win32/ordinals.c
+++ b/win32/ordinals.c
@@ -16,9 +16,6 @@
#include "debug.h"
#include "stddebug.h"
-extern THDB *pCurrentThread;
-extern PDB32 *pCurrentProcess;
-
static CRITICAL_SECTION Win16Mutex;
/***********************************************
diff --git a/win32/thread.c b/win32/thread.c
index e33755a..e974c29 100644
--- a/win32/thread.c
+++ b/win32/thread.c
@@ -159,7 +159,7 @@
void WINAPI DeleteCriticalSection(CRITICAL_SECTION *pcritical)
{
- semctl((int) pcritical->LockSemaphore,0,IPC_RMID,(union semun)NULL);
+ semctl((int) pcritical->LockSemaphore,0,IPC_RMID, (void *)0);
pcritical->Reserved=-1;
}
diff --git a/windows/dce.c b/windows/dce.c
index 2d3b506..6fb6d56 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -12,8 +12,9 @@
*
* DCX_DCEEMPTY - dce is uninitialized
* DCX_DCEBUSY - dce is in use
- * DCX_KEEPCLIPRGN - ReleaseDC should preserve the clipping region
- * DCX_WINDOWPAINT - BeginPaint specific flag
+ * DCX_DCEDIRTY - ReleaseDC() should wipe instead of caching
+ * DCX_KEEPCLIPRGN - ReleaseDC() should not delete the clipping region
+ * DCX_WINDOWPAINT - BeginPaint() is in effect
*/
#include "options.h"
@@ -192,7 +193,17 @@
if (dce->DCXflags & DCX_CACHE)
{
SetDCState( dce->hDC, defaultDCstate );
- dce->DCXflags &= ~DCX_DCEBUSY; /* but without DCX_DCEEMPTY */
+ dce->DCXflags &= ~DCX_DCEBUSY;
+ if (dce->DCXflags & DCX_DCEDIRTY)
+ {
+ /* don't keep around invalidated entries
+ * because SetDCState() disables hVisRgn updates
+ * by removing dirty bit. */
+
+ dce->hwndCurrent = 0;
+ dce->DCXflags &= DCX_CACHE;
+ dce->DCXflags |= DCX_DCEEMPTY;
+ }
}
return 1;
}
@@ -261,11 +272,12 @@
}
else
{
- /* Set dirty bit in the hDC */
+ /* Set dirty bits in the hDC and DCE structs */
dprintf_dc(stddeb,"\tfixed up %08x dce [%04x]\n",
(unsigned)dce, wndCurrent->hwndSelf);
+ dce->DCXflags |= DCX_DCEDIRTY;
SetHookFlags(dce->hDC, DCHF_INVALIDATEVISRGN);
bRet = TRUE;
}
@@ -769,6 +781,7 @@
wnd->flags |= WIN_SAVEUNDER_OVERRIDE;
}
dc->w.flags &= ~DC_DIRTY;
+ dce->DCXflags &= ~DCX_DCEDIRTY;
SelectVisRgn( hdc, hrgnVisible );
}
else
@@ -908,7 +921,8 @@
else
CombineRgn32(hVisRgn, hVisRgn, dce->hClipRgn,
(dce->DCXflags & DCX_EXCLUDERGN)? RGN_DIFF:RGN_AND);
- }
+ }
+ dce->DCXflags &= ~DCX_DCEDIRTY;
SelectVisRgn(hDC, hVisRgn);
DeleteObject32( hVisRgn );
}
diff --git a/windows/defwnd.c b/windows/defwnd.c
index e50d00b..002868a 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -12,6 +12,7 @@
#include "heap.h"
#include "nonclient.h"
#include "winpos.h"
+#include "dce.h"
#include "syscolor.h"
#include "sysmetrics.h"
#include "stddebug.h"
@@ -28,8 +29,6 @@
static short iF10Key = 0;
static short iMenuSysKey = 0;
-extern void EndMenu(void);
-
/***********************************************************************
* DEFWND_HandleWindowPosChanged
*
@@ -91,6 +90,33 @@
return sysColorObjects.hbrushWindow;
}
+
+/***********************************************************************
+ * DEFWND_SetRedraw
+ */
+static void DEFWND_SetRedraw( WND* wndPtr, WPARAM32 wParam )
+{
+ BOOL32 bVisible = wndPtr->dwStyle & WS_VISIBLE;
+
+ if( wParam )
+ {
+ if( !bVisible )
+ {
+ wndPtr->dwStyle |= WS_VISIBLE;
+ DCE_InvalidateDCE( wndPtr->parent, &wndPtr->rectWindow );
+ }
+ }
+ else if( bVisible )
+ {
+ if( wndPtr->dwStyle & WS_MINIMIZE ) wParam = RDW_VALIDATE;
+ else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
+
+ PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam, 0 );
+ DCE_InvalidateDCE( wndPtr->parent, &wndPtr->rectWindow );
+ wndPtr->dwStyle &= ~WS_VISIBLE;
+ }
+}
+
/***********************************************************************
* DEFWND_DefWinProc
*
@@ -167,14 +193,7 @@
}
case WM_SETREDRAW:
- if(wParam)
- SetWindowPos32( wndPtr->hwndSelf, NULL, 0, 0, 0, 0,
- SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
- SWP_NOACTIVATE | SWP_NOREDRAW );
- else
- SetWindowPos32( wndPtr->hwndSelf, NULL, 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
- SWP_NOACTIVATE | SWP_NOREDRAW );
+ DEFWND_SetRedraw( wndPtr, wParam );
return 0;
case WM_CLOSE:
diff --git a/windows/dialog.c b/windows/dialog.c
index b68151e..f469c61 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -66,7 +66,7 @@
*
* Initialisation of the dialog manager.
*/
-BOOL32 DIALOG_Init()
+BOOL32 DIALOG_Init(void)
{
TEXTMETRIC16 tm;
HDC16 hdc;
diff --git a/windows/mdi.c b/windows/mdi.c
index 54babe0..e9e1980 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -1512,7 +1512,7 @@
switch( msg->wParam )
{
case VK_F6:
- case VK_SEPARATOR:
+ case VK_TAB:
wParam = ( GetKeyState32(VK_SHIFT) & 0x8000 )
? SC_NEXTWINDOW : SC_PREVWINDOW;
break;
diff --git a/windows/message.c b/windows/message.c
index 01e0c070..a62ca87 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -37,7 +37,7 @@
extern MESSAGEQUEUE *pCursorQueue; /* queue.c */
extern MESSAGEQUEUE *pActiveQueue;
-extern void JoySendMessages(void);
+extern void joySendMessages(void);
DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
@@ -440,7 +440,7 @@
int i, kbd_msg, pos = sysMsgQueue->nextMessage;
/* FIXME: there has to be a better way to do this */
- JoySendMessages();
+ joySendMessages();
/* If the queue is empty, attempt to fill it */
if (!sysMsgQueue->msgCount && XPending(display))
@@ -1136,7 +1136,7 @@
WND **list, **ppWnd;
LRESULT ret;
- if (hwnd == HWND_BROADCAST)
+ if (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST)
{
if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
return TRUE;
@@ -1178,7 +1178,7 @@
/***********************************************************************
- * SendMessage32W (USER32.458)
+ * SendMessage32W (USER32.459)
*/
LRESULT WINAPI SendMessage32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
LPARAM lParam )
@@ -1187,7 +1187,7 @@
WND **list, **ppWnd;
LRESULT ret;
- if (hwnd == HWND_BROADCAST)
+ if (hwnd == HWND_BROADCAST || hwnd == HWND_TOPMOST)
{
if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
return TRUE;
@@ -1228,6 +1228,42 @@
/***********************************************************************
+ * SendMessageTimeout16 (not a WINAPI)
+ */
+LRESULT WINAPI SendMessageTimeout16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
+ LPARAM lParam, UINT16 flags,
+ UINT16 timeout, LPWORD resultp)
+{
+ fprintf (stdnimp, "SendMessageTimeout16 -- semistub\n");
+ return SendMessage16 (hwnd, msg, wParam, lParam);
+}
+
+
+/***********************************************************************
+ * SendMessageTimeout32A (USER32.457)
+ */
+LRESULT WINAPI SendMessageTimeout32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
+ LPARAM lParam, UINT32 flags,
+ UINT32 timeout, LPDWORD resultp)
+{
+ fprintf (stdnimp, "SendMessageTimeout32A -- semistub\n");
+ return SendMessage32A (hwnd, msg, wParam, lParam);
+}
+
+
+/***********************************************************************
+ * SendMessageTimeout32W (USER32.458)
+ */
+LRESULT WINAPI SendMessageTimeout32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
+ LPARAM lParam, UINT32 flags,
+ UINT32 timeout, LPDWORD resultp)
+{
+ fprintf (stdnimp, "SendMessageTimeout32W -- semistub\n");
+ return SendMessage32W (hwnd, msg, wParam, lParam);
+}
+
+
+/***********************************************************************
* WaitMessage (USER.112) (USER32.577)
*/
void WINAPI WaitMessage( void )
diff --git a/windows/msgbox.c b/windows/msgbox.c
index 627e0cf..f5f90bd 100644
--- a/windows/msgbox.c
+++ b/windows/msgbox.c
@@ -13,14 +13,6 @@
#include "resource.h"
#include "task.h"
-typedef struct
-{
- LPCSTR title;
- LPCSTR text;
- UINT32 type;
-} MSGBOX, *LPMSGBOX;
-
-
/**************************************************************************
* MSGBOX_DlgProc
*
@@ -29,7 +21,8 @@
static LRESULT CALLBACK MSGBOX_DlgProc( HWND32 hwnd, UINT32 message,
WPARAM32 wParam, LPARAM lParam )
{
- LPMSGBOX lpmb;
+ LPMSGBOXPARAMS32A lpmb;
+
RECT32 rect, textrect;
HWND32 hItem;
HDC32 hdc;
@@ -39,11 +32,11 @@
switch(message) {
case WM_INITDIALOG:
- lpmb = (LPMSGBOX)lParam;
- if (lpmb->title) SetWindowText32A(hwnd, lpmb->title);
- SetWindowText32A(GetDlgItem32(hwnd, 100), lpmb->text);
+ lpmb = (LPMSGBOXPARAMS32A)lParam;
+ if (lpmb->lpszCaption) SetWindowText32A(hwnd, lpmb->lpszCaption);
+ SetWindowText32A(GetDlgItem32(hwnd, 100), lpmb->lpszText);
/* Hide not selected buttons */
- switch(lpmb->type & MB_TYPEMASK) {
+ switch(lpmb->dwStyle & MB_TYPEMASK) {
case MB_OK:
ShowWindow32(GetDlgItem32(hwnd, 2), SW_HIDE);
/* fall through */
@@ -71,7 +64,7 @@
break;
}
/* Set the icon */
- switch(lpmb->type & MB_ICONMASK) {
+ switch(lpmb->dwStyle & MB_ICONMASK) {
case MB_ICONEXCLAMATION:
SendDlgItemMessage16(hwnd, stc1, STM_SETICON16,
(WPARAM16)LoadIcon16(0, IDI_EXCLAMATION), 0);
@@ -121,7 +114,7 @@
GetClientRect32(hItem, &rect);
hdc = GetDC32(hItem);
- lRet = DrawText32A( hdc, lpmb->text, -1, &rect,
+ lRet = DrawText32A( hdc, lpmb->lpszText, -1, &rect,
DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_CALCRECT);
theight = rect.bottom - rect.top;
tiheight = 16 + MAX(iheight, theight);
@@ -150,7 +143,7 @@
/* some arithmetic to get the right order for YesNoCancel windows */
hItem = GetDlgItem32(hwnd, (i + 5) % 7 + 1);
if (GetWindowLong32A(hItem, GWL_STYLE) & WS_VISIBLE) {
- if (buttons++ == ((lpmb->type & MB_DEFMASK) >> 8)) {
+ if (buttons++ == ((lpmb->dwStyle & MB_DEFMASK) >> 8)) {
SetFocus32(hItem);
SendMessage32A( hItem, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
}
@@ -195,13 +188,13 @@
*/
INT32 WINAPI MessageBox32A(HWND32 hWnd, LPCSTR text, LPCSTR title, UINT32 type)
{
- MSGBOX mbox;
+ MSGBOXPARAMS32A mbox;
if (!text) text="<WINE-NULL>";
if (!title) title="<WINE-NULL>";
- mbox.title = title;
- mbox.text = text;
- mbox.type = type;
+ mbox.lpszCaption = title;
+ mbox.lpszText = text;
+ mbox.dwStyle = type;
return DialogBoxIndirectParam32A( WIN_GetWindowInstance(hWnd),
SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ),
hWnd, MSGBOX_DlgProc, (LPARAM)&mbox );
@@ -243,6 +236,31 @@
return MessageBox32W(hWnd,text,title,type);
}
+/**************************************************************************
+ * MessageBoxIndirect32A (USER32.394)
+ */
+INT32 WINAPI MessageBoxIndirect32A( LPMSGBOXPARAMS32A msgbox )
+{
+ return DialogBoxIndirectParam32A( msgbox->hInstance,
+ SYSRES_GetResPtr( SYSRES_DIALOG_MSGBOX ),
+ msgbox->hwndOwner, MSGBOX_DlgProc,
+ (LPARAM)msgbox );
+}
+
+/**************************************************************************
+ * MessageBoxIndirect32W (USER32.395)
+ */
+INT32 WINAPI MessageBoxIndirect32W( LPMSGBOXPARAMS32W msgbox )
+{
+ MSGBOXPARAMS32A msgboxa;
+
+ memcpy(&msgboxa,msgbox,sizeof(msgboxa));
+ if (msgbox->lpszCaption) lstrcpyWtoA(msgboxa.lpszCaption,msgbox->lpszCaption);
+ if (msgbox->lpszText) lstrcpyWtoA(msgboxa.lpszText,msgbox->lpszText);
+
+ return MessageBoxIndirect32A(&msgboxa);
+}
+
/**************************************************************************
* FatalAppExit16 (KERNEL.137)
diff --git a/windows/nonclient.c b/windows/nonclient.c
index e9b2489..7bdbce4 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -11,7 +11,7 @@
#include "sysmetrics.h"
#include "user.h"
#include "heap.h"
-#include "shell.h"
+#include "cursoricon.h"
#include "dialog.h"
#include "syscolor.h"
#include "menu.h"
@@ -67,8 +67,6 @@
#define ON_BOTTOM_BORDER(hit) \
(((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
-extern HCURSOR16 CURSORICON_IconToCursor( HICON16, BOOL32 );
-
/***********************************************************************
* NC_AdjustRect
*
diff --git a/windows/painting.c b/windows/painting.c
index 9ab73d4..eeb1c78 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -144,6 +144,10 @@
}
GetRgnBox16( InquireVisRgn(lps->hdc), &lps->rcPaint );
+
+dprintf_win(stddeb,"box = (%i,%i - %i,%i)\n", lps->rcPaint.left, lps->rcPaint.top,
+ lps->rcPaint.right, lps->rcPaint.bottom );
+
DPtoLP16( lps->hdc, (LPPOINT16)&lps->rcPaint, 2 );
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
diff --git a/windows/scroll.c b/windows/scroll.c
index fdc9f4a..b4daae6 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -387,7 +387,7 @@
else if( bUpdate ) hrgnUpdate = CreateRectRgn32( 0, 0, 0, 0 );
hDC = GetDCEx32( hwnd, hrgnClip, DCX_CACHE | DCX_USESTYLE |
- (flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0 );
+ ((flags & SW_SCROLLCHILDREN) ? DCX_NOCLIPCHILDREN : 0) );
if( (dc = (DC *)GDI_GetObjPtr(hDC, DC_MAGIC)) )
{
POINT32 dst, src;
diff --git a/windows/win.c b/windows/win.c
index 5f6fbc0..c8ac1c4 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -45,11 +45,7 @@
extern BOOL32 ICONTITLE_Init(void);
extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
-extern HCURSOR16 CURSORICON_IconToCursor(HICON16, BOOL32);
extern HWND32 CARET_GetHwnd(void);
-extern BOOL32 WINPOS_CreateInternalPosAtom(void);
-extern void WINPOS_CheckInternalPos(HWND32);
-extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
extern BOOL32 EVENT_CheckFocus(void);
/***********************************************************************
@@ -623,8 +619,17 @@
if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
}
- if (cs->cx <= 0) cs->cx = 1;
- if (cs->cy <= 0) cs->cy = 1;
+
+ if(cs->style & WS_CHILD)
+ {
+ if(cs->cx < 0) cs->cx = 0;
+ if(cs->cy < 0) cs->cy = 0;
+ }
+ else
+ {
+ if (cs->cx <= 0) cs->cx = 1;
+ if (cs->cy <= 0) cs->cy = 1;
+ }
wndPtr->rectWindow.left = cs->x;
wndPtr->rectWindow.top = cs->y;
@@ -1148,13 +1153,15 @@
return 0;
}
+
for ( ; pWnd; pWnd = pWnd->next)
{
if (className && !(pWnd->dwStyle & WS_CHILD))
{
- if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
+ if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
continue; /* Skip this window */
}
+
if (pClass && (pWnd->class != pClass))
continue; /* Not the right class */
diff --git a/windows/winhelp.c b/windows/winhelp.c
index 3b0576f..d8521d4 100644
--- a/windows/winhelp.c
+++ b/windows/winhelp.c
@@ -28,21 +28,28 @@
BOOL32 WINAPI WinHelp32A( HWND32 hWnd, LPCSTR lpHelpFile, UINT32 wCommand,
DWORD dwData )
{
- static WORD WM_WINHELP=0;
+ static WORD WM_WINHELP = 0;
HWND32 hDest;
LPWINHELP lpwh;
HGLOBAL16 hwh;
int size,dsize,nlen;
if (wCommand != HELP_QUIT) /* FIXME */
- if(WinExec32("winhelp.exe -x",SW_SHOWNORMAL)<=32)
+ {
+ if (WinExec32("winhelp.exe -x",SW_SHOWNORMAL) <= 32)
return FALSE;
- /* FIXME: Should be directed yield, to let winhelp open the window */
- Yield16();
- if(!WM_WINHELP) {
+
+ /* NOTE: Probably, this should be directed yield,
+ to let winhelp open the window in all cases. */
+ Yield16();
+ }
+
+ if(!WM_WINHELP)
+ {
WM_WINHELP=RegisterWindowMessage32A("WM_WINHELP");
if(!WM_WINHELP)
return FALSE;
}
+
hDest = FindWindow32A( "MS_WINHELP", NULL );
if(!hDest)
if(wCommand == HELP_QUIT)
diff --git a/windows/winproc.c b/windows/winproc.c
index 259b384..1402b6c 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -76,18 +76,18 @@
(WNDPROC16)((pproc)->thunk.t_from32.proc) : \
(WNDPROC16)((pproc)->thunk.t_from16.proc))
-LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
- WPARAM16 wParam, LPARAM lParam,
- WNDPROC32 func );
-LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
- WPARAM16 wParam, LPARAM lParam,
- WNDPROC32 func );
static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
UINT32 msg, WPARAM32 wParam,
LPARAM lParam );
static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
UINT32 msg, WPARAM32 wParam,
LPARAM lParam );
+static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
+ WPARAM16 wParam, LPARAM lParam,
+ WNDPROC32 func );
+static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
+ WPARAM16 wParam, LPARAM lParam,
+ WNDPROC32 func );
static HANDLE32 WinProcHeap;
@@ -739,8 +739,13 @@
*plparam = (LPARAM)(HMENU32)HIWORD(*plparam);
return 0;
case WM_MDIACTIVATE:
- *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
- *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
+ if( *plparam )
+ {
+ *pwparam32 = (WPARAM32)(HWND32)HIWORD(*plparam);
+ *plparam = (LPARAM)(HWND32)LOWORD(*plparam);
+ }
+ else /* message sent to MDI client */
+ *pwparam32 = wParam16;
return 0;
case WM_NCCALCSIZE:
{
@@ -1343,9 +1348,17 @@
*plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
return 0;
case WM_MDIACTIVATE:
- *pwparam16 = ((HWND32)*plparam == hwnd);
- *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
- (HWND16)LOWORD(wParam32) );
+ if( WIDGETS_IsControl32(WIN_FindWndPtr(hwnd), BIC32_MDICLIENT) )
+ {
+ *pwparam16 = (HWND32)wParam32;
+ *plparam = 0;
+ }
+ else
+ {
+ *pwparam16 = ((HWND32)*plparam == hwnd);
+ *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
+ (HWND16)LOWORD(wParam32) );
+ }
return 0;
case WM_NCCALCSIZE:
{