From 44ed71f52f783a91bb2a44085444ce14438c515a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 21 Dec 1997 19:17:50 +0000 Subject: [PATCH] Release 971221 Fri Dec 19 10:50:46 1997 Douglas Ridgway * [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 * [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 * [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 * [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 * [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 * [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 * [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 * [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 * [file/drive.c] First attempt for GetDiskFreeSpaceEx. Fri Dec 12 23:18:41 1997 Marcus Meissner * [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 * [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 * [*/*.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 instead of . * [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 * [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. --- ANNOUNCE | 20 +- AUTHORS | 1 + BUGS | 12 +- ChangeLog | 262 +++++ Make.rules.in | 5 + Makefile.in | 13 +- configure | 6 +- configure.in | 4 +- controls/edit.c | 2 +- controls/menu.c | 4 +- controls/uitools.c | 1536 +++++++++++++++++++++++----- debugger/info.c | 8 +- documentation/Makefile.in | 12 +- documentation/README.documentation | 122 +++ documentation/how-to-port | 135 +++ files/dos_fs.c | 29 +- files/drive.c | 51 + files/file.c | 15 +- files/profile.c | 23 + graphics/Makefile.in | 2 + graphics/cache.c | 41 + graphics/metafiledrv/init.c | 23 +- graphics/painting.c | 261 ++++- graphics/path.c | 704 +++++++++++++ graphics/win16drv/graphics.c | 7 +- graphics/win16drv/init.c | 4 +- graphics/wing.c | 2 +- graphics/x11drv/graphics.c | 13 +- graphics/x11drv/init.c | 2 - graphics/x11drv/pen.c | 16 +- graphics/x11drv/xfont.c | 65 +- if1632/Makefile.in | 27 +- if1632/builtin.c | 459 ++------- if1632/kernel.spec | 18 +- if1632/mmsystem.spec | 46 +- if1632/ole2thk.spec | 10 + if1632/relay.c | 202 ---- if1632/thunk.c | 611 +---------- if1632/toolhelp.spec | 6 +- if1632/user.spec | 4 +- if1632/win32s16.spec | 6 +- if1632/windebug.spec | 6 + if1632/winsock.spec | 18 +- include/builtin32.h | 31 + include/cache.h | 17 + include/callback.h | 4 +- include/color.h | 3 + include/compobj.h | 2 +- include/config.h.in | 3 + include/cursoricon.h | 3 + include/dce.h | 1 + include/debug.h | 65 +- include/gdi.h | 10 +- include/interfaces.h | 76 +- include/mmsystem.h | 186 +++- include/ntdll.h | 21 + include/path.h | 45 + include/pe_image.h | 2 +- include/shell.h | 30 +- include/shlobj.h | 231 ++++- include/stddebug.h | 2 + include/task.h | 1 + include/toolhelp.h | 12 + include/user.h | 3 + include/version.h | 2 +- include/windows.h | 263 ++++- include/winerror.h | 15 + include/winnt.h | 6 + include/winpos.h | 3 + include/winsock.h | 133 ++- include/wintypes.h | 1 + include/x11drv.h | 2 + loader/module.c | 10 +- loader/ne_image.c | 7 +- loader/pe_image.c | 35 +- loader/pe_resource.c | 27 +- loader/task.c | 4 +- memory/heap.c | 3 +- memory/selector.c | 43 +- memory/virtual.c | 15 +- misc/Makefile.in | 2 + misc/callback.c | 18 +- misc/commdlg.c | 12 +- misc/cpu.c | 25 +- misc/crtdll.c | 37 +- misc/lstr.c | 56 +- misc/main.c | 2 +- misc/network.c | 2 +- misc/port.c | 8 + misc/printdrv.c | 8 + misc/shell.c | 157 ++- misc/shellord.c | 384 ++++--- misc/toolhelp.c | 15 + misc/ver.c | 24 +- misc/w32scomb.c | 3 +- misc/w32skrnl.c | 4 +- misc/win32s16.c | 16 + misc/windebug.c | 20 + misc/winsock.c | 545 ++++++---- misc/winsock_dns.c | 78 +- miscemu/instr.c | 11 +- msdos/int13.c | 8 +- multimedia/audio.c | 2 +- multimedia/joystick.c | 231 ++++- multimedia/mcianim.c | 2 +- multimedia/mcicda.c | 2 +- multimedia/mcistring.c | 34 +- multimedia/midi.c | 2 +- multimedia/mixer.c | 9 +- multimedia/mmsystem.c | 308 ++++-- multimedia/time.c | 157 ++- objects/bitmap.c | 23 + objects/brush.c | 9 + objects/cursoricon.c | 23 +- objects/dc.c | 151 ++- objects/dib.c | 3 + objects/gdiobj.c | 52 +- objects/metafile.c | 6 + objects/palette.c | 13 +- objects/pen.c | 24 + objects/text.c | 141 ++- ole/Makefile.in | 3 +- ole/folders.c | 174 ++++ ole/ifs.c | 136 +++ programs/Makefile.in | 6 +- programs/notepad/ChangeLog | 5 + programs/notepad/De.rc | 91 ++ programs/notepad/En.rc | 91 ++ programs/notepad/License_En.c | 48 + programs/notepad/Makefile.in | 47 + programs/notepad/README | 19 + programs/notepad/TODO | 8 + programs/notepad/license.c | 45 + programs/notepad/license.h | 29 + programs/notepad/notepad.rc | 58 ++ rc/winerc.c | 2 +- relay32/Makefile.in | 63 ++ {if1632 => relay32}/advapi32.spec | 0 relay32/builtin32.c | 379 +++++++ {if1632 => relay32}/comctl32.spec | 0 {if1632 => relay32}/comdlg32.spec | 0 {if1632 => relay32}/crtdll.spec | 2 +- relay32/dciman32.spec | 25 + {if1632 => relay32}/gdi32.spec | 24 +- {if1632 => relay32}/kernel32.spec | 26 +- {if1632 => relay32}/lz32.spec | 0 {if1632 => relay32}/mpr.spec | 0 relay32/msvfw32.spec | 52 + {if1632 => relay32}/ntdll.spec | 0 {if1632 => relay32}/ole32.spec | 14 +- {if1632 => relay32}/olecli32.spec | 0 {if1632 => relay32}/olesvr32.spec | 0 relay32/relay386.c | 203 ++++ {if1632 => relay32}/shell32.spec | 30 +- relay32/tapi32.spec | 117 +++ {if1632 => relay32}/user32.spec | 14 +- {if1632 => relay32}/version.spec | 0 {if1632 => relay32}/w32skrnl.spec | 0 {if1632 => relay32}/winmm.spec | 28 +- {if1632 => relay32}/winspool.spec | 2 +- relay32/wow32.spec | 20 + {if1632 => relay32}/wsock32.spec | 22 +- resources/sysres_De.rc | 12 +- scheduler/process.c | 5 +- tools/build.c | 228 ++--- win32/Makefile.in | 1 + win32/code_page.c | 100 +- win32/console.c | 78 +- win32/environment.c | 4 +- win32/kernel32.c | 663 ++++++++++++ win32/newfns.c | 11 + win32/ordinals.c | 3 - win32/thread.c | 2 +- windows/dce.c | 24 +- windows/defwnd.c | 39 +- windows/dialog.c | 2 +- windows/mdi.c | 2 +- windows/message.c | 46 +- windows/msgbox.c | 58 +- windows/nonclient.c | 4 +- windows/painting.c | 4 + windows/scroll.c | 2 +- windows/win.c | 21 +- windows/winhelp.c | 17 +- windows/winproc.c | 35 +- 185 files changed, 9077 insertions(+), 2824 deletions(-) create mode 100644 documentation/README.documentation create mode 100644 documentation/how-to-port create mode 100644 graphics/cache.c create mode 100644 graphics/path.c create mode 100644 if1632/ole2thk.spec create mode 100644 if1632/windebug.spec create mode 100644 include/builtin32.h create mode 100644 include/cache.h create mode 100644 include/path.h create mode 100644 misc/win32s16.c create mode 100644 misc/windebug.c create mode 100644 ole/folders.c create mode 100644 ole/ifs.c create mode 100644 programs/notepad/ChangeLog create mode 100644 programs/notepad/De.rc create mode 100644 programs/notepad/En.rc create mode 100644 programs/notepad/License_En.c create mode 100644 programs/notepad/Makefile.in create mode 100644 programs/notepad/README create mode 100644 programs/notepad/TODO create mode 100644 programs/notepad/license.c create mode 100644 programs/notepad/license.h create mode 100644 programs/notepad/notepad.rc create mode 100644 relay32/Makefile.in rename {if1632 => relay32}/advapi32.spec (100%) create mode 100644 relay32/builtin32.c rename {if1632 => relay32}/comctl32.spec (100%) rename {if1632 => relay32}/comdlg32.spec (100%) rename {if1632 => relay32}/crtdll.spec (99%) create mode 100644 relay32/dciman32.spec rename {if1632 => relay32}/gdi32.spec (96%) rename {if1632 => relay32}/kernel32.spec (97%) rename {if1632 => relay32}/lz32.spec (100%) rename {if1632 => relay32}/mpr.spec (100%) create mode 100644 relay32/msvfw32.spec rename {if1632 => relay32}/ntdll.spec (100%) rename {if1632 => relay32}/ole32.spec (92%) rename {if1632 => relay32}/olecli32.spec (100%) rename {if1632 => relay32}/olesvr32.spec (100%) create mode 100644 relay32/relay386.c rename {if1632 => relay32}/shell32.spec (91%) create mode 100644 relay32/tapi32.spec rename {if1632 => relay32}/user32.spec (98%) rename {if1632 => relay32}/version.spec (100%) rename {if1632 => relay32}/w32skrnl.spec (100%) rename {if1632 => relay32}/winmm.spec (91%) rename {if1632 => relay32}/winspool.spec (98%) create mode 100644 relay32/wow32.spec rename {if1632 => relay32}/wsock32.spec (78%) create mode 100644 win32/kernel32.c diff --git a/ANNOUNCE b/ANNOUNCE index 93c7b241d33..3f2c3595c6d 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 @@ Because of lags created by using mirror, this message may reach you before the release is available at the ftp sites. The sources will be available from the following locations: - 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 cd18940e3d2..616a2e62cbc 100644 --- a/AUTHORS +++ b/AUTHORS @@ -102,6 +102,7 @@ Rick Sladkey, William Smith, Dominik Strasser, Vadim Strizhevsky, +Bertho Stultiens, Erik Svendsen, Tristan Tarrant, Andrew Taylor, diff --git a/BUGS b/BUGS index cc9b8c0a45c..8e339b25f30 100644 --- a/BUGS +++ b/BUGS @@ -5,7 +5,7 @@ done something for one of the problems. You are encouraged to 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 @@ General: 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 @@ Miscellaneous: (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 @@ Miscellaneous: * 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 76ac4baf3ef..aad647d1ecf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,265 @@ +---------------------------------------------------------------------- +Fri Dec 19 10:50:46 1997 Douglas Ridgway + + * [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 + + * [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 + + * [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 + + * [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 + + * [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 + + * [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 + + * [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 + + * [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 + + * [file/drive.c] + First attempt for GetDiskFreeSpaceEx. + +Fri Dec 12 23:18:41 1997 Marcus Meissner + + * [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 + + * [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 + + * [*/*.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 instead of . + + * [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 + + * [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 diff --git a/Make.rules.in b/Make.rules.in index e27e88b82d5..7b1e7d7f1bf 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -36,6 +36,7 @@ LDCOMBINE = ld -r 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 @@ $(BUILD) checkbuild: $(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 c326756d4f1..c34c3b6f524 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 @@ MODULE = none LIBSUBDIRS = \ rc \ + tools \ controls \ files \ graphics \ @@ -44,11 +46,11 @@ LIBSUBDIRS = \ windows EMUSUBDIRS = \ - tools \ debugger \ graphics/win16drv \ if1632 \ - miscemu + miscemu \ + relay32 PROGSUBDIRS = libtest programs @@ -90,7 +92,8 @@ EMUOBJS = \ 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 @@ depend:: dummy 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 5699464ff4f..1032ff2e6ce 100755 --- a/configure +++ b/configure @@ -2070,7 +2070,7 @@ fi -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 @@ multimedia/Makefile 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 @@ multimedia/Makefile 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 8c1186ce811..11b26ab7b54 100644 --- a/configure.in +++ b/configure.in @@ -114,7 +114,7 @@ AC_SUBST(DLLFLAGS) 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 @@ multimedia/Makefile 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 b4cd3ac12ef..303d2f1f70e 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -3494,7 +3494,7 @@ static LRESULT EDIT_WM_LButtonDown(WND *wnd, EDITSTATE *es, DWORD keys, INT32 x, 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 35a89f18a4c..8c2e984af37 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -3878,7 +3878,7 @@ BOOL16 WINAPI InsertMenuItem16( HMENU16 hmenu, UINT16 pos, BOOL16 byposition, 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 InsertMenuItem32A(HMENU32 hMenu, UINT32 uItem, BOOL32 bypos, 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 b245ebc810c..e3c64de36e9 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 #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 @@ static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, RECT32 *rect, UINT32 edge, * 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 @@ BOOL32 WINAPI DrawEdge32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags ) } +/************************************************************************ + * 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 @@ BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType, 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 f5c4d4c4866..a1cb3787a32 100644 --- a/debugger/info.c +++ b/debugger/info.c @@ -141,7 +141,7 @@ void DEBUG_Help(void) " delete display \n", "Wine-specific commands:", -" mode [16,32] walk [wnd,class,queue] ", +" 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 @@ void DEBUG_HelpInfo(void) " 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 Dumps queue information", +" info module Displays internal module state", +" info queue 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 Dumps information about all windows", +" info wnd Displays internal window state", "", NULL }; diff --git a/documentation/Makefile.in b/documentation/Makefile.in index fe1be2bff58..602615833be 100644 --- a/documentation/Makefile.in +++ b/documentation/Makefile.in @@ -22,6 +22,10 @@ DVIFILES = wine.dvi all: $(INFOFILES) $(DVIFILES) +info: $(INFOFILES) + +dvi: $(DVIFILES) + @MAKE_RULES@ $(INFOFILES): $(SOURCES) @@ -34,13 +38,17 @@ $(INCLUDES): $(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 00000000000..6a91dc698bd --- /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 00000000000..5800f92ee0f --- /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 ", 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 + +to + + #ifdef HAVE_FOO_H + #include + #elif defined (HAVE_BAR_H) + #include + #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 2ace4e0547d..5cd8e762bf2 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -373,15 +374,15 @@ static BOOL32 DOSFS_ReadDir( DOS_DIR *dir, LPCSTR *long_name, #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 @@ BOOL32 DOSFS_FindUnixName( LPCSTR path, LPCSTR name, LPSTR long_buf, 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 @@ static DWORD DOSFS_DoGetFullPathName( LPCSTR name, DWORD len, LPSTR result, 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 f874df833ae..0fd582d096e 100644 --- a/files/drive.c +++ b/files/drive.c @@ -652,6 +652,57 @@ BOOL32 WINAPI GetDiskFreeSpace32W( LPCWSTR root, LPDWORD cluster_sectors, } +/*********************************************************************** + * 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) */ diff --git a/files/file.c b/files/file.c index cdbbe55c9dc..10380e81ee2 100644 --- a/files/file.c +++ b/files/file.c @@ -147,7 +147,7 @@ void FILE_SetDosError(void) 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 @@ UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique, 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 @@ UINT16 WINAPI GetTempFileName16( BYTE drive, LPCSTR prefix, UINT16 unique, } 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 @@ static BOOL32 DOS_AddLock(FILE_OBJECT *file, struct flock *f) /* 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 875a5900604..545049d3834 100644 --- a/files/profile.c +++ b/files/profile.c @@ -942,6 +942,8 @@ INT32 WINAPI GetPrivateProfileString32A( LPCSTR section, LPCSTR entry, 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 @@ BOOL32 WINAPI WritePrivateProfileString32W( LPCWSTR section, LPCWSTR entry, 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 5912d90fdb6..3784c524e30 100644 --- a/graphics/Makefile.in +++ b/graphics/Makefile.in @@ -7,12 +7,14 @@ MODULE = graphics 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 00000000000..5d0f1843874 --- /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 b187bce5e8d..f60fe08c521 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 @@ static const DC_FUNCTIONS MFDRV_Funcs = 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 @@ static BOOL32 MFDRV_DeleteDC( DC *dc ) 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 @@ HDC16 WINAPI CreateMetaFile16( LPCSTR filename ) 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 @@ HMETAFILE16 WINAPI CloseMetaFile16( HDC16 hdc ) 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 @@ HMETAFILE16 WINAPI CloseMetaFile16( HDC16 hdc ) if (!MF_MetaParam0(dc, META_EOF)) { - DeleteDC32( hdc ); + MFDRV_DeleteDC( dc ); return 0; } @@ -205,13 +204,13 @@ HMETAFILE16 WINAPI CloseMetaFile16( HDC16 hdc ) 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 @@ HMETAFILE16 WINAPI CloseMetaFile16( HDC16 hdc ) 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 15cb841964d..9b169e4e525 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 @@ -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 @@ BOOL32 WINAPI LineTo32( HDC32 hdc, INT32 x, INT32 y ) { 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 @@ BOOL32 WINAPI MoveToEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt ) { 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 @@ BOOL32 WINAPI FloodFill32( HDC32 hdc, INT32 x, INT32 y, COLORREF color ) /********************************************************************** - * DrawFrameControl32 (USER32.152) + * DrawAnimatedRects32 (USER32.153) */ BOOL32 WINAPI DrawAnimatedRects32( HWND32 hwnd, int idAni, const LPRECT32 lprcFrom, @@ -691,13 +695,238 @@ BOOL32 WINAPI DrawAnimatedRects32( HWND32 hwnd, int idAni, 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 00000000000..e4e40135b57 --- /dev/null +++ b/graphics/path.c @@ -0,0 +1,704 @@ +/* + * Graphics paths (BeginPath, EndPath etc.) + * + * Copyright 1997 Martin Boehme + */ + +#include +#include + +#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(nSizenumEntriesUsed) + { + 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; inumEntriesUsed; 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; inumEntriesUsed; 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(numEntriesToAllocatepPoints) + { + 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 ec2a72e8bfa..2452542a67e 100644 --- a/graphics/win16drv/graphics.c +++ b/graphics/win16drv/graphics.c @@ -4,8 +4,11 @@ * Copyright 1997 John Harvey */ +#include #include "heap.h" #include "win16drv.h" +#include "stddebug.h" +#include "debug.h" /********************************************************************** * WIN16DRV_MoveToEx @@ -57,9 +60,9 @@ WIN16DRV_Rectangle(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom) 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 62811862e30..e00e638713c 100644 --- a/graphics/win16drv/init.c +++ b/graphics/win16drv/init.c @@ -386,8 +386,8 @@ BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output, 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 58be55439bc..f2b71dd624e 100644 --- a/graphics/wing.c +++ b/graphics/wing.c @@ -44,7 +44,7 @@ static int __WinGOK = -1; 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 ec80312f7ac..9348d91223e 100644 --- a/graphics/x11drv/graphics.c +++ b/graphics/x11drv/graphics.c @@ -250,11 +250,14 @@ X11DRV_Rectangle(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom) 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 6cfd5a1bb4d..e4151048401 100644 --- a/graphics/x11drv/init.c +++ b/graphics/x11drv/init.c @@ -108,8 +108,6 @@ static DeviceCaps X11DRV_DevCaps = { */ 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 85165691b52..3a424cf7d16 100644 --- a/graphics/x11drv/pen.c +++ b/graphics/x11drv/pen.c @@ -13,6 +13,7 @@ static const char PEN_dash[] = { 5,3 }; /* ----- ----- ----- */ 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 X11DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen ) 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 @@ HPEN32 X11DRV_PEN_SelectObject( DC * dc, HPEN32 hpen, PENOBJ * pen ) 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 9b988cf155b..be3bb664f32 100644 --- a/graphics/x11drv/xfont.c +++ b/graphics/x11drv/xfont.c @@ -170,13 +170,14 @@ static UINT16 __lfCheckSum( LPLOGFONT16 plf ) 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 @@ static void XFONT_SetFontMetric(fontInfo* fi, fontResource* fr, XFontStruct* xfs 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 @@ static void XFONT_WindowsNames( char* buffer ) } 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 @@ static BOOL32 XFONT_ReadCachedMetrics( int fd, int res, unsigned x_checksum, int 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 @@ static void XFONT_CheckIniCallback( /* 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 @@ BOOL32 X11DRV_FONT_Init( DeviceCaps* pDevCaps ) #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 @@ static UINT32 XFONT_Match( fontMatch* pfm ) 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 @@ static UINT32 XFONT_MatchFIList( fontMatch* pfm ) { 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 63fb303d551..26e1e7a6ece 100644 --- a/if1632/Makefile.in +++ b/if1632/Makefile.in @@ -6,56 +6,39 @@ VPATH = @srcdir@ 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 @@ C_SRCS = \ GEN_ASM_SRCS = \ $(SPEC_FILES) \ - call32.s \ callfrom16.s \ callto16.s @@ -86,9 +68,6 @@ $(SPEC_FILES): $(BUILD) 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 f51400470dc..273908a9b56 100644 --- a/if1632/builtin.c +++ b/if1632/builtin.c @@ -8,6 +8,7 @@ #include #include #include "windows.h" +#include "builtin32.h" #include "gdi.h" #include "global.h" #include "heap.h" @@ -34,158 +35,89 @@ typedef struct 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 */ @@ -242,188 +174,6 @@ static HMODULE16 BUILTIN_DoLoadModule16( const WIN16_DESCRIPTOR *descr ) } -/*********************************************************************** - * 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 * @@ -431,22 +181,15 @@ static HMODULE32 BUILTIN_DoLoadModule32( BUILTIN_DLL *dll ) */ 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 @@ BOOL32 BUILTIN_Init(void) */ 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 @@ HMODULE32 BUILTIN_LoadModule( LPCSTR name, BOOL32 force ) 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 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd ) } -/*********************************************************************** - * 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 @@ void BUILTIN_DefaultIntHandler( CONTEXT *context ) */ BOOL32 BUILTIN_ParseDLLOptions( const char *str ) { - BUILTIN_DLL *dll; + BUILTIN16_DLL *dll; const char *p; while (*str) @@ -685,7 +386,7 @@ BOOL32 BUILTIN_ParseDLLOptions( const char *str ) 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 c7fa8da5796..db1dae26ab4 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -213,16 +213,16 @@ file krnl386.exe 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 @@ file krnl386.exe 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 c0178e11ac4..cd9889a737a 100644 --- a/if1632/mmsystem.spec +++ b/if1632/mmsystem.spec @@ -12,14 +12,14 @@ type win16 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 @@ type win16 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 @@ type win16 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 @@ type win16 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 00000000000..e945a98b480 --- /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 a49114de647..6596be52efe 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -232,208 +232,6 @@ void RELAY_DebugCallTo16( int* stack, int nb_args ) } -/*********************************************************************** - * 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 4a9a446987c..5bb6eba462c 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 #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 @@ extern void CallFrom16_long_wwwll(void); /* 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 @@ static const CALLBACKS_TABLE CALLBACK_EmulatorTable = (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 @@ static void THUNK_Free( THUNK *thunk ) 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 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, 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 @@ FARPROC16 WINAPI THUNK_SetResourceHandler( HMODULE16 hModule, SEGPTR typeId, FAR } 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(,%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;ilong registers. - * - * 665A pop edx - * 6668x arg2 x pushl - * 6652 push edx - * EAx arg1 x jmpf - * - * 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 c3837e971ef..9940d9979d4 100644 --- a/if1632/toolhelp.spec +++ b/if1632/toolhelp.spec @@ -17,9 +17,9 @@ type win16 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 fef3bfc91c3..814a19f8704 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -346,7 +346,7 @@ file user.exe 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 @@ file user.exe 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 2457c8847e9..a82aff27c1a 100644 --- a/if1632/win32s16.spec +++ b/if1632/win32s16.spec @@ -2,7 +2,7 @@ name win32s16 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 @@ type win16 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 00000000000..7b4fb6b88b1 --- /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 2548e10c70e..e8564bb8e89 100644 --- a/if1632/winsock.spec +++ b/if1632/winsock.spec @@ -16,7 +16,7 @@ type win16 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 @@ type win16 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 00000000000..56532a374dd --- /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 00000000000..aa10b037cc0 --- /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 86b604f004f..c02abcc66d2 100644 --- a/include/callback.h +++ b/include/callback.h @@ -19,7 +19,8 @@ extern int (*IF1632_CallLargeStack)( int (*func)(), void *arg ); 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 @@ typedef struct 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 735e62935a1..d226a199206 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 BOOL32 COLOR_IsSolid( COLORREF color ); 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 9aca77141f3..6f2289f8cea 100644 --- a/include/compobj.h +++ b/include/compobj.h @@ -11,7 +11,7 @@ struct tagGUID 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 12cd82d44c2..2d301c7bab2 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 14c34b8352a..691487ee58a 100644 --- a/include/cursoricon.h +++ b/include/cursoricon.h @@ -50,6 +50,9 @@ typedef struct #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 11d235ff304..089ad22cd8d 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 365c0ea580a..a34519db29b 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 @@ short debug_msg_enabled[]={ #else 0, #endif +#ifdef DEBUG_THUNK + 1, +#else + 0, +#endif #ifdef DEBUG_TIMER 1, #else @@ -1539,8 +1546,21 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ extern short debug_msg_enabled[]; #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 @@ static char *debug_msg_name[] = { "string", "task", "text", + "thunk", "timer", "toolhelp", "tweak", diff --git a/include/gdi.h b/include/gdi.h index d744a415302..ed90b94ac4b 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 @@ typedef struct HBITMAP16 hFirstBitmap; /* Bitmap selected at creation of the DC */ HANDLE16 hDevice; HPALETTE16 hPalette; + + GdiPath path; WORD ROPmode; WORD polyFillMode; @@ -246,7 +249,7 @@ typedef struct tagDC_FUNCS /* 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 @@ typedef struct tagDC_FUNCS #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 5e912daa9d9..ef70a22ae48 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_IRootStorage,0x12,0,0); 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 fa5a50b7ad4..6845f3594e3 100644 --- a/include/mmsystem.h +++ b/include/mmsystem.h @@ -18,6 +18,7 @@ typedef LPCSTR HPCSTR; /* a huge version of LPCSTR */ #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 @@ DECL_WINELIB_TYPE(MMVERSION); 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 @@ DWORD WINAPI auxOutMessage32(UINT32,UINT32,DWORD,DWORD); #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 @@ UINT16 WINAPI timeEndPeriod(UINT16 uPeriod); #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 @@ typedef struct { 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 @@ typedef struct { } 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 @@ BOOL16 WINAPI DriverCallback(DWORD dwCallBack, UINT16 uFlags, HANDLE16 hDev, 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 2f1bf8b91ee..28f35837ddb 100644 --- a/include/ntdll.h +++ b/include/ntdll.h @@ -156,6 +156,27 @@ typedef struct _UNICODE_STRING { 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 00000000000..fbf00e12598 --- /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 b432c833f15..b6876e9601a 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -41,6 +41,6 @@ extern HGLOBAL32 PE_LoadResource32(HINSTANCE32,HRSRC32); 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 2ddf3a33e2e..ee0ba36ff7b 100644 --- a/include/shell.h +++ b/include/shell.h @@ -32,6 +32,16 @@ typedef struct { /* structure for dropped files */ /* 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 @@ typedef struct _AppBarData { 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 @@ DWORD WINAPI SHGetFileInfo32W(LPCWSTR,DWORD,SHFILEINFO32W*,UINT32,UINT32); #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 bb06efed492..d51a190ddf6 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_IFileViewer, 0x000214F0L, 0, 0); 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 @@ typedef struct { 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 8f73efcf770..0f519949f42 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 ef541355bfc..460f5dea362 100644 --- a/include/task.h +++ b/include/task.h @@ -131,5 +131,6 @@ extern HTASK16 TASK_CreateTask( HMODULE16 hModule, HINSTANCE16 hInstance, 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 8d1cd81638a..1d2ddb701aa 100644 --- a/include/toolhelp.h +++ b/include/toolhelp.h @@ -348,6 +348,18 @@ typedef struct { 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 68e023f3ef5..b235b76adf8 100644 --- a/include/user.h +++ b/include/user.h @@ -24,5 +24,8 @@ extern WORD USER_HeapSel; ((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 b0cfc85f1b7..d3413e2e8bf 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 997208a4c6a..86cb5b85d6b 100644 --- a/include/windows.h +++ b/include/windows.h @@ -1591,13 +1591,30 @@ typedef struct 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 @@ typedef struct { 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 @@ typedef struct tagCOMSTAT #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 @@ DECL_WINELIB_TYPE_AW(LPMENUITEMINFO); #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 @@ DECL_WINELIB_TYPE_AW(LPMENUITEMINFO); #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 @@ typedef BOOL32 (CALLBACK *DRAWSTATEPROC)(HDC32,LPARAM,WPARAM32,INT32,INT32); #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 @@ typedef struct 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 @@ typedef struct _SYSTEM_POWER_STATUS #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 @@ typedef struct _LDT_ENTRY { } 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 @@ WORD WINAPI GetExpWinVer(HMODULE16); 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 @@ HGLOBAL16 WINAPI LoadDIBIconHandler(HGLOBAL16,HMODULE16,HRSRC16); 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 CreateFile32A(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES, 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 @@ BOOL32 WINAPI FileTimeToSystemTime(const FILETIME*,LPSYSTEMTIME); 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 GetCommTimeouts(INT32,LPCOMMTIMEOUTS); 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 GetFileType(HFILE32); 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 @@ DWORD WINAPI HeapSize(HANDLE32,DWORD,LPVOID); 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 @@ DWORD WINAPI SearchPath32W(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*); 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 VirtualProtectEx(HANDLE32,LPVOID,DWORD,DWORD,LPDWORD); 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 @@ VOID WINAPI WaitMessage(VOID); /* 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 @@ HDWP32 WINAPI BeginDeferWindowPos32(INT32); 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 @@ BOOL32 WINAPI ClipCursor32(const RECT32*); 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 @@ INT32 WINAPI EndDoc32(HDC32); 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 @@ INT32 WINAPI ExcludeUpdateRgn32(HDC32,HWND32); 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 FatalAppExit16(UINT16,LPCSTR); 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 @@ HINSTANCE32 WINAPI FindExecutable32W(LPCWSTR,LPCWSTR,LPWSTR); 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 @@ HWND32 WINAPI GetDesktopWindow32(void); 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 @@ UINT32 WINAPI GetPaletteEntries32(HPALETTE32,UINT32,UINT32,LPPALETTEENTRY); 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 @@ INT16 WINAPI MessageBox16(HWND16,LPCSTR,LPCSTR,UINT16); 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 @@ BOOL32 WINAPI PaintRgn32(HDC32,HRGN32); 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 @@ INT16 WINAPI ScrollWindowEx16(HWND16,INT16,INT16,const RECT16*, 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 SendMessage16(HWND16,UINT16,WPARAM16,LPARAM); 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 @@ BOOL32 WINAPI SetCursorPos32(INT32,INT32); 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 ce1a3fe8ab3..dd2f3f33ce4 100644 --- a/include/winerror.h +++ b/include/winerror.h @@ -17,6 +17,7 @@ extern int WIN32_LastError; #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 @@ extern int WIN32_LastError; #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 @@ extern int WIN32_LastError; #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 a23df14bd1b..0d532993260 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 f07431e4383..a572d932281 100644 --- a/include/winpos.h +++ b/include/winpos.h @@ -41,5 +41,8 @@ extern LONG WINPOS_SendNCCalcSize(HWND32 hwnd, BOOL32 calcValidRect, 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 d20265553a2..edee250c770 100644 --- a/include/winsock.h +++ b/include/winsock.h @@ -61,46 +61,62 @@ typedef struct { 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 @@ typedef struct ws_addr_in #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 @@ INT32 WINAPI WSAUnhookBlockingHook32(void); 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 @@ typedef struct __aop /* 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 @@ typedef struct __aop #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 @@ typedef struct __sop /* WSAAsyncSelect() control struct */ 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 50921576ef9..a5ab5562bdd 100644 --- a/include/wintypes.h +++ b/include/wintypes.h @@ -88,6 +88,7 @@ typedef int INT32; 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 da3588f857f..0db6b86edbb 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 f35bae499e5..cebaea00dae 100644 --- a/loader/module.c +++ b/loader/module.c @@ -526,7 +526,7 @@ static HMODULE32 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs ) 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 @@ HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname ) * * 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 @@ void WINAPI FreeLibrary16( HINSTANCE16 handle ) * * 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 d42e5bcad64..98a8a9c4390 100644 --- a/loader/ne_image.c +++ b/loader/ne_image.c @@ -55,8 +55,8 @@ BOOL32 NE_LoadSegment( NE_MODULE *pModule, WORD segnum ) 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 @@ static BOOL32 NE_InitDLL( TDB* pTask, HMODULE16 hModule ) 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 @@ void NE_InitializeDLLs( HMODULE16 hModule ) /* 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 1485cb68185..6693fe2c63c 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -167,7 +167,7 @@ FARPROC32 PE_FindExportedFunction( HMODULE32 hModule, LPCSTR funcName) } 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 @@ fixup_imports (PDB32 *process,PE_MODREF *pem) /* 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 @@ static HMODULE32 PE_MapImage( HMODULE32 hModule, PDB32 *process, 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 @@ static HMODULE32 PE_MapImage( HMODULE32 hModule, PDB32 *process, 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 @@ HINSTANCE16 MODULE_CreateInstance(HMODULE16 hModule,LOADPARAMS *params); /****************************************************************************** * 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 @@ HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, HFILE32 hFile, DWORD flags) { 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 4ba09dde6c4..01396336b84 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c @@ -53,7 +53,8 @@ HMODULE32toPE_MODREF(HMODULE32 hmod) { * */ 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 @@ LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY resdirptr, 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 @@ LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY resdirptr, 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 @@ HANDLE32 PE_FindResourceEx32W( 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 @@ PE_EnumResourceNames32A( 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 @@ PE_EnumResourceNames32W( 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 @@ PE_EnumResourceLanguages32A( 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 @@ PE_EnumResourceLanguages32A( 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 @@ PE_EnumResourceLanguages32W( 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 cf981d4958c..08881d6ef7b 100644 --- a/loader/task.c +++ b/loader/task.c @@ -386,7 +386,7 @@ static void TASK_CallToStart(void) 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 @@ static void TASK_DeleteTask( HTASK16 hTask ) */ 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 0cf20f5308a..1d4aee294ca 100644 --- a/memory/heap.c +++ b/memory/heap.c @@ -885,7 +885,7 @@ LPVOID WINAPI HeapAlloc( HANDLE32 heap, DWORD flags, DWORD size ) 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 @@ LPVOID WINAPI HeapAlloc( HANDLE32 heap, DWORD flags, DWORD size ) 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 5c4777519f0..410c0d5b7af 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 @@ WORD WINAPI AllocSelectorArray( WORD count ) 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 @@ void WINAPI WOWGetVDMPointerUnfix(DWORD vp) 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 7ae69be49f1..82d4845a2f1 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 @@ static FILE_VIEW *VIRTUAL_CreateView( UINT32 base, UINT32 size, UINT32 offset, /* 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 @@ LPVOID WINAPI VirtualAlloc( LPVOID addr, DWORD size, DWORD type, DWORD protect) 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 @@ BOOL32 WINAPI FlushViewOfFile( LPCVOID base, DWORD cbFlush ) 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 4bbbe90bd76..f9722db76da 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -37,6 +37,8 @@ C_SRCS = \ 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 c379a90e949..34e5f027029 100644 --- a/misc/callback.c +++ b/misc/callback.c @@ -7,8 +7,8 @@ #include #include #include "callback.h" +#include "task.h" -extern void TASK_Reschedule(void); /* loader/task.c */ /********************************************************************** * CALLBACK_CallWndProc @@ -24,10 +24,11 @@ static LRESULT WINAPI CALLBACK_CallWndProc( WNDPROC16 proc, HWND16 hwnd, /********************************************************************** * 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 @@ static LRESULT WINAPI CALLBACK_CallASPIPostProc( FARPROC16 proc, SEGPTR ptr ) return proc( ptr ); } + +/********************************************************************** + * CALLBACK_CallWOWCallbackProc + */ +static DWORD WINAPI CALLBACK_CallWOWCallbackProc( FARPROC16 proc, DWORD dw ) +{ + return proc( dw ); +} + /********************************************************************** * CALLBACK_WinelibTable * @@ -130,7 +140,8 @@ static LRESULT WINAPI CALLBACK_CallASPIPostProc( FARPROC16 proc, SEGPTR ptr ) */ 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 @@ static const CALLBACKS_TABLE CALLBACK_WinelibTable = 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 83fa922b19f..d422c879c99 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c @@ -538,10 +538,14 @@ static LONG FILEDLG_WMInitDialog(HWND16 hWnd, WPARAM16 wParam, LPARAM lParam) } 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 014c546cfa7..ffbbbbfbbe8 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 #include #include "windows.h" +#include "winnt.h" VOID WINAPI GetSystemInfo(LPSYSTEM_INFO si) { @@ -99,3 +100,25 @@ VOID WINAPI GetSystemInfo(LPSYSTEM_INFO si) 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 7ffa01a4d59..3a12c9bb81d 100644 --- a/misc/crtdll.c +++ b/misc/crtdll.c @@ -30,6 +30,7 @@ Unresolved issues Uwe Bonnes 970904: #include #include #include +#include #include "win.h" #include "windows.h" #include "stddebug.h" @@ -438,7 +439,7 @@ INT32 __cdecl CRTDLL__write(INT32 fd,LPCVOID buf,UINT32 count) 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 @@ INT32 __cdecl CRTDLL__write(INT32 fd,LPCVOID buf,UINT32 count) * FIXME _exit (CRTDLL.87) * FIXME exit (CRTDLL.359) * + * atexit-processing comes to mind -- MW. + * */ void __cdecl CRTDLL__cexit(INT32 ret) { @@ -502,10 +505,13 @@ INT32 __cdecl CRTDLL_fflush(LPVOID stream) */ 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 @@ INT32 CRTDLL_system(LPSTR x) 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 @@ INT32 CRTDLL_system(LPSTR x) bp++; y++; if (*(y-1) =='\\') *bp++ = '\\'; } - /* remove spaces from end of string */ + /* Remove spaces from end of string. */ while (*(y-1) == ' ') { bp--;y--; } @@ -835,6 +841,16 @@ LPWSTR __cdecl CRTDLL__wcslwr(LPWSTR x) } +/********************************************************************* + * 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) */ @@ -1088,14 +1104,14 @@ LPWSTR __cdecl CRTDLL_wcscat( LPWSTR s1, LPCWSTR s2 ) /********************************************************************* * 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 @@ INT32 __cdecl CRTDLL_mbstowcs(LPWSTR wcs, LPCSTR mbs, INT32 size) { /* 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 @@ CHAR* __cdecl CRTDLL__getcwd(LPSTR buf, INT32 size) 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 2d7db18660a..ce80476df0e 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -10,40 +10,50 @@ #include #include #include +#include #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 @@ SEGPTR WINAPI AnsiUpper16( SEGPTR strOrChar ) 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 @@ SEGPTR WINAPI AnsiLower16( SEGPTR strOrChar ) 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 @@ LPSTR WINAPI CharLower32A(LPSTR x) } return x; } - else return (LPSTR)tolower(LOWORD(x)); + else return (LPSTR)tolower((char)(int)x); } /*********************************************************************** @@ -285,6 +295,7 @@ DWORD WINAPI CharLowerBuff32A(LPSTR x,DWORD buflen) { DWORD done=0; + if (!x) return 0; /* YES */ while (*x && (buflen--)) { *x=tolower(*x); @@ -302,9 +313,10 @@ DWORD WINAPI CharLowerBuff32W(LPWSTR x,DWORD buflen) { DWORD done=0; + if (!x) return 0; /* YES */ while (*x && (buflen--)) { - *x=tolower(*x); + *x=towlower(*x); x++; done++; } @@ -322,12 +334,12 @@ LPWSTR WINAPI CharLower32W(LPWSTR x) 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 @@ LPSTR WINAPI CharUpper32A(LPSTR x) } return x; } - else return (LPSTR)toupper(LOWORD(x)); + return (LPSTR)toupper((char)(int)x); } /*********************************************************************** @@ -357,6 +369,7 @@ DWORD WINAPI CharUpperBuff32A(LPSTR x,DWORD buflen) { DWORD done=0; + if (!x) return 0; /* YES */ while (*x && (buflen--)) { *x=toupper(*x); @@ -374,9 +387,10 @@ DWORD WINAPI CharUpperBuff32W(LPWSTR x,DWORD buflen) { DWORD done=0; + if (!x) return 0; /* YES */ while (*x && (buflen--)) { - *x=toupper(*x); + *x=towupper(*x); x++; done++; } @@ -394,12 +408,12 @@ LPWSTR WINAPI CharUpper32W(LPWSTR x) 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 IsCharAlphaNumeric32A(CHAR x) */ BOOL32 WINAPI IsCharAlphaNumeric32W(WCHAR x) { - return isalnum(x); + return iswalnum(x); } /*********************************************************************** @@ -435,7 +449,7 @@ BOOL32 WINAPI IsCharAlphaNumeric32W(WCHAR x) */ BOOL32 WINAPI IsCharAlpha32W(WCHAR x) { - return isalpha(x); + return iswalpha(x); } /*********************************************************************** @@ -453,7 +467,7 @@ BOOL32 WINAPI IsCharLower32A(CHAR x) */ BOOL32 WINAPI IsCharLower32W(WCHAR x) { - return islower(x); + return iswlower(x); } /*********************************************************************** @@ -471,7 +485,7 @@ BOOL32 WINAPI IsCharUpper32A(CHAR x) */ BOOL32 WINAPI IsCharUpper32W(WCHAR x) { - return isupper(x); + return iswupper(x); } /*********************************************************************** diff --git a/misc/main.c b/misc/main.c index 02984aeec0b..bda1779b33a 100644 --- a/misc/main.c +++ b/misc/main.c @@ -18,12 +18,12 @@ #include #include #include +#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 12ed9fa0784..58b8cbd607b 100644 --- a/misc/network.c +++ b/misc/network.c @@ -156,7 +156,7 @@ int WINAPI WNetUnlockQueueData(LPSTR szQueue) /************************************************************************** * 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 b16ff0f8873..f98a95181d2 100644 --- a/misc/port.c +++ b/misc/port.c @@ -49,3 +49,11 @@ void *memmove( void *dest, const void *src, unsigned int len ) 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 94ca6960732..3c735810acd 100644 --- a/misc/printdrv.c +++ b/misc/printdrv.c @@ -89,6 +89,14 @@ LONG WINAPI DocumentProperties32A(HWND32 hWnd,HANDLE32 hPrinter, 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 66a94ce3e87..d0bd6baf096 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -8,6 +8,7 @@ #include #include #include "windows.h" +#include "winerror.h" #include "file.h" #include "shell.h" #include "heap.h" @@ -125,6 +126,7 @@ static const char * const SHELL_People[] = "William Smith", "Dominik Strasser", "Vadim Strizhevsky", + "Bertho Stultiens", "Erik Svendsen", "Tristan Tarrant", "Andrew Taylor", @@ -181,9 +183,6 @@ typedef struct #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 @@ BOOL32 WINAPI ShellAbout32W( HWND32 hWnd, LPCWSTR szApp, LPCWSTR szOtherStuff, 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 @@ HGLOBAL16 WINAPI InternalExtractIcon(HINSTANCE16 hInstance, _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 @@ HGLOBAL16 WINAPI InternalExtractIcon(HINSTANCE16 hInstance, /* 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 @@ HGLOBAL16 WINAPI InternalExtractIcon(HINSTANCE16 hInstance, /* 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 @@ HGLOBAL16 WINAPI InternalExtractIcon(HINSTANCE16 hInstance, for (i=0;iQueryInterface(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 f3a1191bd07..3a1a6dc909a 100644 --- a/misc/shellord.c +++ b/misc/shellord.c @@ -31,6 +31,81 @@ #include "debug.h" #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 "\\\" */ + 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 @@ -47,6 +122,27 @@ LPSTR WINAPI SHELL32_32(LPSTR path) { return path+len; } +/************************************************************************* + * 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); @@ -134,6 +230,27 @@ LPSTR WINAPI SHELL32_36(LPSTR x1,LPSTR x2) { return SHELL32_37(x1,x1,x2); } +/************************************************************************* + * 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 @@ -153,14 +270,95 @@ LPSTR WINAPI SHELL32_52(LPSTR cmdline) { } /************************************************************************* - * 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); } /************************************************************************* @@ -181,14 +379,6 @@ void WINAPI SHELL32_181(DWORD x,DWORD y) { fprintf(stderr,"SHELL32_181(0x%08lx,0x%08lx)\n",x,y); } -/************************************************************************* - * 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 @@ BOOL32 WINAPI SHELL32_75(LPDWORD x,LPDWORD y) { 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 @@ static DWORD _get_instance(REFCLSID clsid,LPSTR dllname, ) { 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; } /************************************************************************* @@ -320,24 +528,6 @@ void __cdecl SHELL32_183(HMODULE32 hmod,HWND32 hwnd,DWORD id,DWORD x,DWORD type, } -/************************************************************************* - * 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 key, value, returns @@ -375,56 +565,6 @@ DWORD WINAPI SHELL32_100(DWORD pol) { } -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 "\\\" */ - 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 @@ -442,6 +582,34 @@ DWORD WINAPI SHELL32_152(LPITEMIDLIST iil) { return len; } +/************************************************************************* + * 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 @@ -480,32 +648,6 @@ LPITEMIDLIST WINAPI SHELL32_25(LPITEMIDLIST iil1,LPITEMIDLIST iil2) { return newiil; } -/************************************************************************* - * 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 @@ DWORD WINAPI SHELL32_155(LPVOID x) { 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 c9ceabbf305..afbdc4645d5 100644 --- a/misc/toolhelp.c +++ b/misc/toolhelp.c @@ -70,3 +70,18 @@ BOOL16 WINAPI NotifyUnregister( HTASK16 htask ) 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 422e6c3a5ba..883af0d441e 100644 --- a/misc/ver.c +++ b/misc/ver.c @@ -310,10 +310,6 @@ static int find_ne_resource( } } -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 @@ find_pe_resource( 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 @@ _find_dataA(BYTE *block,LPCSTR str, int buff_remain) { nextslash++; if (!*nextslash) nextslash=NULL; - } + } else if (*str == 0) + return NULL; while (1) { @@ -1208,7 +1205,7 @@ _find_dataA(BYTE *block,LPCSTR str, int buff_remain) { } /* 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 @@ _find_dataW(BYTE *block,LPCWSTR str, int buff_remain) { nextslash++; if (!*nextslash) nextslash=NULL; - } + } else if (*str == 0) + return NULL; while (1) { @@ -1298,6 +1296,7 @@ DWORD WINAPI VerQueryValue16(SEGPTR segblock,LPCSTR subblock,SEGPTR *buffer, 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 @@ DWORD WINAPI VerQueryValue16(SEGPTR segblock,LPCSTR subblock,SEGPTR *buffer, 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 @@ DWORD WINAPI VerQueryValue32A(LPVOID vblock,LPCSTR subblock, 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 @@ DWORD WINAPI VerQueryValue32A(LPVOID vblock,LPCSTR subblock, 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 54d1d5c04da..9d2ac9efe11 100644 --- a/misc/w32scomb.c +++ b/misc/w32scomb.c @@ -10,13 +10,14 @@ #include #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 af8dae58f73..f05cc9960e6 100644 --- a/misc/w32skrnl.c +++ b/misc/w32skrnl.c @@ -10,7 +10,7 @@ #include #include -LPSTR WINAPI GetWin32sDirectory() +LPSTR WINAPI GetWin32sDirectory(void) { static char *sysdir; LPSTR text; @@ -24,7 +24,7 @@ LPSTR WINAPI GetWin32sDirectory() } /* 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 00000000000..382e1465d3e --- /dev/null +++ b/misc/win32s16.c @@ -0,0 +1,16 @@ +/* + * WIN32S16 + * DLL for Win32s + * + * Copyright (c) 1997 Andreas Mohr + */ + +#include "windows.h" +#include +#include +#include + +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 00000000000..30f4d2c0bce --- /dev/null +++ b/misc/windebug.c @@ -0,0 +1,20 @@ +/* + * WINDEBUG.DLL + * + * Copyright (c) 1997 Andreas Mohr + */ + +#include +#include +#include +#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 a5d4dc932cb..b94bb3cc5f3 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 @@ -32,13 +31,13 @@ #include #include +#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 @@ static ws_socket* wsi_alloc_socket(LPWSINFO pwsi, int fd) 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 @@ __inline__ static int sock_error_p(int s) 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 @@ static int fd_set_export( LPWSINFO pwsi, fd_set* fds, fd_set* exceptfds, ws_fd_s 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 @@ INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, LPWSINFO pwsi ) 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 @@ SOCKET32 WINAPI WINSOCK_accept32(SOCKET32 s, struct sockaddr *addr, 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 @@ INT32 WINAPI WINSOCK_bind32(SOCKET32 s, struct sockaddr *name, INT32 namelen) 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 @@ INT32 WINAPI WINSOCK_closesocket32(SOCKET32 s) { 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_long WINAPI WINSOCK_htonl(u_long hostlong) { return( htonl(hostlong) ); } */ 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_long WINAPI WINSOCK_ntohl(u_long netlong) { return( ntohl(netlong) ); } 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 @@ INT16 WINAPI WINSOCK_recvfrom16(SOCKET16 s, char *buf, INT16 len, INT16 flags, } /*********************************************************************** - * 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 @@ INT16 WINAPI WINSOCK_select16(INT16 nfds, ws_fd_set *ws_readfds, 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 @@ INT16 WINAPI WINSOCK_select16(INT16 nfds, ws_fd_set *ws_readfds, 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 @@ INT32 WINAPI WINSOCK_send32(SOCKET32 s, char *buf, INT32 len, INT32 flags) 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 @@ INT32 WINAPI WINSOCK_shutdown32(SOCKET32 s, INT32 how) case 2: /* drop all */ default: - WSAAsyncSelect( s, 0, 0, 0 ); + WSAAsyncSelect32( s, 0, 0, 0 ); break; } @@ -1586,23 +1624,40 @@ INT16 WINAPI WINSOCK_gethostname16(char *name, INT16 namelen) */ /* 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 @@ HANDLE16 WINAPI WSAAsyncGetHostByAddr(HWND16 hWnd, UINT16 uMsg, LPCSTR addr, /*********************************************************************** * 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 @@ HANDLE16 WINAPI WSAAsyncGetHostByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name, * 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 @@ HANDLE32 WINAPI WSAAsyncGetHostByName32(HWND32 hWnd, UINT32 uMsg, LPCSTR name, /*********************************************************************** * 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 @@ HANDLE16 WINAPI WSAAsyncGetProtoByName(HWND16 hWnd, UINT16 uMsg, LPCSTR name, /*********************************************************************** * 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 @@ HANDLE16 WINAPI WSAAsyncGetProtoByNumber(HWND16 hWnd, UINT16 uMsg, INT16 number, /*********************************************************************** * 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 @@ BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set io_set[3] ) /* 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 @@ BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set io_set[3] ) { 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 @@ BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set io_set[3] ) 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 @@ INT16 WINAPI WSAAsyncSelect(SOCKET16 s, HWND16 hWnd, UINT16 uMsg, UINT32 lEvent) 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 @@ INT16 WINAPI __WSAFDIsSet16(SOCKET16 s, ws_fd_set *set) /*********************************************************************** * __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 @@ INT32 WINAPI WSAUnhookBlockingHook32(void) 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" + * 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 WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag) 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 WS_dup_pe(LPWSINFO pwsi, struct protoent* p_pe, int flag) 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 WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag) 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 @@ int WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag) 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 @@ UINT16 wsaErrno(void) 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 @@ UINT16 wsaHerrno(void) #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 173f6bb154d..94224de35e9 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 int __async_io_max_fd = 0; 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 @@ static int aop_control(ws_async_op* p_aop, int flag ) { 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 @@ static int aop_control(ws_async_op* p_aop, int flag ) /* 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 @@ HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND16 hWnd, UINT16 uMsg, INT16 type, L 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 @@ void WS_do_async_gethost(LPWSINFO pwsi, unsigned flag ) 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 @@ void WS_do_async_getproto(LPWSINFO pwsi, unsigned flag ) 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 @@ void WS_do_async_getserv(LPWSINFO pwsi, unsigned flag ) 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 @@ void fixup_wshe(struct ws_hostent* p_wshe, SEGPTR base) 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 @@ void fixup_wspe(struct ws_protoent* p_wspe, SEGPTR base) 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 c101d21bd3a..46cd421bc0a 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 eb9560c7735..1e86258687d 100644 --- a/msdos/int13.c +++ b/msdos/int13.c @@ -25,15 +25,13 @@ void WINAPI INT_Int13Handler( CONTEXT *context ) 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 0d5e14c96a2..58d8365497b 100644 --- a/multimedia/audio.c +++ b/multimedia/audio.c @@ -1738,7 +1738,7 @@ DWORD widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, * 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 cdd65abf5b5..97f401602fb 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 @@ struct js_status /************************************************************************** - * JoyOpenDriver [internal] + * joyOpenDriver [internal] */ -BOOL16 JoyOpenDriver(WORD wID) +BOOL16 joyOpenDriver(WORD wID) { char dev_name[] = "/dev/jsx"; @@ -52,9 +52,9 @@ BOOL16 JoyOpenDriver(WORD wID) } /************************************************************************** - * 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 @@ void JoyCloseDriver(WORD wID) } /************************************************************************** - * JoySendMessages [internal] + * joySendMessages [internal] */ -void JoySendMessages(void) +void joySendMessages(void) { int joy; struct js_status js; @@ -75,67 +75,146 @@ void JoySendMessages(void) 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,26 +227,55 @@ WORD WINAPI JoyGetDevCaps(WORD wID, LPJOYCAPS lpCaps, WORD wSize) 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 return MMSYSERR_NODRIVER; } +/************************************************************************** + * 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; @@ -181,10 +289,22 @@ WORD WINAPI JoyGetPos(WORD wID, LPJOYINFO lpInfo) return JOYERR_NOERROR; } +/************************************************************************** + * 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; @@ -192,14 +312,22 @@ WORD WINAPI JoyGetThreshold(WORD wID, LPWORD lpThreshold) return JOYERR_NOERROR; } +/************************************************************************** + * 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 @@ WORD WINAPI JoyReleaseCapture(WORD wID) /************************************************************************** * 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; } @@ -224,10 +360,17 @@ WORD WINAPI JoySetCapture(HWND16 hWnd, WORD wID, WORD wPeriod, BOOL16 bChanged) return JOYERR_NOCANDO; /* FIXME: what should be returned ? */ } +/************************************************************************** + * 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 @@ WORD WINAPI JoySetThreshold(WORD wID, WORD wThreshold) /************************************************************************** * 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 7b44e399f36..39fcdf1c93f 100644 --- a/multimedia/mcianim.c +++ b/multimedia/mcianim.c @@ -605,7 +605,7 @@ static DWORD ANIM_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms) * 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 d92d8406970..65a337556e3 100644 --- a/multimedia/mcicda.c +++ b/multimedia/mcicda.c @@ -1026,7 +1026,7 @@ static DWORD CDAUDIO_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParm * 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 298bd5c34b4..88cf60aef62 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 @@ LONG ANIM_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, #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 @@ MCISTR_Open(_MCISTR_PROTO_) { 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 @@ DWORD WINAPI mciSendString (LPCSTR lpstrCommand, LPSTR lpstrReturnString, 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 471a4d16439..f38d5dddba6 100644 --- a/multimedia/midi.c +++ b/multimedia/midi.c @@ -1347,7 +1347,7 @@ DWORD modMessage(WORD wDevID, WORD wMsg, DWORD dwUser, * 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 14ec17ae164..89f939453c0 100644 --- a/multimedia/mixer.c +++ b/multimedia/mixer.c @@ -39,7 +39,6 @@ static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize) { #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 @@ static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize) 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 159e78f8603..ad9d211689e 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 InstalledCount; 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 @@ LONG ANIM_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, #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 @@ MMSYSTEM_MMTIME16to32(LPMMTIME32 mmt32,LPMMTIME16 mmt16) { } /************************************************************************** -* 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 @@ UINT16 mixerGetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,D /************************************************************************** * 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 @@ UINT32 mixerGetLineControls32A(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32A lpmlc,DWO /************************************************************************** * 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 @@ UINT32 mixerGetLineControls32W(HMIXEROBJ32 hmix,LPMIXERLINECONTROLS32W lpmlc,DWO /************************************************************************** * 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 @@ UINT16 mixerGetLineControls16(HMIXEROBJ16 hmix,LPMIXERLINECONTROLS16 lpmlc,DWORD /************************************************************************** * 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 @@ UINT32 mixerGetLineInfo32A(HMIXEROBJ32 hmix,LPMIXERLINE32A lpml,DWORD fdwInfo) { /************************************************************************** * 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 @@ UINT32 mixerGetLineInfo32W(HMIXEROBJ32 hmix,LPMIXERLINE32W lpml,DWORD fdwInfo) { /************************************************************************** * 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 @@ UINT16 mixerGetLineInfo16(HMIXEROBJ16 hmix,LPMIXERLINE16 lpml,DWORD fdwInfo) { /************************************************************************** * 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 @@ UINT32 mixerSetControlDetails32(HMIXEROBJ32 hmix,LPMIXERCONTROLDETAILS32 lpmcd,D /************************************************************************** * 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 @@ UINT16 mixerSetControlDetails16(HMIXEROBJ16 hmix,LPMIXERCONTROLDETAILS16 lpmcd,D /************************************************************************** * 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 @@ UINT32 mixerMessage32(HMIXER32 hmix,UINT32 uMsg,DWORD dwParam1,DWORD dwParam2) { /************************************************************************** * 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 @@ DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms) 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 @@ DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms) 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 @@ DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms) } 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 @@ DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms) 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 @@ DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms) 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 @@ DWORD mciOpen(DWORD dwParam, LPMCI_OPEN_PARMS16 lp16Parms) 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 @@ DWORD mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms) /************************************************************************** -* mciSysinfo [internal] -*/ + * mciSysinfo [internal] + */ DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS16 lpParms) { int len; @@ -1381,6 +1422,63 @@ DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS16 lpParms) return MMSYSERR_INVALPARAM; } +/************************************************************************** + * 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 @@ static const char *_mciCommandToString(UINT16 wMsg) } /************************************************************************** -* 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 @@ DWORD WINAPI mciSendCommand(UINT16 wDevID, UINT16 wMsg, DWORD dwParam1, 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 @@ UINT16 WINAPI mciGetDeviceID (LPCSTR lpstrName) 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 @@ HANDLE16 WINAPI DrvGetModuleHandle(HDRVR16 hDrvr) /************************************************************************** -* 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 c631ce06f89..7a4eb6d006a 100644 --- a/multimedia/time.c +++ b/multimedia/time.c @@ -24,14 +24,15 @@ static MMTIME16 mmSysTimeMS; 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 @@ static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg, 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 @@ static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg, * 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; } @@ -111,12 +117,25 @@ static void StartMMTime() } } +/************************************************************************** + * 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 @@ WORD WINAPI timeGetSystemTime(LPMMTIME16 lpTime, WORD wSize) /************************************************************************** * 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 @@ WORD WINAPI timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc, 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 @@ WORD WINAPI timeSetEvent(WORD wDelay, WORD wResol, LPTIMECALLBACK lpFunc, } /************************************************************************** - * 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 @@ WORD WINAPI timeKillEvent(WORD wID) } /************************************************************************** - * 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) @@ -192,10 +261,35 @@ WORD WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, WORD wSize) return 0; } +/************************************************************************** + * 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 @@ WORD WINAPI timeBeginPeriod(WORD wPeriod) } /************************************************************************** - * 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 @@ WORD WINAPI timeEndPeriod(WORD wPeriod) } /************************************************************************** - * 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 c6fbbe18bfe..4092719c410 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -489,6 +489,29 @@ LONG WINAPI SetBitmapBits32( HBITMAP32 hbitmap, LONG count, LPCVOID buffer ) 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 5ef84fb6cdb..8f2eb8361ad 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -236,6 +236,15 @@ BOOL32 WINAPI SetBrushOrgEx( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 oldorg ) 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 a9a7a06e22a..d77a5f772ab 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 @@ HICON16 WINAPI CreateIconFromResourceEx16( LPBYTE bits, UINT16 cbSize, BOOL16 bI } + /********************************************************************** + * 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 2e0e1c1b934..7ff616d55eb 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] = @@ -133,6 +93,54 @@ void DC_FillDevCaps( DeviceCaps * caps ) } +/*********************************************************************** + * 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 */ @@ -159,7 +167,8 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs ) 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 @@ BOOL32 DC_SetupGCForPen( DC * dc ) } 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 @@ HDC16 WINAPI GetDCState( HDC16 hdc ) 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 @@ INT32 WINAPI SaveDC32( HDC32 hdc ) 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 @@ BOOL16 WINAPI RestoreDC16( HDC16 hdc, INT16 level ) 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 @@ BOOL32 WINAPI RestoreDC32( HDC32 hdc, INT32 level ) return FALSE; } + success=TRUE; while (dc->saveLevel >= level) { HDC16 hdcs = dc->header.hNext; @@ -629,11 +681,18 @@ BOOL32 WINAPI RestoreDC32( HDC32 hdc, INT32 level ) 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 @@ BOOL32 WINAPI DeleteDC32( HDC32 hdc ) 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 3c1be2eb9ed..b5d1cf2d9a3 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -291,6 +291,7 @@ static void DIB_SetImageBits_1( int lines, const BYTE *srcbits, 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 @@ static void DIB_SetImageBits_4( int lines, const BYTE *srcbits, 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 @@ static void DIB_SetImageBits_32( int lines, const BYTE *srcbits, 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 dd49530ac43..fe3c6f959eb 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -90,6 +90,10 @@ static FONTOBJ OEMFixedFont = { 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 @@ static FONTOBJ AnsiFixedFont = { 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 @@ static FONTOBJ AnsiVarFont = { 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 @@ static FONTOBJ SystemFont = { 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 @@ static FONTOBJ DeviceDefaultFont = { 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 @@ static FONTOBJ SystemFixedFont = { 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 @@ static GDIOBJHDR * StockObjects[NB_STOCK_OBJECTS] = (GDIOBJHDR *) &SystemFont, (GDIOBJHDR *) &DeviceDefaultFont, NULL, /* DEFAULT_PALETTE created by PALETTE_Init */ - (GDIOBJHDR *) &SystemFixedFont + (GDIOBJHDR *) &SystemFixedFont, + (GDIOBJHDR *) &DefaultGuiFont }; /****************************************************************************** @@ -213,6 +232,15 @@ BOOL32 GDI_Init(void) 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 @@ INT32 WINAPI GetObject32W( HANDLE32 handle, INT32 count, LPVOID buffer ) 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 7785313ee39..373c8515891 100644 --- a/objects/metafile.c +++ b/objects/metafile.c @@ -277,6 +277,10 @@ BOOL32 WINAPI PlayMetaFile32( HDC32 hdc, HMETAFILE32 hmf ) 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 @@ void WINAPI PlayMetaFileRecord16( HDC16 hdc, HANDLETABLE16 *ht, METARECORD *mr, 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 c8adcaad286..f7f4a0426f4 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 @@ static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */ */ HPALETTE16 PALETTE_Init(void) { - extern const PALETTEENTRY* COLOR_GetSystemPaletteTemplate(void); - int i; HPALETTE16 hpalette; LOGPALETTE * palPtr; @@ -117,6 +112,14 @@ HPALETTE32 WINAPI CreatePalette32( const LOGPALETTE* palette ) 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 c2c63adbbdc..ca3a1912f48 100644 --- a/objects/pen.c +++ b/objects/pen.c @@ -73,6 +73,30 @@ HPEN32 WINAPI CreatePenIndirect32( const LOGPEN32 * pen ) 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 04f8f8b3618..60ec10cbd9c 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 @@ -419,6 +420,110 @@ BOOL32 WINAPI TextOut32W(HDC32 hdc, INT32 x, INT32 y, LPCWSTR str, INT32 count) } +/*********************************************************************** + * 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) */ @@ -426,15 +531,7 @@ 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 @@ BOOL32 WINAPI GrayString32A( HDC32 hdc, HBRUSH32 hbr, GRAYSTRINGPROC32 gsprc, 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 @@ BOOL32 WINAPI GrayString32W( HDC32 hdc, HBRUSH32 hbr, GRAYSTRINGPROC32 gsprc, 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 @@ INT16 WINAPI GetTextCharset16(HDC16 hdc) 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 feeca6c4b95..1d923733de9 100644 --- a/ole/Makefile.in +++ b/ole/Makefile.in @@ -7,6 +7,8 @@ MODULE = ole C_SRCS = \ compobj.c \ + ifs.c \ + folders.c \ ole2.c \ ole2disp.c \ ole2nls.c \ @@ -18,4 +20,3 @@ all: $(MODULE).o @MAKE_RULES@ ### Dependencies: - diff --git a/ole/folders.c b/ole/folders.c new file mode 100644 index 00000000000..cf0def5127d --- /dev/null +++ b/ole/folders.c @@ -0,0 +1,174 @@ +/* + * Shell Folder stuff + * + * Copyright 1997 Marcus Meissner + */ + +#include +#include +#include +#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 00000000000..958a0ae8e69 --- /dev/null +++ b/ole/ifs.c @@ -0,0 +1,136 @@ +/* + * basic interfaces + * + * Copyright 1997 Marcus Meissner + */ + +#include +#include +#include +#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 0118d6d7621..2f2e8390309 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 00000000000..aca5fa07f87 --- /dev/null +++ b/programs/notepad/ChangeLog @@ -0,0 +1,5 @@ +Fri Dec 05 20:51:55 1997 Marcel Baur + * [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 00000000000..ca2a109e19d --- /dev/null +++ b/programs/notepad/De.rc @@ -0,0 +1,91 @@ +/* + * Notepad (German resources) + * + * Copyright 1997 Marcel Baur + */ + +#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 00000000000..35ab98a4d59 --- /dev/null +++ b/programs/notepad/En.rc @@ -0,0 +1,91 @@ +/* + * Notepad (English resources) + * + * Copyright 1997 Marcel Baur + * 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 00000000000..bec66d995eb --- /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 00000000000..f8a83d6fee3 --- /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 00000000000..2e03ea9c1a1 --- /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 . + +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 00000000000..d2d28b47c4b --- /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 00000000000..eee36e10488 --- /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 00000000000..c9a1e8dd77e --- /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 00000000000..0079af5f99e --- /dev/null +++ b/programs/notepad/notepad.rc @@ -0,0 +1,58 @@ +/* + * Notepad (notepad.rc) + * + * Copyright 1997 Marcel Baur + */ + +#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 ea8aa653531..058343bd8b3 100644 --- a/rc/winerc.c +++ b/rc/winerc.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/relay32/Makefile.in b/relay32/Makefile.in new file mode 100644 index 00000000000..74603e60987 --- /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 00000000000..8bdf3eb73b2 --- /dev/null +++ b/relay32/builtin32.c @@ -0,0 +1,379 @@ +/* + * Win32 builtin functions + * + * Copyright 1997 Alexandre Julliard + */ + +#include +#include +#include +#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 91b4e2d9876..a41af77d40b 100644 --- a/if1632/crtdll.spec +++ b/relay32/crtdll.spec @@ -427,7 +427,7 @@ type win32 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 00000000000..c7d10bc09c9 --- /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 686cfcf6457..e068279dac2 100644 --- a/if1632/gdi32.spec +++ b/relay32/gdi32.spec @@ -2,7 +2,7 @@ name gdi32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 4de6ca3c015..7dde6b4d870 100644 --- a/if1632/kernel32.spec +++ b/relay32/kernel32.spec @@ -169,7 +169,7 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 00000000000..1f75461b645 --- /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 18cec809c57..3faa9e50b0e 100644 --- a/if1632/ole32.spec +++ b/relay32/ole32.spec @@ -3,12 +3,12 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 00000000000..1531e4a6f1a --- /dev/null +++ b/relay32/relay386.c @@ -0,0 +1,203 @@ +/* + * 386-specific Win32 relay functions + * + * Copyright 1997 Alexandre Julliard + */ + +#ifdef __i386__ + +#include +#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 91% rename from if1632/shell32.spec rename to relay32/shell32.spec index 9867e608b3c..f31d8a3b5c4 100644 --- a/if1632/shell32.spec +++ b/relay32/shell32.spec @@ -5,7 +5,7 @@ type win32 # (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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 00000000000..011d0ab1ccc --- /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 f0f98be03e6..5c099ba42e6 100644 --- a/if1632/user32.spec +++ b/relay32/user32.spec @@ -76,7 +76,7 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 91% rename from if1632/winmm.spec rename to relay32/winmm.spec index 3c7016749fb..de1a4e5e71f 100644 --- a/if1632/winmm.spec +++ b/relay32/winmm.spec @@ -2,6 +2,8 @@ name winmm 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 @@ type win32 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 f5bd31a876f..be7721fa0d3 100644 --- a/if1632/winspool.spec +++ b/relay32/winspool.spec @@ -96,7 +96,7 @@ type win32 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 00000000000..2f5b5481e93 --- /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 829fe953434..7dc4def5fe6 100644 --- a/if1632/wsock32.spec +++ b/relay32/wsock32.spec @@ -10,8 +10,8 @@ type win32 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 @@ type win32 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 @@ type win32 # 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 @@ type win32 #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 b866fd4411c..3534338d767 100644 --- a/resources/sysres_De.rc +++ b/resources/sysres_De.rc @@ -17,14 +17,14 @@ EDITMENU MENU LOADONCALL MOVEABLE DISCARDABLE { 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 e3bd71b0e4d..b819080820d 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -658,6 +658,7 @@ DWORD WINAPI ExpandEnvironmentStrings32A( LPCSTR src, LPSTR dst, DWORD len) 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 @@ DWORD WINAPI ExpandEnvironmentStrings32A( LPCSTR src, LPSTR dst, DWORD len) } 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 3f39bda055c..c692a41bf23 100644 --- a/tools/build.c +++ b/tools/build.c @@ -960,102 +960,47 @@ static int BuildModule16( FILE *outfile, int max_code_offset, /******************************************************************* * 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 @@ static int BuildSpec32File( char * specfile, FILE *outfile ) } } - /* 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 @@ static int BuildSpec32File( char * specfile, FILE *outfile ) 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) ); - } - - /* 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 ); + if (nb_names++) fprintf( outfile, ",\n" ); + fprintf( outfile, " %d", i - Base ); } + 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 @@ static void BuildCallFrom16Func( FILE *outfile, char *profile ) * 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 @@ static void BuildCallTo16Func( FILE *outfile, char *profile ) 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 @@ static void BuildCallTo16Func( FILE *outfile, char *profile ) 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 @@ static void BuildCallTo16Func( FILE *outfile, char *profile ) 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 @@ static void BuildCallTo32LargeStack( FILE *outfile ) 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 @@ static int BuildCall32( FILE *outfile, char * outname ) 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 @@ static int BuildCall32( FILE *outfile, char * outname ) 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 d42613dba24..7c683e1ca2b 100644 --- a/win32/Makefile.in +++ b/win32/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ 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 ed6ea82291d..2771061aa92 100644 --- a/win32/code_page.c +++ b/win32/code_page.c @@ -85,54 +85,82 @@ BOOL32 WINAPI IsValidCodePage(UINT32 CodePage) /*********************************************************************** * 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 d10a1caa2d4..fa8166f3643 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 @@ -81,9 +82,7 @@ BOOL32 WINAPI GetConsoleMode(HANDLE32 hcon,LPDWORD mode) { *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 @@ DWORD WINAPI GetConsoleTitle32W(LPWSTR title,DWORD size) * WriteConsoleA (KERNEL32.567) */ BOOL32 WINAPI WriteConsole32A( HANDLE32 hConsoleOutput, - LPVOID lpBuffer, + LPCVOID lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved ) @@ -133,7 +132,7 @@ BOOL32 WINAPI WriteConsole32A( HANDLE32 hConsoleOutput, * WriteConsoleW (KERNEL32.577) */ BOOL32 WINAPI WriteConsole32W( HANDLE32 hConsoleOutput, - LPVOID lpBuffer, + LPCVOID lpBuffer, DWORD nNumberOfCharsToWrite, LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved ) @@ -199,7 +198,8 @@ BOOL32 WINAPI SetConsoleTitle32W( LPCWSTR title ) /*********************************************************************** * 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 SetConsoleCursorPosition(HANDLE32 hcons,COORD c) */ 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 90a0bf3a775..65ad44d4e15 100644 --- a/win32/environment.c +++ b/win32/environment.c @@ -29,9 +29,9 @@ LPCSTR WINAPI GetCommandLine32A(void) */ 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 00000000000..a53e04eff80 --- /dev/null +++ b/win32/kernel32.c @@ -0,0 +1,663 @@ +/* + * KERNEL32 thunks and other undocumented stuff + * + * Copyright 1997 Marcus Meissner + */ + +#include +#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(,%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 ? "" : 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 ? "" : 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 ? "" : 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;ilong registers. + * + * 665A pop edx + * 6668x arg2 x pushl + * 6652 push edx + * EAx arg1 x jmpf + * + * 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 31924511712..1ef72e5f02d 100644 --- a/win32/newfns.c +++ b/win32/newfns.c @@ -49,6 +49,17 @@ BOOL32 WINAPI QueryPerformanceCounter(LPLARGE_INTEGER counter) 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 576d25b17e5..10af63b8044 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 e33755a672d..e974c2905f8 100644 --- a/win32/thread.c +++ b/win32/thread.c @@ -159,7 +159,7 @@ void WINAPI InitializeCriticalSection(CRITICAL_SECTION *pcritical) 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 2d3b506d3fb..6fb6d5686c7 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 @@ static INT32 DCE_ReleaseDC( DCE* dce ) 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 @@ BOOL32 DCE_InvalidateDCE(WND* wndScope, const RECT32* pRectUpdate) } 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 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags ) wnd->flags |= WIN_SAVEUNDER_OVERRIDE; } dc->w.flags &= ~DC_DIRTY; + dce->DCXflags &= ~DCX_DCEDIRTY; SelectVisRgn( hdc, hrgnVisible ); } else @@ -908,7 +921,8 @@ BOOL16 WINAPI DCHook( HDC16 hDC, WORD code, DWORD data, LPARAM lParam ) 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 e50d00b1560..002868a6ce7 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 @@ HBRUSH32 DEFWND_ControlColor( HDC32 hDC, UINT16 ctlType ) 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 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT32 msg, WPARAM32 wParam, } 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 b68151e3dfe..f469c61697d 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -66,7 +66,7 @@ static WORD xBaseUnit = 0, yBaseUnit = 0; * * 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 54babe0edbc..e9e1980107c 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -1512,7 +1512,7 @@ BOOL16 WINAPI TranslateMDISysAccel16( HWND16 hwndClient, LPMSG16 msg ) 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 01e0c070307..a62ca874802 100644 --- a/windows/message.c +++ b/windows/message.c @@ -37,7 +37,7 @@ typedef enum { SYSQ_MSG_ABANDON, SYSQ_MSG_SKIP, 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 @@ static BOOL32 MSG_PeekHardwareMsg( MSG16 *msg, HWND16 hwnd, DWORD filter, 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 @@ LRESULT WINAPI SendMessage32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, 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 @@ LRESULT WINAPI SendMessage32A( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, /*********************************************************************** - * SendMessage32W (USER32.458) + * SendMessage32W (USER32.459) */ LRESULT WINAPI SendMessage32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam ) @@ -1187,7 +1187,7 @@ LRESULT WINAPI SendMessage32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, 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; @@ -1227,6 +1227,42 @@ LRESULT WINAPI SendMessage32W( HWND32 hwnd, UINT32 msg, WPARAM32 wParam, } +/*********************************************************************** + * 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) */ diff --git a/windows/msgbox.c b/windows/msgbox.c index 627e0cf34d3..f5f90bd1d66 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 @@ typedef struct 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 @@ static LRESULT CALLBACK MSGBOX_DlgProc( HWND32 hwnd, UINT32 message, 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 @@ static LRESULT CALLBACK MSGBOX_DlgProc( HWND32 hwnd, UINT32 message, 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 @@ static LRESULT CALLBACK MSGBOX_DlgProc( HWND32 hwnd, UINT32 message, 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 @@ static LRESULT CALLBACK MSGBOX_DlgProc( HWND32 hwnd, UINT32 message, /* 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 @@ INT16 WINAPI MessageBox16( HWND16 hwnd, LPCSTR text, LPCSTR title, UINT16 type) */ INT32 WINAPI MessageBox32A(HWND32 hWnd, LPCSTR text, LPCSTR title, UINT32 type) { - MSGBOX mbox; + MSGBOXPARAMS32A mbox; if (!text) text=""; if (!title) title=""; - 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 @@ INT32 WINAPI MessageBoxEx32W( HWND32 hWnd, LPCWSTR text, LPCWSTR title, 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 e9b24897ab1..7bdbce48229 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 @@ static HBITMAP16 hbitmapRestoreD = 0; #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 9ab73d4ca37..eeb1c7867ce 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -144,6 +144,10 @@ HDC16 WINAPI BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps ) } 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 fdc9f4a0927..b4daae693fb 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -387,7 +387,7 @@ rect?rect->left:0, rect?rect->top:0, rect ?rect->right:0, rect ?rect->bottom:0, 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 5f6fbc005a2..c8ac1c444ce 100644 --- a/windows/win.c +++ b/windows/win.c @@ -45,11 +45,7 @@ static WORD wDragHeight= 3; 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 @@ static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom, 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 @@ static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className, 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 3b0576f1fa7..d8521d483e4 100644 --- a/windows/winhelp.c +++ b/windows/winhelp.c @@ -28,21 +28,28 @@ BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand, 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 259b384071d..1402b6c3b35 100644 --- a/windows/winproc.c +++ b/windows/winproc.c @@ -76,18 +76,18 @@ typedef struct tagWINDOWPROC (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 @@ INT32 WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT32 *pmsg32, *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 @@ INT32 WINPROC_MapMsg32ATo16( HWND32 hwnd, UINT32 msg32, WPARAM32 wParam32, *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: {